From 6f2686e0d3ccc0fa38d4fd7991ea1c1f4e847bde Mon Sep 17 00:00:00 2001 From: mstar Date: Fri, 16 May 2025 16:43:24 +0200 Subject: [PATCH] Double-bang requests with rfc9421 and cavage after on error --- activitypub/import.go | 23 +++++++++++++++++++---- web/shared/clientRfc9421.go | 16 ++++++++++------ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/activitypub/import.go b/activitypub/import.go index e4ab7b3..6dec959 100644 --- a/activitypub/import.go +++ b/activitypub/import.go @@ -415,14 +415,29 @@ func ImportRemoteAccountByAPUrl(apUrl string) (*models.User, error) { return nil, other.Error("activitypub", "failed to get server actor", err) } var response *http.Response - response, err = webshared.RequestSignedCavage("GET", apUrl, nil, linstromActor) + // Try a rfc9421 based signature first for the request, if it fails, fall back to cavage + // Reason: Implementations should be switching over from cavage to the final implementation + // (rfc9421) slowly, but might not support the latter. Double-knocking will work + // around this + response, err = webshared.RequestSignedRFC9421("GET", apUrl, nil, linstromActor) if err != nil { - return nil, other.Error("activitypub", "failed to complete cavage signed request", err) + return nil, other.Error("activitypub", "failed to complete rfc9421 signed request", err) } - defer response.Body.Close() body, _ := io.ReadAll(response.Body) + response.Body.Close() if response.StatusCode != 200 { - return nil, fmt.Errorf("activitypub: invalid status code: %v", response.StatusCode) + log.Debug(). + Int("status-code", response.StatusCode). + Msg("RFC9421 signed request failed, trying cavage signature") + response, err = webshared.RequestSignedCavage("GET", apUrl, nil, linstromActor) + if err != nil { + return nil, other.Error("activitypub", "failed to complete cavage signed request", err) + } + body, _ = io.ReadAll(response.Body) + response.Body.Close() + if response.StatusCode != 200 { + return nil, fmt.Errorf("activitypub: invalid status code: %v", response.StatusCode) + } } var data inboundImportUser err = json.Unmarshal(body, &data) diff --git a/web/shared/clientRfc9421.go b/web/shared/clientRfc9421.go index 97fe1b1..612790b 100644 --- a/web/shared/clientRfc9421.go +++ b/web/shared/clientRfc9421.go @@ -33,9 +33,7 @@ Links for home: func RequestSignedRFC9421( method, target string, body []byte, - keyId string, - privateKeyBytes []byte, - useEd bool, + actor *models.User, ) (*http.Response, error) { req, err := http.NewRequest(method, target, bytes.NewBuffer(slices.Clone(body))) if err != nil { @@ -46,7 +44,7 @@ func RequestSignedRFC9421( signerFields := httpsign.Headers("@request-target", "content-digest") if config.GlobalConfig.Experimental.UseEd25519Keys { signer, err = httpsign.NewEd25519Signer( - privateKeyBytes, + actor.PrivateKeyEd, httpsign.NewSignConfig(), signerFields, ) @@ -54,7 +52,7 @@ func RequestSignedRFC9421( return nil, err } } else { - key, err := x509.ParsePKCS1PrivateKey(privateKeyBytes) + key, err := x509.ParsePKCS1PrivateKey(actor.PrivateKeyRsa) if err != nil { return nil, err } @@ -63,9 +61,15 @@ func RequestSignedRFC9421( return nil, err } } + clientConfig := httpsign.NewClientConfig().SetSigner(signer) + if config.GlobalConfig.Experimental.UseEd25519Keys { + clientConfig = clientConfig.SetSignatureName("sig-ed") + } else { + clientConfig = clientConfig.SetSignatureName("sig-rsa") + } client := httpsign.NewClient( RequestClient, - httpsign.NewClientConfig().SetSigner(signer).SetSignatureName("sig1"), + clientConfig, ) res, err := client.Do(req) return res, err