mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-10-29 06:22:25 -05:00
[feature] Try HTTP signature validation with and without query params for incoming requests (#2591)
* [feature] Verify signatures both with + without query params * Bump to tagged version
This commit is contained in:
parent
c675d47a8c
commit
b614d33c40
18 changed files with 1799 additions and 22 deletions
|
|
@ -28,7 +28,6 @@ import (
|
|||
"time"
|
||||
|
||||
"codeberg.org/gruf/go-kv"
|
||||
"github.com/go-fed/httpsig"
|
||||
"github.com/superseriousbusiness/activity/streams"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
|
@ -37,6 +36,7 @@ import (
|
|||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/log"
|
||||
"github.com/superseriousbusiness/httpsig"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -509,24 +509,62 @@ var signingAlgorithms = []httpsig.Algorithm{
|
|||
httpsig.ED25519, // Try ED25519 as a long shot.
|
||||
}
|
||||
|
||||
// verifyAuth verifies auth using generated verifier, according to pubkey and our supported signing algorithms.
|
||||
func verifyAuth(l *log.Entry, verifier httpsig.Verifier, pubKey *rsa.PublicKey) bool {
|
||||
// Cheeky type to wrap a signing option with a
|
||||
// description of that option for logging purposes.
|
||||
type signingOption struct {
|
||||
desc string // Description of this options set.
|
||||
sigOpt httpsig.SignatureOption // The options themselves.
|
||||
}
|
||||
|
||||
var signingOptions = []signingOption{
|
||||
{
|
||||
// Prefer include query params.
|
||||
desc: "include query params",
|
||||
sigOpt: httpsig.SignatureOption{
|
||||
ExcludeQueryStringFromPathPseudoHeader: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
// Fall back to exclude query params.
|
||||
desc: "exclude query params",
|
||||
sigOpt: httpsig.SignatureOption{
|
||||
ExcludeQueryStringFromPathPseudoHeader: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// verifyAuth verifies auth using generated verifier,
|
||||
// according to pubkey, our supported signing algorithms,
|
||||
// and signature options. The loops in the function are
|
||||
// arranged in such a way that the most common combos are
|
||||
// tried first, so that we can hopefully succeed quickly
|
||||
// without wasting too many CPU cycles.
|
||||
func verifyAuth(
|
||||
l *log.Entry,
|
||||
verifier httpsig.VerifierWithOptions,
|
||||
pubKey *rsa.PublicKey,
|
||||
) bool {
|
||||
if pubKey == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Loop through all supported algorithms.
|
||||
// Loop through supported algorithms.
|
||||
for _, algo := range signingAlgorithms {
|
||||
|
||||
// Verify according to pubkey and algo.
|
||||
err := verifier.Verify(pubKey, algo)
|
||||
if err != nil {
|
||||
l.Tracef("authentication NOT PASSED with %s: %v", algo, err)
|
||||
continue
|
||||
}
|
||||
// Loop through signing options.
|
||||
for _, opt := range signingOptions {
|
||||
|
||||
l.Tracef("authenticated PASSED with %s", algo)
|
||||
return true
|
||||
// Try to verify according to this pubkey,
|
||||
// algo, and signing options combination.
|
||||
err := verifier.VerifyWithOptions(pubKey, algo, opt.sigOpt)
|
||||
if err != nil {
|
||||
l.Tracef("authentication NOT PASSED with %s (%s): %v", algo, opt.desc, err)
|
||||
continue
|
||||
}
|
||||
|
||||
l.Tracef("authenticated PASSED with %s (%s)", algo, opt.desc)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ import (
|
|||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/go-fed/httpsig"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtscontext"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/testrig"
|
||||
"github.com/superseriousbusiness/httpsig"
|
||||
)
|
||||
|
||||
type FederatingProtocolTestSuite struct {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import (
|
|||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/go-fed/httpsig"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/httpsig"
|
||||
)
|
||||
|
||||
// package private context key type.
|
||||
|
|
@ -129,8 +129,8 @@ func SetOtherIRIs(ctx context.Context, iris []*url.URL) context.Context {
|
|||
|
||||
// HTTPSignatureVerifier returns an http signature verifier for the current ActivityPub
|
||||
// request chain. This verifier can be called to authenticate the current request.
|
||||
func HTTPSignatureVerifier(ctx context.Context) httpsig.Verifier {
|
||||
verifier, _ := ctx.Value(httpSigVerifierKey).(httpsig.Verifier)
|
||||
func HTTPSignatureVerifier(ctx context.Context) httpsig.VerifierWithOptions {
|
||||
verifier, _ := ctx.Value(httpSigVerifierKey).(httpsig.VerifierWithOptions)
|
||||
return verifier
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import (
|
|||
"github.com/superseriousbusiness/gotosocial/internal/log"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-fed/httpsig"
|
||||
"github.com/superseriousbusiness/httpsig"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
package transport
|
||||
|
||||
import (
|
||||
"github.com/go-fed/httpsig"
|
||||
"github.com/superseriousbusiness/httpsig"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-fed/httpsig"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtscontext"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/httpclient"
|
||||
"github.com/superseriousbusiness/httpsig"
|
||||
)
|
||||
|
||||
// Transport implements the pub.Transport interface with some additional functionality for fetching remote media.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue