Double-bang requests with rfc9421 and cavage after on error
All checks were successful
/ docker (push) Successful in 4m20s

This commit is contained in:
Melody Becker 2025-05-16 16:43:24 +02:00
parent 3f4f1fd9d2
commit 6f2686e0d3
2 changed files with 29 additions and 10 deletions

View file

@ -415,15 +415,30 @@ func ImportRemoteAccountByAPUrl(apUrl string) (*models.User, error) {
return nil, other.Error("activitypub", "failed to get server actor", err) return nil, other.Error("activitypub", "failed to get server actor", err)
} }
var response *http.Response var response *http.Response
// 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 rfc9421 signed request", err)
}
body, _ := io.ReadAll(response.Body)
response.Body.Close()
if response.StatusCode != 200 {
log.Debug().
Int("status-code", response.StatusCode).
Msg("RFC9421 signed request failed, trying cavage signature")
response, err = webshared.RequestSignedCavage("GET", apUrl, nil, linstromActor) response, err = webshared.RequestSignedCavage("GET", apUrl, nil, linstromActor)
if err != nil { if err != nil {
return nil, other.Error("activitypub", "failed to complete cavage signed request", err) return nil, other.Error("activitypub", "failed to complete cavage signed request", err)
} }
defer response.Body.Close() body, _ = io.ReadAll(response.Body)
body, _ := io.ReadAll(response.Body) response.Body.Close()
if response.StatusCode != 200 { if response.StatusCode != 200 {
return nil, fmt.Errorf("activitypub: invalid status code: %v", response.StatusCode) return nil, fmt.Errorf("activitypub: invalid status code: %v", response.StatusCode)
} }
}
var data inboundImportUser var data inboundImportUser
err = json.Unmarshal(body, &data) err = json.Unmarshal(body, &data)
if err != nil { if err != nil {

View file

@ -33,9 +33,7 @@ Links for home:
func RequestSignedRFC9421( func RequestSignedRFC9421(
method, target string, method, target string,
body []byte, body []byte,
keyId string, actor *models.User,
privateKeyBytes []byte,
useEd bool,
) (*http.Response, error) { ) (*http.Response, error) {
req, err := http.NewRequest(method, target, bytes.NewBuffer(slices.Clone(body))) req, err := http.NewRequest(method, target, bytes.NewBuffer(slices.Clone(body)))
if err != nil { if err != nil {
@ -46,7 +44,7 @@ func RequestSignedRFC9421(
signerFields := httpsign.Headers("@request-target", "content-digest") signerFields := httpsign.Headers("@request-target", "content-digest")
if config.GlobalConfig.Experimental.UseEd25519Keys { if config.GlobalConfig.Experimental.UseEd25519Keys {
signer, err = httpsign.NewEd25519Signer( signer, err = httpsign.NewEd25519Signer(
privateKeyBytes, actor.PrivateKeyEd,
httpsign.NewSignConfig(), httpsign.NewSignConfig(),
signerFields, signerFields,
) )
@ -54,7 +52,7 @@ func RequestSignedRFC9421(
return nil, err return nil, err
} }
} else { } else {
key, err := x509.ParsePKCS1PrivateKey(privateKeyBytes) key, err := x509.ParsePKCS1PrivateKey(actor.PrivateKeyRsa)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -63,9 +61,15 @@ func RequestSignedRFC9421(
return nil, err 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( client := httpsign.NewClient(
RequestClient, RequestClient,
httpsign.NewClientConfig().SetSigner(signer).SetSignatureName("sig1"), clientConfig,
) )
res, err := client.Do(req) res, err := client.Do(req)
return res, err return res, err