From 542e0a28ea6af2e276df06b3a66fb2b864f297e7 Mon Sep 17 00:00:00 2001 From: Yaron Sheffer Date: Sat, 8 Jun 2024 19:33:31 -0700 Subject: [PATCH] Breaking change: keyid is optional, now in SignConfig/VerifyConfig --- client_test.go | 14 ++-- clientex_test.go | 8 +- config.go | 22 +++-- crypto.go | 91 +++++--------------- crypto_test.go | 97 +++++----------------- fuzz_test.go | 4 +- handler_test.go | 22 ++--- handlerex_test.go | 8 +- http2_test.go | 8 +- signatures.go | 23 ++++-- signatures_test.go | 192 +++++++++++++++++++++++-------------------- signaturesex_test.go | 8 +- trailer_test.go | 16 ++-- 13 files changed, 216 insertions(+), 297 deletions(-) diff --git a/client_test.go b/client_test.go index 9428c74..a49b194 100644 --- a/client_test.go +++ b/client_test.go @@ -36,7 +36,7 @@ func TestClient_Get(t *testing.T) { fields: fields{ sigName: "sig1", signer: func() *Signer { - signer, _ := NewHMACSHA256Signer("key1", bytes.Repeat([]byte{1}, 64), NewSignConfig(), Headers("@method")) + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{1}, 64), NewSignConfig().SetKeyID("key1"), Headers("@method")) return signer }(), verifier: nil, @@ -54,7 +54,7 @@ func TestClient_Get(t *testing.T) { fields: fields{ sigName: "sig1", signer: func() *Signer { - signer, _ := NewHMACSHA256Signer("key1", bytes.Repeat([]byte{1}, 64), NewSignConfig(), Headers("@method")) + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{1}, 64), NewSignConfig().SetKeyID("key1"), Headers("@method")) return signer }(), verifier: nil, @@ -72,7 +72,7 @@ func TestClient_Get(t *testing.T) { fields: fields{ sigName: "", signer: func() *Signer { - signer, _ := NewHMACSHA256Signer("key1", bytes.Repeat([]byte{1}, 64), NewSignConfig(), Headers("@method")) + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{1}, 64), NewSignConfig().SetKeyID("key1"), Headers("@method")) return signer }(), verifier: nil, @@ -90,7 +90,7 @@ func TestClient_Get(t *testing.T) { fields: fields{ sigName: "sig1", signer: func() *Signer { - signer, _ := NewHMACSHA256Signer("key1", bytes.Repeat([]byte{1}, 64), NewSignConfig(), Headers("@method")) + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{1}, 64), NewSignConfig().SetKeyID("key1"), Headers("@method")) return signer }(), verifier: nil, @@ -110,12 +110,12 @@ func TestClient_Get(t *testing.T) { fields: fields{ sigName: "sig1", signer: func() *Signer { - signer, _ := NewHMACSHA256Signer("key1", bytes.Repeat([]byte{1}, 64), NewSignConfig(), Headers("@method")) + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{1}, 64), NewSignConfig().SetKeyID("key1"), Headers("@method")) return signer }(), verifier: nil, fetchVerifier: func(res *http.Response, req *http.Request) (sigName string, verifier *Verifier) { - verifier, _ = NewHMACSHA256Verifier("key1", bytes.Repeat([]byte{2}, 64), NewVerifyConfig(), Headers("@method")) + verifier, _ = NewHMACSHA256Verifier(bytes.Repeat([]byte{2}, 64), NewVerifyConfig(), Headers("@method")) return "name", verifier }, Client: *http.DefaultClient, @@ -196,7 +196,7 @@ func TestClient_Head(t *testing.T) { fields: fields{ sigName: "sig1", signer: func() *Signer { - signer, _ := NewHMACSHA256Signer("key1", bytes.Repeat([]byte{1}, 64), NewSignConfig(), + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{1}, 64), NewSignConfig().SetKeyID("key1"), Headers("@method")) return signer }(), diff --git a/clientex_test.go b/clientex_test.go index c3f10e7..e778279 100644 --- a/clientex_test.go +++ b/clientex_test.go @@ -30,8 +30,8 @@ func ExampleClient_Get() { // Client code starts here // Create a signer and a wrapped HTTP client (we set SignCreated to false to make the response deterministic, // don't do that in production.) - signer, _ := httpsign.NewHMACSHA256Signer("key1", bytes.Repeat([]byte{1}, 64), - httpsign.NewSignConfig().SignCreated(false), httpsign.Headers("@method")) + signer, _ := httpsign.NewHMACSHA256Signer(bytes.Repeat([]byte{1}, 64), + httpsign.NewSignConfig().SignCreated(false).SetKeyID("key1"), httpsign.Headers("@method")) client := httpsign.NewDefaultClient(httpsign.NewClientConfig().SetSignatureName("sig22").SetSigner(signer)) // sign, don't verify // Send an HTTP GET, get response -- signing and verification happen behind the scenes @@ -107,8 +107,8 @@ func TestClientUsage(t *testing.T) { // Client code starts here // Create a signer and a wrapped HTTP client - signer, _ := httpsign.NewRSAPSSSigner("key1", *prvKey, - httpsign.NewSignConfig(), + signer, _ := httpsign.NewRSAPSSSigner(*prvKey, + httpsign.NewSignConfig().SetKeyID("key1"), httpsign.Headers("@request-target", "content-digest")) // The Content-Digest header will be auto-generated client := httpsign.NewDefaultClient(httpsign.NewClientConfig().SetSignatureName("sig1").SetSigner(signer)) // sign requests, don't verify responses diff --git a/config.go b/config.go index 4b5fd0e..445d6fa 100644 --- a/config.go +++ b/config.go @@ -16,6 +16,7 @@ type SignConfig struct { expires int64 nonce string tag string + keyID *string } // NewSignConfig generates a default configuration. @@ -27,6 +28,7 @@ func NewSignConfig() *SignConfig { expires: 0, nonce: "", tag: "", // we disallow an empty tag + keyID: nil, } } @@ -70,6 +72,12 @@ func (c *SignConfig) SetTag(tag string) *SignConfig { return c } +// SetKeyID configures a keyid value that will be included as a signature parameter. +func (c *SignConfig) SetKeyID(keyID string) *SignConfig { + c.keyID = &keyID + return c +} + // VerifyConfig contains additional configuration for the verifier. type VerifyConfig struct { verifyCreated bool @@ -77,7 +85,7 @@ type VerifyConfig struct { notOlderThan time.Duration allowedAlgs []string rejectExpired bool - verifyKeyID bool + keyID *string dateWithin time.Duration allowedTags []string } @@ -118,11 +126,11 @@ func (v *VerifyConfig) SetAllowedAlgs(allowedAlgs []string) *VerifyConfig { return v } -// SetVerifyKeyID defines how to verify the keyid parameter, if one exists. If this value is set, -// the signature verifies only if the value is the same as was specified in the Verifier structure. -// Default: true. -func (v *VerifyConfig) SetVerifyKeyID(verify bool) *VerifyConfig { - v.verifyKeyID = verify +// SetKeyID defines how to verify the keyid parameter, if one exists. If this value is a non-nil string, +// the signature verifies only if the value is the same as was specified here. +// Default: nil. +func (v *VerifyConfig) SetKeyID(keyID string) *VerifyConfig { + v.keyID = &keyID return v } @@ -150,7 +158,7 @@ func NewVerifyConfig() *VerifyConfig { notOlderThan: 10 * time.Second, rejectExpired: true, allowedAlgs: []string{}, - verifyKeyID: true, + keyID: nil, dateWithin: 0, // meaning no constraint allowedTags: nil, // no constraint } diff --git a/crypto.go b/crypto.go index 542d141..8b3cf02 100644 --- a/crypto.go +++ b/crypto.go @@ -18,7 +18,6 @@ import ( // Signer includes a cryptographic key (typically a private key) and configuration of what needs to be signed. type Signer struct { - keyID string key interface{} alg string config *SignConfig @@ -28,18 +27,14 @@ type Signer struct { // NewHMACSHA256Signer returns a new Signer structure. Key must be at least 64 bytes long. // Config may be nil for a default configuration. -func NewHMACSHA256Signer(keyID string, key []byte, config *SignConfig, fields Fields) (*Signer, error) { +func NewHMACSHA256Signer(key []byte, config *SignConfig, fields Fields) (*Signer, error) { if key == nil || len(key) < 64 { return nil, fmt.Errorf("key must be at least 64 bytes long") } - if keyID == "" { - return nil, fmt.Errorf("keyID must not be empty") - } if config == nil { config = NewSignConfig() } return &Signer{ - keyID: keyID, key: key, alg: "hmac-sha256", config: config, @@ -49,15 +44,11 @@ func NewHMACSHA256Signer(keyID string, key []byte, config *SignConfig, fields Fi // NewRSASigner returns a new Signer structure. Key is an RSA private key. // Config may be nil for a default configuration. -func NewRSASigner(keyID string, key rsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error) { - if keyID == "" { - return nil, fmt.Errorf("keyID must not be empty") - } +func NewRSASigner(key rsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error) { if config == nil { config = NewSignConfig() } return &Signer{ - keyID: keyID, key: key, alg: "rsa-v1_5-sha256", config: config, @@ -67,15 +58,11 @@ func NewRSASigner(keyID string, key rsa.PrivateKey, config *SignConfig, fields F // NewRSAPSSSigner returns a new Signer structure. Key is an RSA private key. // Config may be nil for a default configuration. -func NewRSAPSSSigner(keyID string, key rsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error) { - if keyID == "" { - return nil, fmt.Errorf("keyID must not be empty") - } +func NewRSAPSSSigner(key rsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error) { if config == nil { config = NewSignConfig() } return &Signer{ - keyID: keyID, key: key, alg: "rsa-pss-sha512", config: config, @@ -85,20 +72,17 @@ func NewRSAPSSSigner(keyID string, key rsa.PrivateKey, config *SignConfig, field // NewP256Signer returns a new Signer structure. Key is an elliptic curve P-256 private key. // Config may be nil for a default configuration. -func NewP256Signer(keyID string, key ecdsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error) { - return newECCSigner(keyID, key, config, fields, elliptic.P256(), "P-256", "ecdsa-p256-sha256") +func NewP256Signer(key ecdsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error) { + return newECCSigner(key, config, fields, elliptic.P256(), "P-256", "ecdsa-p256-sha256") } // NewP384Signer returns a new Signer structure. Key is an elliptic curve P-384 private key. // Config may be nil for a default configuration. -func NewP384Signer(keyID string, key ecdsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error) { - return newECCSigner(keyID, key, config, fields, elliptic.P384(), "P-384", "ecdsa-p384-sha384") +func NewP384Signer(key ecdsa.PrivateKey, config *SignConfig, fields Fields) (*Signer, error) { + return newECCSigner(key, config, fields, elliptic.P384(), "P-384", "ecdsa-p384-sha384") } -func newECCSigner(keyID string, key ecdsa.PrivateKey, config *SignConfig, fields Fields, curve elliptic.Curve, curveName, alg string) (*Signer, error) { - if keyID == "" { - return nil, fmt.Errorf("keyID must not be empty") - } +func newECCSigner(key ecdsa.PrivateKey, config *SignConfig, fields Fields, curve elliptic.Curve, curveName, alg string) (*Signer, error) { if key.Curve != curve { return nil, fmt.Errorf("key curve must be %s", curveName) } @@ -106,7 +90,6 @@ func newECCSigner(keyID string, key ecdsa.PrivateKey, config *SignConfig, fields config = NewSignConfig() } return &Signer{ - keyID: keyID, key: key, alg: alg, config: config, @@ -116,18 +99,14 @@ func newECCSigner(keyID string, key ecdsa.PrivateKey, config *SignConfig, fields // NewEd25519Signer returns a new Signer structure. Key is an EdDSA Curve 25519 private key. // Config may be nil for a default configuration. -func NewEd25519Signer(keyID string, key ed25519.PrivateKey, config *SignConfig, fields Fields) (*Signer, error) { +func NewEd25519Signer(key ed25519.PrivateKey, config *SignConfig, fields Fields) (*Signer, error) { if key == nil { return nil, fmt.Errorf("key must not be nil") } - if keyID == "" { - return nil, fmt.Errorf("keyID must not be empty") - } if config == nil { config = NewSignConfig() } return &Signer{ - keyID: keyID, key: key, alg: "ed25519", config: config, @@ -138,18 +117,18 @@ func NewEd25519Signer(keyID string, key ed25519.PrivateKey, config *SignConfig, // NewEd25519SignerFromSeed returns a new Signer structure. Key is an EdDSA Curve 25519 private key, // a 32 byte buffer according to RFC 8032. // Config may be nil for a default configuration. -func NewEd25519SignerFromSeed(keyID string, seed []byte, config *SignConfig, fields Fields) (*Signer, error) { +func NewEd25519SignerFromSeed(seed []byte, config *SignConfig, fields Fields) (*Signer, error) { if seed == nil || len(seed) != ed25519.SeedSize { return nil, fmt.Errorf("seed must not be nil, and must have length %d", ed25519.SeedSize) } key := ed25519.NewKeyFromSeed(seed) - return NewEd25519Signer(keyID, key, config, fields) + return NewEd25519Signer(key, config, fields) } // NewJWSSigner creates a generic signer for JWS algorithms, using the go-jwx package. The particular key type for each algorithm // is documented in that package. // Config may be nil for a default configuration. -func NewJWSSigner(alg jwa.SignatureAlgorithm, keyID string, key interface{}, config *SignConfig, fields Fields) (*Signer, error) { +func NewJWSSigner(alg jwa.SignatureAlgorithm, key interface{}, config *SignConfig, fields Fields) (*Signer, error) { if key == nil { return nil, fmt.Errorf("key must not be nil") } @@ -161,7 +140,6 @@ func NewJWSSigner(alg jwa.SignatureAlgorithm, keyID string, key interface{}, con return nil, err } return &Signer{ - keyID: keyID, key: key, alg: "", config: config, @@ -220,7 +198,6 @@ func (s Signer) sign(buff []byte) ([]byte, error) { // Verifier includes a cryptographic key (typically a public key) and configuration of what needs to be verified. type Verifier struct { - keyID string key interface{} alg string config *VerifyConfig @@ -230,7 +207,7 @@ type Verifier struct { // NewHMACSHA256Verifier generates a new Verifier for HMAC-SHA256 signatures. Set config to nil for a default configuration. // Fields is the list of required headers and fields, which may be empty (but this is typically insecure). -func NewHMACSHA256Verifier(keyID string, key []byte, config *VerifyConfig, fields Fields) (*Verifier, error) { +func NewHMACSHA256Verifier(key []byte, config *VerifyConfig, fields Fields) (*Verifier, error) { if key == nil { return nil, fmt.Errorf("key must not be nil") } @@ -240,11 +217,7 @@ func NewHMACSHA256Verifier(keyID string, key []byte, config *VerifyConfig, field if config == nil { config = NewVerifyConfig() } - if config.verifyKeyID && keyID == "" { - return nil, fmt.Errorf("keyID should not be empty") - } return &Verifier{ - keyID: keyID, key: key, alg: "hmac-sha256", config: config, @@ -254,15 +227,11 @@ func NewHMACSHA256Verifier(keyID string, key []byte, config *VerifyConfig, field // NewRSAVerifier generates a new Verifier for RSA signatures. Set config to nil for a default configuration. // Fields is the list of required headers and fields, which may be empty (but this is typically insecure). -func NewRSAVerifier(keyID string, key rsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error) { +func NewRSAVerifier(key rsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error) { if config == nil { config = NewVerifyConfig() } - if config.verifyKeyID && keyID == "" { - return nil, fmt.Errorf("keyID should not be empty") - } return &Verifier{ - keyID: keyID, key: key, alg: "rsa-v1_5-sha256", config: config, @@ -272,15 +241,11 @@ func NewRSAVerifier(keyID string, key rsa.PublicKey, config *VerifyConfig, field // NewRSAPSSVerifier generates a new Verifier for RSA-PSS signatures. Set config to nil for a default configuration. // Fields is the list of required headers and fields, which may be empty (but this is typically insecure). -func NewRSAPSSVerifier(keyID string, key rsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error) { +func NewRSAPSSVerifier(key rsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error) { if config == nil { config = NewVerifyConfig() } - if config.verifyKeyID && keyID == "" { - return nil, fmt.Errorf("keyID should not be empty") - } return &Verifier{ - keyID: keyID, key: key, alg: "rsa-pss-sha512", config: config, @@ -290,28 +255,24 @@ func NewRSAPSSVerifier(keyID string, key rsa.PublicKey, config *VerifyConfig, fi // NewP256Verifier generates a new Verifier for ECDSA (P-256) signatures. Set config to nil for a default configuration. // Fields is the list of required headers and fields, which may be empty (but this is typically insecure). -func NewP256Verifier(keyID string, key ecdsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error) { - return newECCVerifier(keyID, key, config, fields, elliptic.P256(), "P-256", "ecdsa-p256-sha256") +func NewP256Verifier(key ecdsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error) { + return newECCVerifier(key, config, fields, elliptic.P256(), "P-256", "ecdsa-p256-sha256") } // NewP384Verifier generates a new Verifier for ECDSA (P-384) signatures. Set config to nil for a default configuration. // Fields is the list of required headers and fields, which may be empty (but this is typically insecure). -func NewP384Verifier(keyID string, key ecdsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error) { - return newECCVerifier(keyID, key, config, fields, elliptic.P384(), "P-384", "ecdsa-p384-sha384") +func NewP384Verifier(key ecdsa.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error) { + return newECCVerifier(key, config, fields, elliptic.P384(), "P-384", "ecdsa-p384-sha384") } -func newECCVerifier(keyID string, key ecdsa.PublicKey, config *VerifyConfig, fields Fields, curve elliptic.Curve, curveName, alg string) (*Verifier, error) { +func newECCVerifier(key ecdsa.PublicKey, config *VerifyConfig, fields Fields, curve elliptic.Curve, curveName, alg string) (*Verifier, error) { if config == nil { config = NewVerifyConfig() } - if config.verifyKeyID && keyID == "" { - return nil, fmt.Errorf("keyID should not be empty") - } if key.Curve != curve { return nil, fmt.Errorf("key curve must be %s", curveName) } return &Verifier{ - keyID: keyID, key: key, alg: alg, config: config, @@ -321,18 +282,14 @@ func newECCVerifier(keyID string, key ecdsa.PublicKey, config *VerifyConfig, fie // NewEd25519Verifier generates a new Verifier for EdDSA Curve 25519 signatures. Set config to nil for a default configuration. // Fields is the list of required headers and fields, which may be empty (but this is typically insecure). -func NewEd25519Verifier(keyID string, key ed25519.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error) { +func NewEd25519Verifier(key ed25519.PublicKey, config *VerifyConfig, fields Fields) (*Verifier, error) { if key == nil { return nil, fmt.Errorf("key must not be nil") } if config == nil { config = NewVerifyConfig() } - if config.verifyKeyID && keyID == "" { - return nil, fmt.Errorf("keyID should not be empty") - } return &Verifier{ - keyID: keyID, key: key, alg: "ed25519", config: config, @@ -343,16 +300,13 @@ func NewEd25519Verifier(keyID string, key ed25519.PublicKey, config *VerifyConfi // NewJWSVerifier creates a generic verifier for JWS algorithms, using the go-jwx package. The particular key type for each algorithm // is documented in that package. Set config to nil for a default configuration. // Fields is the list of required headers and fields, which may be empty (but this is typically insecure). -func NewJWSVerifier(alg jwa.SignatureAlgorithm, key interface{}, keyID string, config *VerifyConfig, fields Fields) (*Verifier, error) { +func NewJWSVerifier(alg jwa.SignatureAlgorithm, key interface{}, config *VerifyConfig, fields Fields) (*Verifier, error) { if key == nil { return nil, fmt.Errorf("key must not be nil") } if config == nil { config = NewVerifyConfig() } - if config.verifyKeyID && keyID == "" { - return nil, fmt.Errorf("keyID should not be empty") - } if alg == jwa.NoSignature { return nil, fmt.Errorf("the NONE signing algorithm is expressly disallowed") } @@ -361,7 +315,6 @@ func NewJWSVerifier(alg jwa.SignatureAlgorithm, key interface{}, keyID string, c return nil, err } return &Verifier{ - keyID: keyID, key: key, alg: "", config: config, diff --git a/crypto_test.go b/crypto_test.go index cdad3b5..98492c9 100644 --- a/crypto_test.go +++ b/crypto_test.go @@ -13,10 +13,9 @@ import ( func TestNewHMACSHA256Signer(t *testing.T) { type args struct { - keyID string - key []byte - c *SignConfig - f Fields + key []byte + c *SignConfig + f Fields } tests := []struct { name string @@ -27,13 +26,11 @@ func TestNewHMACSHA256Signer(t *testing.T) { { name: "happy path", args: args{ - keyID: "key1", - key: []byte(strings.Repeat("c", 64)), - c: nil, - f: Fields{}, + key: []byte(strings.Repeat("c", 64)), + c: nil, + f: Fields{}, }, want: &Signer{ - keyID: "key1", key: []byte(strings.Repeat("c", 64)), alg: "hmac-sha256", config: NewSignConfig(), @@ -44,8 +41,7 @@ func TestNewHMACSHA256Signer(t *testing.T) { { name: "key too short", args: args{ - keyID: "key2", - key: []byte("abc"), + key: []byte("abc"), }, want: nil, wantErr: true, @@ -53,7 +49,7 @@ func TestNewHMACSHA256Signer(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewHMACSHA256Signer(tt.args.keyID, tt.args.key, tt.args.c, tt.args.f) + got, err := NewHMACSHA256Signer(tt.args.key, tt.args.c, tt.args.f) if (err != nil) != tt.wantErr { t.Errorf("NewHMACSHA256Signer() error = %v, wantErr %v", err, tt.wantErr) return @@ -67,9 +63,8 @@ func TestNewHMACSHA256Signer(t *testing.T) { func TestSigner_sign(t *testing.T) { type fields struct { - keyID string - key interface{} - alg string + key interface{} + alg string } type args struct { buff []byte @@ -84,9 +79,8 @@ func TestSigner_sign(t *testing.T) { { name: "happy path", fields: fields{ - keyID: "key1", - key: []byte(strings.Repeat("a", 64)), - alg: "hmac-sha256", + key: []byte(strings.Repeat("a", 64)), + alg: "hmac-sha256", }, args: args{ buff: []byte("abc"), @@ -97,9 +91,8 @@ func TestSigner_sign(t *testing.T) { { name: "bad alg", fields: fields{ - keyID: "key1", - key: []byte(strings.Repeat("a", 64)), - alg: "hmac-sha999", + key: []byte(strings.Repeat("a", 64)), + alg: "hmac-sha999", }, args: args{ buff: []byte("abc"), @@ -111,9 +104,8 @@ func TestSigner_sign(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { s := Signer{ - keyID: tt.fields.keyID, - key: tt.fields.key, - alg: tt.fields.alg, + key: tt.fields.key, + alg: tt.fields.alg, } got, err := s.sign(tt.args.buff) if (err != nil) != tt.wantErr { @@ -127,51 +119,6 @@ func TestSigner_sign(t *testing.T) { } } -func TestNewRSASigner(t *testing.T) { - privateKey, err := rsa.GenerateKey(rand.Reader, 2048) - if err != nil { - t.Errorf("failed to gen private key") - } - _ = privateKey.Public() - - type args struct { - keyID string - key rsa.PrivateKey - config *SignConfig - fields Fields - } - tests := []struct { - name string - args args - want *Signer - wantErr bool - }{ - { - name: "empty key ID", - args: args{ - keyID: "", - key: *privateKey, - config: nil, - fields: *NewFields(), - }, - want: nil, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := NewRSASigner(tt.args.keyID, tt.args.key, tt.args.config, tt.args.fields) - if (err != nil) != tt.wantErr { - t.Errorf("NewRSASigner() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("NewRSASigner() got = %v, want %v", got, tt.want) - } - }) - } -} - func TestForeignSigner(t *testing.T) { priv, pub, err := genP256KeyPair() if err != nil { @@ -181,7 +128,7 @@ func TestForeignSigner(t *testing.T) { config := NewSignConfig().setFakeCreated(1618884475).SignAlg(false) signatureName := "sig1" fields := *NewFields().AddHeader("@method").AddHeader("date").AddHeader("content-type").AddQueryParam("pet") - signer, err := NewJWSSigner(jwa.ES256, "key1", priv, config, fields) + signer, err := NewJWSSigner(jwa.ES256, priv, config.SetKeyID("key1"), fields) if err != nil { t.Errorf("Failed to create JWS signer") } @@ -192,7 +139,7 @@ func TestForeignSigner(t *testing.T) { } req.Header.Add("Signature", sig) req.Header.Add("Signature-Input", sigInput) - verifier, err := NewJWSVerifier(jwa.ES256, pub, "key1", NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err := NewJWSVerifier(jwa.ES256, pub, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("key1"), fields) if err != nil { t.Errorf("could not generate Verifier: %s", err) } @@ -223,13 +170,11 @@ func TestNewRSASigner1(t *testing.T) { { name: "happy path", args: args{ - keyID: "key100", key: key, config: nil, fields: *NewFields(), }, want: &Signer{ - keyID: "key100", key: *key, alg: "rsa-v1_5-sha256", config: NewSignConfig(), @@ -241,7 +186,7 @@ func TestNewRSASigner1(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewRSASigner(tt.args.keyID, *tt.args.key, tt.args.config, tt.args.fields) + got, err := NewRSASigner(*tt.args.key, tt.args.config, tt.args.fields) if (err != nil) != tt.wantErr { t.Errorf("NewRSASigner() error = %v, wantErr %v", err, tt.wantErr) return @@ -278,7 +223,6 @@ func TestNewJWSVerifier(t *testing.T) { fields: *NewFields(), }, want: &Verifier{ - keyID: "key200", key: "1234", alg: "", config: NewVerifyConfig(), @@ -314,7 +258,7 @@ func TestNewJWSVerifier(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewJWSVerifier(tt.args.alg, tt.args.key, tt.args.keyID, tt.args.config, tt.args.fields) + got, err := NewJWSVerifier(tt.args.alg, tt.args.key, tt.args.config, tt.args.fields) if (err != nil) != tt.wantErr { t.Errorf("NewJWSVerifier() error = %v, wantErr %v", err, tt.wantErr) return @@ -334,7 +278,6 @@ func TestNewJWSVerifier(t *testing.T) { func TestVerify(t *testing.T) { v := Verifier{ - keyID: "", key: nil, alg: "bad-alg", config: NewVerifyConfig(), diff --git a/fuzz_test.go b/fuzz_test.go index 29a7f03..708ba51 100644 --- a/fuzz_test.go +++ b/fuzz_test.go @@ -70,13 +70,13 @@ func FuzzSignAndVerifyHMAC(f *testing.F) { fields := Headers("@authority", "date", "content-type") signatureName := "sig1" key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, config, fields) + signer, _ := NewHMACSHA256Signer(key, config.SetKeyID("test-shared-secret"), fields) req := readRequest(reqString) sigInput, sig, err := SignRequest(signatureName, *signer, req) if err == nil { req.Header.Add("Signature", sig) req.Header.Add("Signature-Input", sigInput) - verifier, err := NewHMACSHA256Verifier("test-shared-secret", key, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err := NewHMACSHA256Verifier(key, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-shared-secret"), fields) assert.NoError(t, err, "could not generate Verifier") err = VerifyRequest(signatureName, *verifier, req) assert.NoError(t, err, "verification error") diff --git a/handler_test.go b/handler_test.go index fce865b..dc8002e 100644 --- a/handler_test.go +++ b/handler_test.go @@ -15,14 +15,14 @@ import ( func Test_WrapHandler(t *testing.T) { fetchVerifier := func(r *http.Request) (string, *Verifier) { sigName := "sig1" - verifier, _ := NewHMACSHA256Verifier("key", bytes.Repeat([]byte{1}, 64), nil, + verifier, _ := NewHMACSHA256Verifier(bytes.Repeat([]byte{1}, 64), nil, Headers("@method")) return sigName, verifier } fetchSigner := func(res http.Response, r *http.Request) (string, *Signer) { sigName := "sig1" - signer, _ := NewHMACSHA256Signer("key", bytes.Repeat([]byte{0}, 64), nil, + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{0}, 64), NewSignConfig().SetKeyID("key"), Headers("@status", "bar", "date", "Content-Digest")) return sigName, signer } @@ -38,11 +38,11 @@ func Test_WrapHandler(t *testing.T) { ts := httptest.NewServer(WrapHandler(http.HandlerFunc(simpleHandler), *config)) defer ts.Close() - signer, err := NewHMACSHA256Signer("key", bytes.Repeat([]byte{1}, 64), nil, + signer, err := NewHMACSHA256Signer(bytes.Repeat([]byte{1}, 64), NewSignConfig().SetKeyID("key"), Headers("@method", "content-digest", "@request-target")) assert.NoError(t, err) - verifier, err := NewHMACSHA256Verifier("key", bytes.Repeat([]byte{0}, 64), NewVerifyConfig(), *NewFields()) + verifier, err := NewHMACSHA256Verifier(bytes.Repeat([]byte{0}, 64), NewVerifyConfig().SetKeyID("key"), *NewFields()) assert.NoError(t, err) client := NewDefaultClient(NewClientConfig().SetSignatureName("sig1").SetSigner(signer).SetVerifier(verifier).SetDigestSchemesSend([]string{DigestSha256})) res, err := client.Post(ts.URL+"?foo", "text/plain", strings.NewReader("Message body here")) @@ -68,7 +68,7 @@ func TestWrapHandlerServerSigns(t *testing.T) { } fetchSigner := func(res http.Response, r *http.Request) (string, *Signer) { sigName := "sig1" - signer, _ := NewHMACSHA256Signer("key", bytes.Repeat([]byte{0}, 64), signConfig, + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{0}, 64), signConfig.SetKeyID("key1"), Headers("@status", "bar", "date")) return sigName, signer } @@ -99,7 +99,7 @@ func TestWrapHandlerServerSigns(t *testing.T) { config = config.SetFetchSigner(nil) } if verifyRequest { - serverVerifier, _ := NewHMACSHA256Verifier("key", bytes.Repeat([]byte{9}, 64), NewVerifyConfig(), *NewFields()) + serverVerifier, _ := NewHMACSHA256Verifier(bytes.Repeat([]byte{9}, 64), NewVerifyConfig().SetKeyID("key"), *NewFields()) config = config.SetFetchVerifier(func(r *http.Request) (sigName string, verifier *Verifier) { return "sig333", serverVerifier }) @@ -114,11 +114,11 @@ func TestWrapHandlerServerSigns(t *testing.T) { } else { key = bytes.Repeat([]byte{3}, 64) } - verifyConfig := NewVerifyConfig() + verifyConfig := NewVerifyConfig().SetKeyID("key") if badAlgs { verifyConfig = verifyConfig.SetAllowedAlgs([]string{"zuzu"}) } - verifier, _ := NewHMACSHA256Verifier("key", key, verifyConfig, *NewFields()) + verifier, _ := NewHMACSHA256Verifier(key, verifyConfig, *NewFields()) client := NewDefaultClient(NewClientConfig().SetSignatureName("sig1").SetVerifier(verifier)) res, err := client.Get(ts.URL) @@ -176,7 +176,7 @@ func TestWrapHandlerServerFails(t *testing.T) { // non-default verify handler } fetchVerifier := func(r *http.Request) (string, *Verifier) { sigName := "sig1" - verifier, _ := NewHMACSHA256Verifier("key", bytes.Repeat([]byte{0}, 64), nil, + verifier, _ := NewHMACSHA256Verifier(bytes.Repeat([]byte{0}, 64), NewVerifyConfig().SetKeyID("key"), Headers("@method")) return sigName, verifier } @@ -187,8 +187,8 @@ func TestWrapHandlerServerFails(t *testing.T) { // non-default verify handler // Client code starts here // Create a signer and a wrapped HTTP client (we set SignCreated to false to make the response deterministic, // don't do that in production.) - signer, _ := NewHMACSHA256Signer("key1", bytes.Repeat([]byte{1}, 64), - NewSignConfig().SignCreated(false), Headers("@method")) + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{1}, 64), + NewSignConfig().SetKeyID("key1").SignCreated(false), Headers("@method")) client := NewDefaultClient(NewClientConfig().SetSignatureName("sig22").SetSigner(signer)) // sign, don't verify // Send an HTTP GET, get response -- signing and verification happen behind the scenes diff --git a/handlerex_test.go b/handlerex_test.go index 7fe69f4..3a9240d 100644 --- a/handlerex_test.go +++ b/handlerex_test.go @@ -17,7 +17,7 @@ func ExampleWrapHandler_clientSigns() { // Callback to let the server locate its verifying key and configuration fetchVerifier := func(r *http.Request) (string, *httpsign.Verifier) { sigName := "sig1" - verifier, _ := httpsign.NewHMACSHA256Verifier("key", bytes.Repeat([]byte{0x99}, 64), nil, + verifier, _ := httpsign.NewHMACSHA256Verifier(bytes.Repeat([]byte{0x99}, 64), httpsign.NewVerifyConfig().SetKeyID("key1"), httpsign.Headers("@method")) return sigName, verifier } @@ -35,7 +35,7 @@ func ExampleWrapHandler_clientSigns() { defer ts.Close() // HTTP client code, with a signer - signer, _ := httpsign.NewHMACSHA256Signer("key", bytes.Repeat([]byte{0x99}, 64), nil, + signer, _ := httpsign.NewHMACSHA256Signer(bytes.Repeat([]byte{0x99}, 64), httpsign.NewSignConfig().SetKeyID("key1"), *httpsign.NewFields().AddHeader("content-type").AddQueryParam("pet").AddHeader("@method")) client := httpsign.NewDefaultClient(httpsign.NewClientConfig().SetSignatureName("sig1").SetSigner(signer)) @@ -58,7 +58,7 @@ func ExampleWrapHandler_serverSigns() { // Callback to let the server locate its signing key and configuration fetchSigner := func(res http.Response, r *http.Request) (string, *httpsign.Signer) { sigName := "sig1" - signer, _ := httpsign.NewHMACSHA256Signer("key", bytes.Repeat([]byte{0}, 64), nil, + signer, _ := httpsign.NewHMACSHA256Signer(bytes.Repeat([]byte{0}, 64), httpsign.NewSignConfig().SetKeyID("key"), httpsign.Headers("@status", "bar", "date", "content-type")) return sigName, signer } @@ -76,7 +76,7 @@ func ExampleWrapHandler_serverSigns() { defer ts.Close() // HTTP client code - verifier, _ := httpsign.NewHMACSHA256Verifier("key", bytes.Repeat([]byte{0}, 64), httpsign.NewVerifyConfig(), *httpsign.NewFields()) + verifier, _ := httpsign.NewHMACSHA256Verifier(bytes.Repeat([]byte{0}, 64), httpsign.NewVerifyConfig().SetKeyID("key"), *httpsign.NewFields()) client := httpsign.NewDefaultClient(httpsign.NewClientConfig().SetSignatureName("sig1").SetVerifier(verifier)) res, err := client.Get(ts.URL) if err != nil { diff --git a/http2_test.go b/http2_test.go index 93de722..8984c0f 100644 --- a/http2_test.go +++ b/http2_test.go @@ -75,8 +75,8 @@ func testHTTP(t *testing.T, proto string) { if err != nil { t.Errorf("execTemplate failed") } - verifier, err := NewHMACSHA256Verifier("key1", bytes.Repeat([]byte{0x03}, 64), - NewVerifyConfig().SetVerifyCreated(false), + verifier, err := NewHMACSHA256Verifier(bytes.Repeat([]byte{0x03}, 64), + NewVerifyConfig().SetVerifyCreated(false).SetKeyID("key1"), Headers("@query")) if err != nil { t.Errorf("could not create verifier") @@ -110,8 +110,8 @@ func simpleClient(t *testing.T, proto string, simpleHandler func(w http.Response } defer ts.Close() - signer, err := NewHMACSHA256Signer("key1", bytes.Repeat([]byte{0x03}, 64), - NewSignConfig().SignCreated(false), + signer, err := NewHMACSHA256Signer(bytes.Repeat([]byte{0x03}, 64), + NewSignConfig().SetKeyID("key1").SignCreated(false), *NewFields().AddHeaders("kuku", "@query", "@method", "@target-uri", "@request-target", "@authority", "@scheme", "@target-uri", "@path", "@query").AddQueryParam("k1").AddQueryParam("k2")) if err != nil { diff --git a/signatures.go b/signatures.go index 771cf47..4f96d08 100644 --- a/signatures.go +++ b/signatures.go @@ -17,7 +17,7 @@ func signMessage(config SignConfig, signatureName string, signer Signer, parsedM if err != nil { return "", "", "", err } - sigParams, err := generateSigParams(&config, signer.keyID, signer.alg, signer.foreignSigner, filtered) + sigParams, err := generateSigParams(&config, signer.alg, signer.foreignSigner, filtered) if err != nil { return "", "", "", err } @@ -257,7 +257,7 @@ func quotedString(s string) (string, error) { return result.String(), nil } -func generateSigParams(config *SignConfig, keyID, alg string, foreignSigner interface{}, fields Fields) (string, error) { +func generateSigParams(config *SignConfig, alg string, foreignSigner interface{}, fields Fields) (string, error) { p := httpsfv.NewParams() var createdTime int64 if config.fakeCreated != 0 { @@ -291,7 +291,12 @@ func generateSigParams(config *SignConfig, keyID, alg string, foreignSigner inte } p.Add("tag", qContext) } - p.Add("keyid", keyID) + if config.keyID != nil { + if *config.keyID == "" { + return "", fmt.Errorf("key ID must not be an empty string") + } + p.Add("keyid", *config.keyID) + } return fields.asSignatureInput(p) } @@ -548,7 +553,7 @@ func verifyMessage(config VerifyConfig, verifier Verifier, message, assocMessage if !(psiSig.fields.contains(&filtered)) { return "", fmt.Errorf("actual signature does not cover all required fields") } - err := applyVerificationPolicy(verifier, *message, psiSig, config) + err := applyVerificationPolicy(*message, psiSig, config) if err != nil { return "", err } @@ -587,7 +592,7 @@ func signatureFieldsFromHeaders(header http.Header, name string) ([]byte, *psiSi return wantSigRaw, psiSig, nil } -func applyVerificationPolicy(verifier Verifier, message parsedMessage, psi *psiSignature, config VerifyConfig) error { +func applyVerificationPolicy(message parsedMessage, psi *psiSignature, config VerifyConfig) error { err := applyPolicyCreated(psi, message, config) if err != nil { return err @@ -604,22 +609,22 @@ func applyVerificationPolicy(verifier Verifier, message parsedMessage, psi *psiS if err4 != nil { return err4 } - err5 := applyPolicyOthers(verifier, psi, config) + err5 := applyPolicyOthers(psi, config) if err5 != nil { return err5 } return nil } -func applyPolicyOthers(verifier Verifier, psi *psiSignature, config VerifyConfig) error { - if config.verifyKeyID { +func applyPolicyOthers(psi *psiSignature, config VerifyConfig) error { + if config.keyID != nil { keyidParam, ok := psi.params["keyid"] if ok { keyID, ok := keyidParam.(string) if !ok { return fmt.Errorf("malformed \"keyid\" parameter") } - if keyID != verifier.keyID { + if keyID != *config.keyID { return fmt.Errorf("wrong keyid \"%s\"", keyID) } } diff --git a/signatures_test.go b/signatures_test.go index bc0d72a..86131f9 100644 --- a/signatures_test.go +++ b/signatures_test.go @@ -461,10 +461,10 @@ func TestSignRequest(t *testing.T) { args: args{ signatureName: "sig-b25", signer: (func() Signer { - config := NewSignConfig().SignAlg(false).setFakeCreated(1618884473) + config := NewSignConfig().SignAlg(false).setFakeCreated(1618884473).SetKeyID("test-shared-secret") fields := Headers("date", "@authority", "content-type") key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, config, fields) + signer, _ := NewHMACSHA256Signer(key, config, fields) return *signer })(), req: readRequest(httpreq1), @@ -478,10 +478,10 @@ func TestSignRequest(t *testing.T) { args: args{ signatureName: "sig1", signer: (func() Signer { - config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475) + config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475).SetKeyID("test-shared-secret") fields := Headers("@authorityxx", "date", "content-type") key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, config, fields) + signer, _ := NewHMACSHA256Signer(key, config, fields) return *signer })(), req: readRequest(httpreq1), @@ -495,10 +495,10 @@ func TestSignRequest(t *testing.T) { args: args{ signatureName: "sig1", signer: (func() Signer { - config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475) + config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475).SetKeyID("test-shared-secret") fields := Headers("@authority", "date-not-really", "content-type") key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, config, fields) + signer, _ := NewHMACSHA256Signer(key, config, fields) return *signer })(), req: readRequest(httpreq1), @@ -516,9 +516,9 @@ func TestSignRequest(t *testing.T) { if err != nil { t.Errorf("cannot parse private key: %v", err) } - config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475) + config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475).SetKeyID("test-key-rsa-pss") fields := *NewFields() - signer, _ := NewRSAPSSSigner("test-key-rsa-pss", *prvKey, config, fields) + signer, _ := NewRSAPSSSigner(*prvKey, config, fields) return *signer })(), req: nil, @@ -581,12 +581,14 @@ func TestSignRequest(t *testing.T) { func makeRSAPSSSigner(t *testing.T, config SignConfig, fields Fields) Signer { prvKey, err := loadRSAPSSPrivateKey(rsaPSSPrvKey) assert.NoError(t, err, "cannot parse private key") - signer, _ := NewRSAPSSSigner("test-key-rsa-pss", *prvKey, &config, fields) + config.SetKeyID("test-key-rsa-pss") + signer, _ := NewRSAPSSSigner(*prvKey, &config, fields) return *signer } func makeHMACSigner(config SignConfig, fields Fields) Signer { - signer, _ := NewHMACSHA256Signer("test-key-hmac", bytes.Repeat([]byte{0x33}, 64), &config, fields) + config.SetKeyID("test-key-hmac") + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{0x33}, 64), &config, fields) return *signer } @@ -610,13 +612,13 @@ func TestSignRequestDiscardSig(t *testing.T) { signatureName: "sig-b21", signer: (func() Signer { config := NewSignConfig().SignAlg(false). - setFakeCreated(1618884473).SetNonce("b3k2pp5k7z-50gnwp.yemd") + setFakeCreated(1618884473).SetNonce("b3k2pp5k7z-50gnwp.yemd").SetKeyID("test-key-rsa-pss") fields := *NewFields() prvKey, err := loadRSAPSSPrivateKey(rsaPSSPrvKey) if err != nil { t.Errorf("cannot parse private key: %v", err) } - signer, _ := NewRSAPSSSigner("test-key-rsa-pss", *prvKey, config, fields) + signer, _ := NewRSAPSSSigner(*prvKey, config, fields) return *signer })(), req: readRequest(httpreq1), @@ -668,32 +670,32 @@ func readResponse(s string) *http.Response { } func TestSignAndVerifyHMAC(t *testing.T) { - config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475) + config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475).SetKeyID("test-shared-secret") fields := Headers("@authority", "date", "content-type") signatureName := "sig1" key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, config, fields) + signer, _ := NewHMACSHA256Signer(key, config, fields) req := readRequest(httpreq1) sigInput, sig, _ := SignRequest(signatureName, *signer, req) req.Header.Add("Signature", sig) req.Header.Add("Signature-Input", sigInput) - verifier, err := NewHMACSHA256Verifier("test-shared-secret", key, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err := NewHMACSHA256Verifier(key, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-shared-secret"), fields) assert.NoError(t, err, "could not generate Verifier") err = VerifyRequest(signatureName, *verifier, req) assert.NoError(t, err, "verification error") } func TestSignAndVerifyHMACNoHeader(t *testing.T) { - config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475) + config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475).SetKeyID("test-shared-secret") fields := Headers("@authority", "content-type") signatureName := "sig1" key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, config, fields) + signer, _ := NewHMACSHA256Signer(key, config, fields) req := readRequest(longReq1) _, sig, err := SignRequest(signatureName, *signer, req) assert.NoError(t, err, "failed to sign") req.Header.Add("Signature", sig) - verifier, err := NewHMACSHA256Verifier("test-shared-secret", key, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err := NewHMACSHA256Verifier(key, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-shared-secret"), fields) assert.NoError(t, err, "could not generate Verifier") err = VerifyRequest(signatureName, *verifier, req) assert.Error(t, err, "verification should fail, header not found") @@ -702,24 +704,24 @@ func TestSignAndVerifyHMACNoHeader(t *testing.T) { sigInput, _, err := SignRequest(signatureName, *signer, req) assert.NoError(t, err, "failed to sign") req.Header.Add("Signature-Input", sigInput) - verifier, err = NewHMACSHA256Verifier("test-shared-secret", key, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err = NewHMACSHA256Verifier(key, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-shared-secret"), fields) assert.NoError(t, err, "could not generate Verifier") err = VerifyRequest(signatureName, *verifier, req) assert.Error(t, err, "verification should fail, header not found") } func TestSignAndVerifyHMACBad(t *testing.T) { - config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475) + config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475).SetKeyID("test-shared-secret") fields := Headers("@authority", "date", "content-type") signatureName := "sig1" key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, config, fields) + signer, _ := NewHMACSHA256Signer(key, config, fields) req := readRequest(httpreq1) sigInput, sig, _ := SignRequest(signatureName, *signer, req) req.Header.Add("Signature", sig) req.Header.Add("Signature-Input", sigInput) badkey := append(key, byte(0x77)) - verifier, err := NewHMACSHA256Verifier("test-shared-secret", badkey, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err := NewHMACSHA256Verifier(badkey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-shared-secret"), fields) assert.NoError(t, err, "could not generate Verifier") err = VerifyRequest(signatureName, *verifier, req) assert.Error(t, err, "verification should have failed") @@ -730,8 +732,8 @@ func TestCreated(t *testing.T) { fields := Headers("@status", "date", "content-type") signatureName := "sigres" key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - signConfig := NewSignConfig().SignCreated(true).setFakeCreated(createdTime) - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, signConfig, fields) + signConfig := NewSignConfig().SignCreated(true).setFakeCreated(createdTime).SetKeyID("test-shared-secret") + signer, _ := NewHMACSHA256Signer(key, signConfig, fields) res := readResponse(httpres2) nowStr := time.Now().UTC().Format(http.TimeFormat) res.Header.Set("Date", nowStr) @@ -741,7 +743,7 @@ func TestCreated(t *testing.T) { res2.Header.Set("Date", nowStr) res2.Header.Add("Signature", sig) res2.Header.Add("Signature-Input", sigInput) - verifier, err := NewHMACSHA256Verifier("test-shared-secret", key, verifyConfig, fields) + verifier, err := NewHMACSHA256Verifier(key, verifyConfig, fields) if err != nil { t.Errorf("could not generate Verifier: %s", err) } @@ -794,15 +796,15 @@ func TestSignAndVerifyResponseHMAC(t *testing.T) { fields := Headers("@status", "date", "content-type") signatureName := "sigres" key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - config := NewSignConfig().SetExpires(999) // should have expired long ago (but will be ignored by verifier) - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, config, fields) // default config + config := NewSignConfig().SetExpires(999).SetKeyID("test-shared-secret") // should have expired long ago (but will be ignored by verifier) + signer, _ := NewHMACSHA256Signer(key, config, fields) // default config res := readResponse(httpres2) sigInput, sig, _ := SignResponse(signatureName, *signer, res, nil) res2 := readResponse(httpres2) res2.Header.Add("Signature", sig) res2.Header.Add("Signature-Input", sigInput) - verifier, err := NewHMACSHA256Verifier("test-shared-secret", key, NewVerifyConfig().SetRejectExpired(false), fields) + verifier, err := NewHMACSHA256Verifier(key, NewVerifyConfig().SetRejectExpired(false).SetKeyID("test-shared-secret"), fields) if err != nil { t.Errorf("could not generate Verifier: %s", err) } @@ -813,14 +815,14 @@ func TestSignAndVerifyResponseHMAC(t *testing.T) { } func TestSignAndVerifyRSAPSS(t *testing.T) { - config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475) + config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475).SetKeyID("test-key-rsa-pss") fields := Headers("@authority", "date", "content-type") signatureName := "sig1" prvKey, err := loadRSAPSSPrivateKey(rsaPSSPrvKey) if err != nil { t.Errorf("cannot read private key") } - signer, _ := NewRSAPSSSigner("test-key-rsa-pss", *prvKey, config, fields) + signer, _ := NewRSAPSSSigner(*prvKey, config, fields) req := readRequest(httpreq1) sigInput, sig, _ := SignRequest(signatureName, *signer, req) req.Header.Add("Signature", sig) @@ -829,7 +831,7 @@ func TestSignAndVerifyRSAPSS(t *testing.T) { if err != nil { t.Errorf("cannot read public key: %v", err) } - verifier, err := NewRSAPSSVerifier("test-key-rsa-pss", *pubKey, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err := NewRSAPSSVerifier(*pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-rsa-pss"), fields) if err != nil { t.Errorf("could not generate Verifier: %s", err) } @@ -840,14 +842,14 @@ func TestSignAndVerifyRSAPSS(t *testing.T) { } func TestSignAndVerifyRSA(t *testing.T) { - config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475) + config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475).SetKeyID("test-key-rsa") fields := Headers("@authority", "date", "content-type") signatureName := "sig1" prvKey, err := parseRsaPrivateKeyFromPemStr(rsaPrvKey2) if err != nil { t.Errorf("cannot read private key") } - signer, _ := NewRSASigner("test-key-rsa", *prvKey, config, fields) + signer, _ := NewRSASigner(*prvKey, config, fields) req := readRequest(httpreq1) sigInput, sig, _ := SignRequest(signatureName, *signer, req) req.Header.Add("Signature", sig) @@ -856,7 +858,7 @@ func TestSignAndVerifyRSA(t *testing.T) { if err != nil { t.Errorf("cannot read public key: %v", err) } - verifier, err := NewRSAVerifier("test-key-rsa", *pubKey, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err := NewRSAVerifier(*pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-rsa"), fields) if err != nil { t.Errorf("could not generate Verifier: %s", err) } @@ -867,14 +869,14 @@ func TestSignAndVerifyRSA(t *testing.T) { } func TestSignAndVerifyP256(t *testing.T) { - config := NewSignConfig().setFakeCreated(1618884475) + config := NewSignConfig().setFakeCreated(1618884475).SetKeyID("test-key-p256") signatureName := "sig1" prvKey, pubKey, err := genP256KeyPair() if err != nil { t.Errorf("cannot generate P-256 keypair") } fields := *NewFields().AddHeader("@method").AddHeader("Date").AddHeader("Content-Type").AddQueryParam("pet") - signer, _ := NewP256Signer("test-key-p256", *prvKey, config, fields) + signer, _ := NewP256Signer(*prvKey, config, fields) req := readRequest(httpreq2) sigInput, sig, err := SignRequest(signatureName, *signer, req) if err != nil { @@ -882,7 +884,7 @@ func TestSignAndVerifyP256(t *testing.T) { } req.Header.Add("Signature", sig) req.Header.Add("Signature-Input", sigInput) - verifier, err := NewP256Verifier("test-key-p256", *pubKey, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err := NewP256Verifier(*pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-p256"), fields) if err != nil { t.Errorf("could not generate Verifier: %s", err) } @@ -893,14 +895,14 @@ func TestSignAndVerifyP256(t *testing.T) { } func TestSignAndVerifyP384(t *testing.T) { - config := NewSignConfig().setFakeCreated(1618884475) + config := NewSignConfig().setFakeCreated(1618884475).SetKeyID("test-key-p384") signatureName := "sig1" prvKey, pubKey, err := genP384KeyPair() if err != nil { t.Errorf("cannot generate P-384 keypair") } fields := *NewFields().AddHeader("@method").AddHeader("Date").AddHeader("Content-Type").AddQueryParam("pet") - signer, _ := NewP384Signer("test-key-p384", *prvKey, config, fields) + signer, _ := NewP384Signer(*prvKey, config, fields) req := readRequest(httpreq2) sigInput, sig, err := SignRequest(signatureName, *signer, req) if err != nil { @@ -908,7 +910,7 @@ func TestSignAndVerifyP384(t *testing.T) { } req.Header.Add("Signature", sig) req.Header.Add("Signature-Input", sigInput) - verifier, err := NewP384Verifier("test-key-p384", *pubKey, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err := NewP384Verifier(*pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-p384"), fields) if err != nil { t.Errorf("could not generate Verifier: %s", err) } @@ -923,9 +925,9 @@ func TestSignAndVerifyEdDSA(t *testing.T) { if err != nil { t.Errorf("cannot generate keypair: %s", err) } - config := NewSignConfig().setFakeCreated(1618884475) + config := NewSignConfig().setFakeCreated(1618884475).SetKeyID("test-key-ed25519") fields := *NewFields().AddHeader("@method").AddHeader("Date").AddHeader("Content-Type").AddQueryParam("pet") - signer1, _ := NewEd25519Signer("test-key-ed25519", prvKey1, config, fields) + signer1, _ := NewEd25519Signer(prvKey1, config, fields) signAndVerifyEdDSA(t, signer1, pubKey1, fields) @@ -934,10 +936,11 @@ func TestSignAndVerifyEdDSA(t *testing.T) { if err != nil { t.Errorf("rand failed?") } + config.SetKeyID("test-key-ed25519") prvKey2 := ed25519.NewKeyFromSeed(seed2) pubKey2 := prvKey2.Public().(ed25519.PublicKey) - signer2, _ := NewEd25519SignerFromSeed("test-key-ed25519", seed2, config, fields) + signer2, _ := NewEd25519SignerFromSeed(seed2, config, fields) signAndVerifyEdDSA(t, signer2, pubKey2, fields) } @@ -951,7 +954,7 @@ func signAndVerifyEdDSA(t *testing.T, signer *Signer, pubKey ed25519.PublicKey, } req.Header.Add("Signature", sig) req.Header.Add("Signature-Input", sigInput) - verifier, err := NewEd25519Verifier("test-key-ed25519", pubKey, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err := NewEd25519Verifier(pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-ed25519"), fields) if err != nil { t.Errorf("could not generate Verifier: %s", err) } @@ -980,8 +983,8 @@ func TestSignResponse(t *testing.T) { signatureName: "sig1", signer: (func() Signer { key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, NewSignConfig().setFakeCreated(1618889999), Headers( - "@status", "date", "content-type")) + signer, _ := NewHMACSHA256Signer(key, NewSignConfig().setFakeCreated(1618889999). + SetKeyID("test-shared-secret"), Headers("@status", "date", "content-type")) return *signer })(), res: readResponse(httpres1), @@ -996,7 +999,7 @@ func TestSignResponse(t *testing.T) { signatureName: "sig1", signer: (func() Signer { key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, NewSignConfig().setFakeCreated(1618889999), Headers( + signer, _ := NewHMACSHA256Signer(key, NewSignConfig().setFakeCreated(1618889999).SetKeyID("test-shared-secret"), Headers( "@status", "date", "content-type", )) @@ -1057,7 +1060,7 @@ func TestVerifyRequest(t *testing.T) { if err != nil { t.Errorf("cannot parse public key: %v", err) } - verifier, _ := NewRSAPSSVerifier("test-key-rsa-pss", *pubKey, NewVerifyConfig().SetVerifyCreated(false), *NewFields()) + verifier, _ := NewRSAPSSVerifier(*pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-rsa-pss"), *NewFields()) return *verifier })(), req: readRequest(httpreq1pssSelective), @@ -1074,7 +1077,7 @@ func TestVerifyRequest(t *testing.T) { if err != nil { t.Errorf("cannot parse public key: %v", err) } - verifier, _ := NewRSAPSSVerifier("test-key-rsa-pss", *pubKey, NewVerifyConfig().SetVerifyCreated(false), *NewFields()) + verifier, _ := NewRSAPSSVerifier(*pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-rsa-pss"), *NewFields()) return *verifier })(), req: readRequest(httpreq1pssFull), @@ -1092,7 +1095,7 @@ func TestVerifyRequest(t *testing.T) { t.Errorf("cannot parse public key: %v", err) } pubKey := prvKey.Public().(ed25519.PublicKey) - verifier, _ := NewEd25519Verifier("test-key-ed25519", pubKey, NewVerifyConfig().SetVerifyCreated(false), *NewFields()) + verifier, _ := NewEd25519Verifier(pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-ed25519"), *NewFields()) return *verifier })(), req: readRequest(httpreq1ed25519), @@ -1106,7 +1109,7 @@ func TestVerifyRequest(t *testing.T) { signatureName: "ttrp", verifier: (func() Verifier { pubKey, _ := parseECPublicKeyFromPemStr(p256PubKey2) - verifier, _ := NewP256Verifier("test-key-ecc-p256", *pubKey, NewVerifyConfig().SetVerifyCreated(false), *NewFields()) + verifier, _ := NewP256Verifier(*pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-ecc-p256"), *NewFields()) return *verifier })(), req: readRequest(httpreqtlsproxy), @@ -1143,7 +1146,7 @@ func TestVerifyRequest(t *testing.T) { if err != nil { t.Errorf("cannot parse public key: %v", err) } - verifier, _ := NewRSAPSSVerifier("bad-key-id", *pubKey, NewVerifyConfig().SetVerifyCreated(false), *NewFields()) + verifier, _ := NewRSAPSSVerifier(*pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("bad-key-id"), *NewFields()) return *verifier })(), req: readRequest(httpreq1pssSelective), @@ -1152,7 +1155,7 @@ func TestVerifyRequest(t *testing.T) { wantErr: true, }, { - name: "bad keyID but not verified", // this is NOT a failure + name: "keyID not verified", // this is NOT a failure args: args{ signatureName: "sig-b22", verifier: (func() Verifier { @@ -1160,8 +1163,8 @@ func TestVerifyRequest(t *testing.T) { if err != nil { t.Errorf("cannot parse public key: %v", err) } - verifier, _ := NewRSAPSSVerifier("bad-key-id", *pubKey, NewVerifyConfig(). - SetVerifyCreated(false).SetVerifyKeyID(false), *NewFields()) + verifier, _ := NewRSAPSSVerifier(*pubKey, NewVerifyConfig(). + SetVerifyCreated(false), *NewFields()) return *verifier })(), req: readRequest(httpreq1pssSelective), @@ -1191,7 +1194,7 @@ func makeRSAVerifier(f failer, keyID string, fields Fields) Verifier { if err != nil { f.Errorf("cannot parse public key: %v", err) } - verifier, _ := NewRSAPSSVerifier(keyID, *pubKey, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, _ := NewRSAPSSVerifier(*pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID(keyID), fields) return *verifier })() } @@ -1318,7 +1321,7 @@ func TestDictionary(t *testing.T) { } res := readResponse(httpres2) res.Header.Set("X-Dictionary", "a=1, b=2;x=1;y=2, c=(a b c)") - signer2, err := NewP256Signer("key10", *priv, NewSignConfig(), + signer2, err := NewP256Signer(*priv, NewSignConfig().SetKeyID("key10"), *NewFields().AddHeader("@status").AddDictHeader("x-dictionary", "a")) if err != nil { t.Errorf("Could not create signer") @@ -1331,7 +1334,7 @@ func TestDictionary(t *testing.T) { res.Header.Add("Signature", sig2) // Client verifies response - verifier2, err := NewP256Verifier("key10", *pub, NewVerifyConfig().SetVerifyCreated(false), + verifier2, err := NewP256Verifier(*pub, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("key10"), *NewFields().AddHeader("@status").AddDictHeader("x-dictionary", "a")) if err != nil { t.Errorf("Could not create verifier: %v", err) @@ -1348,7 +1351,7 @@ func TestMultipleSignaturesOld(t *testing.T) { t.Errorf("Could not create keypair") } res := readResponse(httpres2) - signer1, err := NewP256Signer("key10", *priv1, NewSignConfig().SignCreated(false), Headers("Content-Type", "Digest")) + signer1, err := NewP256Signer(*priv1, NewSignConfig().SignCreated(false).SetKeyID("key10"), Headers("Content-Type", "Digest")) if err != nil { t.Errorf("Could not create signer") } @@ -1363,7 +1366,7 @@ func TestMultipleSignaturesOld(t *testing.T) { if err != nil { t.Errorf("Could not create keypair") } - signer2, err := NewP256Signer("key20", *priv2, NewSignConfig().SignCreated(false), *NewFields().AddDictHeader("Signature", "sig2")) + signer2, err := NewP256Signer(*priv2, NewSignConfig().SignCreated(false).SetKeyID("key20"), *NewFields().AddDictHeader("Signature", "sig2")) if err != nil { t.Errorf("Could not create signer") } @@ -1399,8 +1402,8 @@ func TestMultipleSignatures(t *testing.T) { req := readRequest(httpreq9) pubKey1, err := parseECPublicKeyFromPemStr(p256PubKey2) assert.NoError(t, err, "cannot parse ECC public key") - verifier1, err := NewP256Verifier("test-key-ecc-p256", *pubKey1, NewVerifyConfig(). - SetVerifyCreated(false), Headers("@method", "@authority", "@path", "content-digest", + verifier1, err := NewP256Verifier(*pubKey1, NewVerifyConfig(). + SetVerifyCreated(false).SetKeyID("test-key-ecc-p256"), Headers("@method", "@authority", "@path", "content-digest", "content-type", "content-length")) assert.NoError(t, err, "cannot create verifier1") _, err = verifyRequestDebug("sig1", *verifier1, req) @@ -1408,8 +1411,8 @@ func TestMultipleSignatures(t *testing.T) { pubKey2, err := parseRsaPublicKey(rsaPubKey) assert.NoError(t, err, "cannot parse RSA public key") - verifier2, err := NewRSAVerifier("test-key-rsa", *pubKey2, NewVerifyConfig(). - SetVerifyCreated(false).SetRejectExpired(false), *NewFields().AddDictHeader("Signature", "sig1").AddHeaders("@authority", "forwarded")) + verifier2, err := NewRSAVerifier(*pubKey2, NewVerifyConfig(). + SetVerifyCreated(false).SetRejectExpired(false).SetKeyID("test-key-rsa"), *NewFields().AddDictHeader("Signature", "sig1").AddHeaders("@authority", "forwarded")) assert.NoError(t, err, "cannot create verifier2") _, err = verifyRequestDebug("proxy_sig", *verifier2, req) assert.NoError(t, err, "proxy signature not verified") @@ -1611,7 +1614,7 @@ func TestVerifyResponse(t *testing.T) { if err != nil { t.Errorf("cannot parse public key: %v", err) } - verifier, _ := NewP256Verifier("test-key-ecc-p256", *pubKey, NewVerifyConfig().SetVerifyCreated(false), *NewFields()) + verifier, _ := NewP256Verifier(*pubKey, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-ecc-p256"), *NewFields()) return *verifier })(), res: readResponse(httpres4), @@ -1632,7 +1635,7 @@ func TestOptionalSign(t *testing.T) { req := readRequest(httpreq2) f1 := NewFields().AddHeader("date").AddHeaderExt("x-optional", true, false, false, false) key1 := bytes.Repeat([]byte{0x55}, 64) - signer1, err := NewHMACSHA256Signer("key1", key1, NewSignConfig().setFakeCreated(9999), *f1) + signer1, err := NewHMACSHA256Signer(key1, NewSignConfig().setFakeCreated(9999).SetKeyID("key1"), *f1) assert.NoError(t, err, "Could not create signer") signatureInput, _, signatureBase, err := signRequestDebug("sig1", *signer1, req) assert.NoError(t, err, "Should not fail with optional header absent") @@ -1646,7 +1649,7 @@ func TestOptionalSign(t *testing.T) { assert.Equal(t, "\"date\": Tue, 20 Apr 2021 02:07:55 GMT\n\"x-optional\": value\n\"@signature-params\": (\"date\" \"x-optional\");created=9999;alg=\"hmac-sha256\";keyid=\"key1\"", signatureBase) f2 := f1.AddQueryParamExt("bla", true, false, false).AddQueryParamExt("bar", true, false, false) - signer2, err := NewHMACSHA256Signer("key1", key1, NewSignConfig().setFakeCreated(9999), *f2) + signer2, err := NewHMACSHA256Signer(key1, NewSignConfig().setFakeCreated(9999).SetKeyID("key1"), *f2) assert.NoError(t, err, "Could not create signer") signatureInput, _, signatureBase, err = signRequestDebug("sig1", *signer2, req) assert.NoError(t, err, "Should not fail with query params") @@ -1656,7 +1659,7 @@ func TestOptionalSign(t *testing.T) { res1 := readResponse(httpres2) res1.Header.Set("X-Dictionary", "a=1, b=2;x=1;y=2, c=(a b c)") f3 := NewFields().AddDictHeaderExt("x-dictionary", "a", true, false, false).AddDictHeaderExt("x-dictionary", "zz", true, false, false) - signer3, err := NewHMACSHA256Signer("key1", key1, NewSignConfig().setFakeCreated(9999), *f3) + signer3, err := NewHMACSHA256Signer(key1, NewSignConfig().setFakeCreated(9999).SetKeyID("key1"), *f3) assert.NoError(t, err, "Could not create signer") signatureInput, _, signatureBase, err = signResponseDebug("sig1", *signer3, res1, nil) assert.NoError(t, err, "Should not fail with dict headers") @@ -1666,7 +1669,7 @@ func TestOptionalSign(t *testing.T) { res2 := readResponse(httpres2) res2.Header.Set("X-Dictionary", "a=1, b=2;x=1;y=2, c=(a b c)") f4 := NewFields().AddStructuredFieldExt("x-dictionary", true, false, false).AddStructuredFieldExt("x-not-a-dictionary", true, false, false) - signer4, err := NewHMACSHA256Signer("key1", key1, NewSignConfig().setFakeCreated(9999), *f4) + signer4, err := NewHMACSHA256Signer(key1, NewSignConfig().setFakeCreated(9999).SetKeyID("key1"), *f4) assert.NoError(t, err, "Could not create signer") signatureInput, _, signatureBase, err = signResponseDebug("sig1", *signer4, res2, nil) assert.NoError(t, err, "Should not fail with structured fields") @@ -1681,7 +1684,7 @@ func TestAssocMessage(t *testing.T) { res1.Header.Set("X-Dictionary", "a=1, b=2;x=1;y=2, c=(a b c)") f3 := NewFields().AddDictHeaderExt("x-dictionary", "a", true, false, false).AddDictHeaderExt("x-dictionary", "zz", true, false, false). AddQueryParamExt("pet", false, true, false) - signer3, err := NewHMACSHA256Signer("key1", key1, NewSignConfig().setFakeCreated(9999), *f3) + signer3, err := NewHMACSHA256Signer(key1, NewSignConfig().setFakeCreated(9999).SetKeyID("key1"), *f3) assert.NoError(t, err, "Could not create signer") signatureInput, signature, signatureBase, err := signResponseDebug("sig1", *signer3, res1, assocReq) assert.NoError(t, err, "Should not fail with dict headers") @@ -1690,7 +1693,7 @@ func TestAssocMessage(t *testing.T) { res1.Header.Add("Signature-Input", signatureInput) res1.Header.Add("Signature", signature) - verifier, err := NewHMACSHA256Verifier("key1", key1, NewVerifyConfig().SetVerifyCreated(false), *f3) + verifier, err := NewHMACSHA256Verifier(key1, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("key1"), *f3) assert.NoError(t, err, "Should create verifier") err = VerifyResponse("sig1", *verifier, res1, assocReq) assert.NoError(t, err, "Verification should succeed") @@ -1765,7 +1768,7 @@ func TestRequestBinding(t *testing.T) { pubKey2, err := parseECPublicKeyFromPemStr(p256PubKey2) assert.NoError(t, err, "read pub key") fields2 := *NewFields() - verifier2, err := NewP256Verifier("test-key-ecc-p256", *pubKey2, NewVerifyConfig().SetVerifyCreated(false), fields2) + verifier2, err := NewP256Verifier(*pubKey2, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-ecc-p256"), fields2) assert.NoError(t, err, "create verifier") err = VerifyResponse("reqres", *verifier2, res, req) assert.NoError(t, err, "verify response") @@ -1776,14 +1779,14 @@ func TestOptionalVerify(t *testing.T) { req.Header.Add("X-Opt1", "val1") f1 := NewFields().AddHeader("date").AddHeaderExt("x-opt1", true, false, false, false) key1 := bytes.Repeat([]byte{0x66}, 64) - signer, err := NewHMACSHA256Signer("key1", key1, NewSignConfig().setFakeCreated(8888), *f1) + signer, err := NewHMACSHA256Signer(key1, NewSignConfig().setFakeCreated(8888).SetKeyID("key1"), *f1) assert.NoError(t, err, "Could not create signer") sigInput, signature, err := SignRequest("sig1", *signer, req) assert.NoError(t, err, "Should not fail with optional header present") req.Header.Add("Signature-Input", sigInput) req.Header.Add("Signature", signature) - verifier, err := NewHMACSHA256Verifier("key1", key1, NewVerifyConfig().SetVerifyCreated(false), *f1) + verifier, err := NewHMACSHA256Verifier(key1, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("key1"), *f1) assert.NoError(t, err, "Could not create verifier") err = VerifyRequest("sig1", *verifier, req) assert.NoError(t, err, "Should not fail: present and signed") @@ -1795,7 +1798,7 @@ func TestOptionalVerify(t *testing.T) { req = readRequest(httpreq2) // header present but not signed req.Header.Add("X-Opt1", "val1") f2 := NewFields().AddHeader("date") // without the optional header - signer, err = NewHMACSHA256Signer("key1", key1, NewSignConfig().setFakeCreated(2222), *f2) + signer, err = NewHMACSHA256Signer(key1, NewSignConfig().setFakeCreated(2222).SetKeyID("key1"), *f2) assert.NoError(t, err, "Should not fail to create Signer") sigInput, signature, err = SignRequest("sig1", *signer, req) assert.NoError(t, err, "Should not fail with redundant header present") @@ -1818,13 +1821,13 @@ func TestBinarySequence(t *testing.T) { res.Header.Add("Set-Cookie", "d=5, eee") // First signature try fails - signer1, err := NewP256Signer("key20", *priv, NewSignConfig(), + signer1, err := NewP256Signer(*priv, NewSignConfig().SetKeyID("key20"), *NewFields().AddHeader("@status").AddHeaderExt("set-cookie", false, false, false, false)) assert.NoError(t, err, "could not create signer") _, _, err = SignResponse("sig2", *signer1, res, nil) assert.Error(t, err, "signature should have failed") - signer2, err := NewP256Signer("key20", *priv, NewSignConfig().setFakeCreated(1659563420), + signer2, err := NewP256Signer(*priv, NewSignConfig().setFakeCreated(1659563420).SetKeyID("key20"), *NewFields().AddHeader("@status").AddHeaderExt("set-cookie", false, true, false, false)) assert.NoError(t, err, "could not create signer") sigInput, sig, sigBase, err := signResponseDebug("sig2", *signer2, res, nil) @@ -1834,14 +1837,14 @@ func TestBinarySequence(t *testing.T) { res.Header.Add("Signature", sig) // Client verifies response - should fail - verifier1, err := NewP256Verifier("key20", *pub, NewVerifyConfig().SetVerifyCreated(false), + verifier1, err := NewP256Verifier(*pub, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("key20"), *NewFields().AddHeader("@status").AddHeaderExt("set-cookie", false, false, false, false)) assert.NoError(t, err, "could not create verifier") err = VerifyResponse("sig2", *verifier1, res, nil) assert.Error(t, err, "binary sequence verified as non-bs") // Client verifies response - should succeed - verifier2, err := NewP256Verifier("key20", *pub, NewVerifyConfig().SetVerifyCreated(false), + verifier2, err := NewP256Verifier(*pub, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("key20"), *NewFields().AddHeader("@status").AddHeaderExt("set-cookie", false, true, false, false)) assert.NoError(t, err, "could not create verifier") err = VerifyResponse("sig2", *verifier2, res, nil) @@ -1853,7 +1856,7 @@ func TestSignatureTag(t *testing.T) { assert.NoError(t, err, "failed to generate key") res := readResponse(httpres2) - signer1, err := NewP256Signer("key21", *priv, NewSignConfig().SetTag("ctx1").setFakeCreated(1660755826), + signer1, err := NewP256Signer(*priv, NewSignConfig().SetTag("ctx1").setFakeCreated(1660755826).SetKeyID("key21"), *NewFields().AddHeader("@status")) assert.NoError(t, err, "could not create signer") sigInput, sig, sigBase, err := signResponseDebug("sig2", *signer1, res, nil) @@ -1863,28 +1866,35 @@ func TestSignatureTag(t *testing.T) { res.Header.Add("Signature", sig) // Signature should fail with malformed tag - signer2, err := NewP256Signer("key21", *priv, NewSignConfig().SetTag("ctx1\x00"), + signer2, err := NewP256Signer(*priv, NewSignConfig().SetTag("ctx1\x00").SetKeyID("key21"), *NewFields().AddHeader("@status")) assert.NoError(t, err, "could not create signer") _, _, _, err = signResponseDebug("sig2", *signer2, res, nil) assert.Error(t, err, "signature should fail") + // Signature should fail when the key ID is an empty string + signer3, err := NewP256Signer(*priv, NewSignConfig().SetKeyID(""), + *NewFields().AddHeader("@status")) + assert.NoError(t, err, "could not create signer") + _, _, _, err = signResponseDebug("sig2", *signer3, res, nil) + assert.Error(t, err, "signature should fail") + // Client verifies response - should succeed, no tag constraint - verifier1, err := NewP256Verifier("key21", *pub, NewVerifyConfig().SetVerifyCreated(false), + verifier1, err := NewP256Verifier(*pub, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("key21"), *NewFields().AddHeader("@status")) assert.NoError(t, err, "could not create verifier") err = VerifyResponse("sig2", *verifier1, res, nil) assert.NoError(t, err, "failed to verify response") // Client verifies response - should succeed, correct tag - verifier2, err := NewP256Verifier("key21", *pub, NewVerifyConfig().SetVerifyCreated(false).SetAllowedTags([]string{"ctx3", "ctx2", "ctx1"}), + verifier2, err := NewP256Verifier(*pub, NewVerifyConfig().SetVerifyCreated(false).SetAllowedTags([]string{"ctx3", "ctx2", "ctx1"}).SetKeyID("key21"), *NewFields().AddHeader("@status")) assert.NoError(t, err, "could not create verifier") err = VerifyResponse("sig2", *verifier2, res, nil) assert.NoError(t, err, "failed to verify response") // Client verifies response - should fail, incorrect tags - verifier3, err := NewP256Verifier("key21", *pub, NewVerifyConfig().SetVerifyCreated(false).SetAllowedTags([]string{"ctx5", "ctx6", "ctx7"}), + verifier3, err := NewP256Verifier(*pub, NewVerifyConfig().SetVerifyCreated(false).SetAllowedTags([]string{"ctx5", "ctx6", "ctx7"}).SetKeyID("key21"), *NewFields().AddHeader("@status")) assert.NoError(t, err, "could not create verifier") err = VerifyResponse("sig2", *verifier3, res, nil) @@ -1958,7 +1968,7 @@ func testOneTransformation(t *testing.T, msg string, verifies bool) { t.Errorf("cannot parse public key: %v", err) } pubKey := prvKey.Public().(ed25519.PublicKey) - verifier, err := NewEd25519Verifier("test-key-ed25519", pubKey, NewVerifyConfig().SetVerifyCreated(false), *NewFields()) + verifier, err := NewEd25519Verifier(pubKey, NewVerifyConfig().SetVerifyCreated(false), *NewFields()) assert.NoError(t, err, "could not create verifier") req := readRequest(msg) err = VerifyRequest("transform", *verifier, req) @@ -1988,7 +1998,7 @@ func TestQPEncoding(t *testing.T) { req := readRequest(httpreq10) f1 := NewFields().AddQueryParam("var").AddQueryParam("bar").AddQueryParam("façade\": ") key1 := bytes.Repeat([]byte{0x67}, 64) - signer, err := NewHMACSHA256Signer("key1", key1, NewSignConfig().setFakeCreated(8888), *f1) + signer, err := NewHMACSHA256Signer(key1, NewSignConfig().setFakeCreated(8888).SetKeyID("key1"), *f1) assert.NoError(t, err, "Could not create signer") _, _, sigBase, err := signRequestDebug("sig1", *signer, req) assert.NoError(t, err, "Should not fail while signing weird QPs") @@ -2035,7 +2045,7 @@ func TestRequestBinding17(t *testing.T) { AddHeaderExt("@method", false, false, true, false). AddHeaderExt("@path", false, false, true, false). AddHeaderExt("content-digest", false, false, true, false) - verifier2, err := NewP256Verifier("test-key-ecc-p256", *pubKey2, NewVerifyConfig().SetVerifyCreated(false), fields2) + verifier2, err := NewP256Verifier(*pubKey2, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-ecc-p256"), fields2) assert.NoError(t, err, "create verifier") sigBase, err := verifyResponseDebug("reqres", *verifier2, res, req) expected := `"@status": 503 @@ -2084,8 +2094,8 @@ func TestMultipleSignatures17(t *testing.T) { req := readRequest(httpreq12) pubKey1, err := parseECPublicKeyFromPemStr(p256PubKey2) assert.NoError(t, err, "cannot parse ECC public key") - verifier1, err := NewP256Verifier("test-key-ecc-p256", *pubKey1, NewVerifyConfig(). - SetVerifyCreated(false), Headers("@method", "@authority", "@path", "content-digest", + verifier1, err := NewP256Verifier(*pubKey1, NewVerifyConfig(). + SetVerifyCreated(false).SetKeyID("test-key-ecc-p256"), Headers("@method", "@authority", "@path", "content-digest", "content-type", "content-length")) assert.NoError(t, err, "cannot create verifier1") _, err = verifyRequestDebug("sig1", *verifier1, req) @@ -2093,7 +2103,7 @@ func TestMultipleSignatures17(t *testing.T) { pubKey2, err := parseRsaPublicKey(rsaPubKey) assert.NoError(t, err, "cannot parse RSA public key") - verifier2, err := NewRSAVerifier("test-key-rsa", *pubKey2, NewVerifyConfig(). + verifier2, err := NewRSAVerifier(*pubKey2, NewVerifyConfig(). SetVerifyCreated(false).SetRejectExpired(false), *NewFields().AddHeaders("@authority", "forwarded")) assert.NoError(t, err, "cannot create verifier2") _, err = verifyRequestDebug("proxy_sig", *verifier2, req) @@ -2144,7 +2154,7 @@ func TestRequestBindingSignedResponse17(t *testing.T) { AddHeaderExt("@path", false, false, true, false). AddHeaderExt("@query", false, false, true, false). AddHeaderExt("content-digest", false, false, true, false) - verifier2, err := NewP256Verifier("test-key-ecc-p256", *pubKey2, NewVerifyConfig().SetVerifyCreated(false), fields2) + verifier2, err := NewP256Verifier(*pubKey2, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-key-ecc-p256"), fields2) assert.NoError(t, err, "create verifier") sigBase, err := verifyResponseDebug("reqres", *verifier2, res, req) expected := `"@status": 503 diff --git a/signaturesex_test.go b/signaturesex_test.go index cef3318..ab6df42 100644 --- a/signaturesex_test.go +++ b/signaturesex_test.go @@ -10,9 +10,9 @@ import ( ) func ExampleSignRequest() { - config := httpsign.NewSignConfig().SignCreated(false).SetNonce("BADCAB") // SignCreated should be "true" to protect against replay attacks + config := httpsign.NewSignConfig().SignCreated(false).SetNonce("BADCAB").SetKeyID("my-shared-secret") // SignCreated should be "true" to protect against replay attacks fields := httpsign.Headers("@authority", "Date", "@method") - signer, _ := httpsign.NewHMACSHA256Signer("my-shared-secret", bytes.Repeat([]byte{0x77}, 64), config, fields) + signer, _ := httpsign.NewHMACSHA256Signer(bytes.Repeat([]byte{0x77}, 64), config, fields) reqStr := `GET /foo HTTP/1.1 Host: example.org Date: Tue, 20 Apr 2021 02:07:55 GMT @@ -28,8 +28,8 @@ Cache-Control: max-age=60 } func ExampleVerifyRequest() { - config := httpsign.NewVerifyConfig().SetVerifyCreated(false) // for testing only - verifier, _ := httpsign.NewHMACSHA256Verifier("my-shared-secret", bytes.Repeat([]byte{0x77}, 64), config, + config := httpsign.NewVerifyConfig().SetKeyID("my-shared-secret").SetVerifyCreated(false) // for testing only + verifier, _ := httpsign.NewHMACSHA256Verifier(bytes.Repeat([]byte{0x77}, 64), config, httpsign.Headers("@authority", "Date", "@method")) reqStr := `GET /foo HTTP/1.1 Host: example.org diff --git a/trailer_test.go b/trailer_test.go index 8602580..5093bd8 100644 --- a/trailer_test.go +++ b/trailer_test.go @@ -57,7 +57,7 @@ var longReq1 = rawHeaders1 + "5000\r\n" + strings.Repeat("x", 0x5000) + "\r\n\r\ func TestTrailer_Get(t *testing.T) { fetchVerifier := func(r *http.Request) (string, *Verifier) { sigName := "sig1" - verifier, _ := NewHMACSHA256Verifier("key1", bytes.Repeat([]byte{1}, 64), nil, + verifier, _ := NewHMACSHA256Verifier(bytes.Repeat([]byte{1}, 64), NewVerifyConfig().SetKeyID("key1"), *NewFields().AddHeader("@method"). AddHeaderExt("hdr", false, false, false, true)) return sigName, verifier @@ -65,7 +65,7 @@ func TestTrailer_Get(t *testing.T) { fetchSigner := func(res http.Response, r *http.Request) (string, *Signer) { sigName := "sig1" - signer, _ := NewHMACSHA256Signer("key", bytes.Repeat([]byte{0}, 64), nil, + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{0}, 64), NewSignConfig().SetKeyID("key"), Headers("@status", "bar", "date", "Content-Digest")) return sigName, signer } @@ -84,7 +84,7 @@ func TestTrailer_Get(t *testing.T) { c := &Client{config: ClientConfig{ signatureName: "sig1", signer: func() *Signer { - signer, _ := NewHMACSHA256Signer("key1", bytes.Repeat([]byte{1}, 64), NewSignConfig(), + signer, _ := NewHMACSHA256Signer(bytes.Repeat([]byte{1}, 64), NewSignConfig().SetKeyID("key1"), *NewFields().AddHeader("@method"). AddHeaderExt("hdr", false, false, false, true)) return signer @@ -139,11 +139,11 @@ func TestTrailer_Get(t *testing.T) { } func TestTrailer_SigFields(t *testing.T) { - config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475) + config := NewSignConfig().SignAlg(false).setFakeCreated(1618884475).SetKeyID("test-shared-secret") fields := Headers("@authority", "@method", "content-type") signatureName := "sig1" key, _ := base64.StdEncoding.DecodeString("uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ==") - signer, _ := NewHMACSHA256Signer("test-shared-secret", key, config, fields) + signer, _ := NewHMACSHA256Signer(key, config, fields) req := readRequest(rawPost2) sigInput, sig, err := SignRequest(signatureName, *signer, req) assert.NoError(t, err, "signature failed") @@ -152,7 +152,7 @@ func TestTrailer_SigFields(t *testing.T) { signedMessage = strings.Replace(signedMessage, "Trailer: Expires, Hdr", "Trailer: Expires, Hdr, Signature, Signature-Input", 1) req2 := readRequestChunked(signedMessage) - verifier, err := NewHMACSHA256Verifier("test-shared-secret", key, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err := NewHMACSHA256Verifier(key, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-shared-secret"), fields) assert.NoError(t, err, "could not generate Verifier") err = VerifyRequest(signatureName, *verifier, req2) assert.NoError(t, err, "verification error") @@ -162,7 +162,7 @@ func TestTrailer_SigFields(t *testing.T) { signedMessage = strings.Replace(signedMessage, "Trailer: Expires, Hdr", "Trailer: Expires, Hdr, Signature, Signature-Input", 1) req2 = readRequestChunked(signedMessage) - verifier, err = NewHMACSHA256Verifier("test-shared-secret", key, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err = NewHMACSHA256Verifier(key, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-shared-secret"), fields) assert.NoError(t, err, "could not generate Verifier") err = VerifyRequest(signatureName, *verifier, req2) assert.Error(t, err, "verification error") @@ -172,7 +172,7 @@ func TestTrailer_SigFields(t *testing.T) { signedMessage = strings.Replace(signedMessage, "Trailer: Expires, Hdr", "Trailer: Expires, Hdr, Signature, Signature-Input", 1) req2 = readRequestChunked(signedMessage) - verifier, err = NewHMACSHA256Verifier("test-shared-secret", key, NewVerifyConfig().SetVerifyCreated(false), fields) + verifier, err = NewHMACSHA256Verifier(key, NewVerifyConfig().SetVerifyCreated(false).SetKeyID("test-shared-secret"), fields) assert.NoError(t, err, "could not generate Verifier") err = VerifyRequest(signatureName, *verifier, req2) assert.Error(t, err, "verification error")