From eb65999a6c12c16b473fd202ba798783565ce7c4 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 17 Mar 2026 05:50:20 -0600 Subject: [PATCH] refactor: rename PublicKey.Key to Pub, PrivateKey.privKey to Priv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PublicKey.Key → PublicKey.Pub (CryptoPublicKey) - PrivateKey.privKey → PrivateKey.Priv (crypto.Signer, now public) - Update all internal usages in jwk.go, sign.go, verify.go - Update all test usages in jwt_test.go, coverage_test.go, edge_test.go - Update interop tests (round-trip-go-jose, round-trip-go-jwt, nuance) - Update SKILL.md documentation Breaking change: PublicKey.Key renamed to PublicKey.Pub --- auth/jwt/SKILL.md | 4 +- auth/jwt/cmd/jwt/main.go | 2 +- auth/jwt/coverage_test.go | 26 ++++----- auth/jwt/edge_test.go | 4 +- auth/jwt/jwk.go | 46 +++++++-------- auth/jwt/jwt_test.go | 58 +++++++++---------- auth/jwt/keyfile/keyfile_test.go | 2 +- auth/jwt/sign.go | 22 +++---- .../round-trip-go-jwt/round_trip_test.go | 42 +++++++------- auth/jwt/tests/testkeys/testkeys.go | 6 +- auth/jwt/verify.go | 6 +- 11 files changed, 110 insertions(+), 108 deletions(-) diff --git a/auth/jwt/SKILL.md b/auth/jwt/SKILL.md index 814d4d1..8a84e7e 100644 --- a/auth/jwt/SKILL.md +++ b/auth/jwt/SKILL.md @@ -136,8 +136,10 @@ Constants: `DefaultTokenTyp = "JWT"`, `AccessTokenTyp = "at+jwt"` (RFC 9068). ## Key types - `NewPrivateKey()` -- generates Ed25519 (default, recommended) -- `PrivateKey` / `PublicKey` -- type-safe wrappers, marshal as JWK +- `PrivateKey` -- holds `crypto.Signer` in `.Priv`, JWK metadata (KID, Use, Alg, KeyOps) +- `PublicKey` -- holds `crypto.PublicKey` in `.Pub`, JWK metadata (KID, Use, Alg, KeyOps) - Algorithm derived from key type automatically (EdDSA, ES256, ES384, ES512, RS256) +- Type-switch on `.Pub` to access raw key: `*ecdsa.PublicKey`, `*rsa.PublicKey`, `ed25519.PublicKey` ## CLI tool (cmd/jwt) diff --git a/auth/jwt/cmd/jwt/main.go b/auth/jwt/cmd/jwt/main.go index fc73fa6..e68be7a 100644 --- a/auth/jwt/cmd/jwt/main.go +++ b/auth/jwt/cmd/jwt/main.go @@ -793,7 +793,7 @@ func loadPublicKeys(source string) ([]jwt.PublicKey, error) { // Try as single public key JWK. var pk jwt.PublicKey - if err := json.Unmarshal(data, &pk); err == nil && pk.Key != nil { + if err := json.Unmarshal(data, &pk); err == nil && pk.Pub != nil { return []jwt.PublicKey{pk}, nil } diff --git a/auth/jwt/coverage_test.go b/auth/jwt/coverage_test.go index a5f60d8..9f93768 100644 --- a/auth/jwt/coverage_test.go +++ b/auth/jwt/coverage_test.go @@ -808,7 +808,7 @@ func TestCov_KeyType(t *testing.T) { {fakeKey{}, ""}, } for _, tt := range tests { - pk := PublicKey{Key: tt.key} + pk := PublicKey{Pub: tt.key} if got := pk.KeyType(); got != tt.expect { t.Errorf("KeyType(%T)=%q want %q", tt.key, got, tt.expect) } @@ -934,7 +934,7 @@ func TestCov_Thumbprint(t *testing.T) { }) } t.Run("unsupported", func(t *testing.T) { - pk := PublicKey{Key: fakeKey{}} + pk := PublicKey{Pub: fakeKey{}} _, err := pk.Thumbprint() if !errors.Is(err, ErrUnsupportedKeyType) { t.Fatalf("expected ErrUnsupportedKeyType, got %v", err) @@ -967,7 +967,7 @@ func TestCov_PrivateKey_PublicKey(t *testing.T) { }) t.Run("bad_signer", func(t *testing.T) { // signer whose Public() returns a non-CryptoPublicKey - pk := &PrivateKey{privKey: fakeSigner{pub: "not a key"}} + pk := &PrivateKey{Priv: fakeSigner{pub: "not a key"}} _, err := pk.PublicKey() if !errors.Is(err, ErrSanityFail) { t.Fatalf("expected ErrSanityFail, got %v", err) @@ -984,8 +984,8 @@ func TestCov_NewPrivateKey(t *testing.T) { t.Fatal("expected auto KID") } // Should be Ed25519 - if _, ok := pk.privKey.(ed25519.PrivateKey); !ok { - t.Fatalf("expected Ed25519, got %T", pk.privKey) + if _, ok := pk.Priv.(ed25519.PrivateKey); !ok { + t.Fatalf("expected Ed25519, got %T", pk.Priv) } } @@ -1298,7 +1298,7 @@ func TestCov_toPublicKeyOps(t *testing.T) { } func TestCov_encode_Unsupported(t *testing.T) { - _, err := encode(PublicKey{Key: fakeKey{}}) + _, err := encode(PublicKey{Pub: fakeKey{}}) if !errors.Is(err, ErrUnsupportedKeyType) { t.Fatalf("expected ErrUnsupportedKeyType, got %v", err) } @@ -1308,8 +1308,8 @@ func TestCov_encodePrivate_Unsupported(t *testing.T) { // Signer whose Public() returns a real ed25519 key but signer type is custom edKey := mustEdKey(t) pk := PrivateKey{ - privKey: fakeSigner{pub: edKey.Public()}, - KID: "test", + Priv: fakeSigner{pub: edKey.Public()}, + KID: "test", } _, err := encodePrivate(pk) if !errors.Is(err, ErrUnsupportedKeyType) { @@ -1320,7 +1320,7 @@ func TestCov_encodePrivate_Unsupported(t *testing.T) { func TestCov_encodePrivate_RSA_NoPrimes(t *testing.T) { rsaKey := mustRSAKey(t) rsaKey.Primes = nil // remove primes - pk := PrivateKey{privKey: rsaKey, KID: "test"} + pk := PrivateKey{Priv: rsaKey, KID: "test"} rk, err := encodePrivate(pk) if err != nil { t.Fatal(err) @@ -2694,7 +2694,7 @@ func TestCov_PublicKey_MarshalJSON(t *testing.T) { } // Error path: unsupported key - bad := PublicKey{Key: fakeKey{}} + bad := PublicKey{Pub: fakeKey{}} _, err = json.Marshal(bad) if err == nil { t.Fatal("expected error for unsupported key") @@ -2851,7 +2851,7 @@ func TestCov_decodeOne_RSA(t *testing.T) { if err != nil { t.Fatal(err) } - if pk.Key == nil { + if pk.Pub == nil { t.Fatal("expected key") } } @@ -2873,7 +2873,7 @@ func TestCov_decodePrivate_RSA(t *testing.T) { if err != nil { t.Fatal(err) } - if priv.privKey == nil { + if priv.Priv == nil { t.Fatal("expected private key") } } @@ -2888,7 +2888,7 @@ func TestCov_decodePrivate_EC(t *testing.T) { if err != nil { t.Fatal(err) } - if priv.privKey == nil { + if priv.Priv == nil { t.Fatal("expected private key") } } diff --git a/auth/jwt/edge_test.go b/auth/jwt/edge_test.go index 7565c54..1dbe1a0 100644 --- a/auth/jwt/edge_test.go +++ b/auth/jwt/edge_test.go @@ -47,7 +47,7 @@ func TestPrivateKeyMissingD(t *testing.T) { if err != nil { t.Fatal(err) } - pub := jwt.PublicKey{Key: &ecKey.PublicKey, KID: "test"} + pub := jwt.PublicKey{Pub: &ecKey.PublicKey, KID: "test"} pubJSON, err := json.Marshal(pub) if err != nil { t.Fatal(err) @@ -439,7 +439,7 @@ func TestVerifyWrongKeyTypeForAlg(t *testing.T) { t.Fatal(err) } rsaPub := jwt.PublicKey{ - Key: &rsaKey.PublicKey, + Pub: &rsaKey.PublicKey, KID: edKey.KID, // same KID } diff --git a/auth/jwt/jwk.go b/auth/jwt/jwk.go index a2a82fc..93c2bde 100644 --- a/auth/jwt/jwk.go +++ b/auth/jwt/jwk.go @@ -33,9 +33,9 @@ type CryptoPublicKey interface { // // PublicKey is the in-memory representation of a JWK. // [PublicKey.KeyType] returns the JWK kty string ("EC", "RSA", or "OKP"). -// To access the raw Go key, type-switch on Key: +// To access the raw Go key, type-switch on Pub: // -// switch key := pk.Key.(type) { +// switch key := pk.Pub.(type) { // case *ecdsa.PublicKey: // ... // case *rsa.PublicKey: // ... // case ed25519.PublicKey: // ... @@ -44,7 +44,7 @@ type CryptoPublicKey interface { // For signing keys, use [PrivateKey] instead - it holds the [crypto.Signer] // and derives a PublicKey on demand. type PublicKey struct { - Key CryptoPublicKey + Pub CryptoPublicKey KID string Use string Alg string @@ -54,9 +54,9 @@ type PublicKey struct { // KeyType returns the JWK "kty" string for the key: "EC", "RSA", or "OKP". // Returns "" if the key type is unrecognized. // -// To access the underlying Go key, use a type switch on Key: +// To access the underlying Go key, use a type switch on Pub: // -// switch key := k.Key.(type) { +// switch key := k.Pub.(type) { // case *ecdsa.PublicKey: // kty "EC" // // key is *ecdsa.PublicKey // case *rsa.PublicKey: // kty "RSA" @@ -67,7 +67,7 @@ type PublicKey struct { // // unrecognized key type // } func (k PublicKey) KeyType() string { - switch k.Key.(type) { + switch k.Pub.(type) { case *ecdsa.PublicKey: return "EC" case *rsa.PublicKey: @@ -163,11 +163,11 @@ func (k PublicKey) Thumbprint() (string, error) { // // Use [FromPrivateKey] to construct. type PrivateKey struct { - privKey crypto.Signer - KID string - Use string - Alg string - KeyOps []string + Priv crypto.Signer + KID string + Use string + Alg string + KeyOps []string } // PublicKey derives the [PublicKey] for this signing key. @@ -179,12 +179,12 @@ type PrivateKey struct { // known CryptoPublicKey type - this should never happen for keys created // through this library. func (k *PrivateKey) PublicKey() (*PublicKey, error) { - pub, ok := k.privKey.Public().(CryptoPublicKey) + pub, ok := k.Priv.Public().(CryptoPublicKey) if !ok { - return nil, fmt.Errorf("%w: private key type %T did not produce a known public key type", ErrSanityFail, k.privKey) + return nil, fmt.Errorf("%w: private key type %T did not produce a known public key type", ErrSanityFail, k.Priv) } return &PublicKey{ - Key: pub, + Pub: pub, KID: k.KID, Use: k.Use, Alg: k.Alg, @@ -232,7 +232,7 @@ func NewPrivateKey() (*PrivateKey, error) { if err != nil { return nil, fmt.Errorf("NewPrivateKey: generate Ed25519 key: %w", err) } - pk := &PrivateKey{privKey: priv} + pk := &PrivateKey{Priv: priv} pub, err := pk.PublicKey() if err != nil { return nil, fmt.Errorf("NewPrivateKey: derive public key: %w", err) @@ -307,7 +307,7 @@ type WellKnownJWKs struct { func encode(k PublicKey) (rawKey, error) { rk := rawKey{KID: k.KID, Use: k.Use, Alg: k.Alg, KeyOps: k.KeyOps} - switch key := k.Key.(type) { + switch key := k.Pub.(type) { case *ecdsa.PublicKey: ci, err := ecInfo(key.Curve) if err != nil { @@ -337,7 +337,7 @@ func encode(k PublicKey) (rawKey, error) { return rk, nil default: - return rawKey{}, fmt.Errorf("%T: %w", k.Key, ErrUnsupportedKeyType) + return rawKey{}, fmt.Errorf("%T: %w", k.Pub, ErrUnsupportedKeyType) } } @@ -354,7 +354,7 @@ func encodePrivate(k PrivateKey) (rawKey, error) { return rawKey{}, err } - switch priv := k.privKey.(type) { + switch priv := k.Priv.(type) { case *ecdsa.PrivateKey: dBytes, err := priv.Bytes() if err != nil { @@ -379,7 +379,7 @@ func encodePrivate(k PrivateKey) (rawKey, error) { rk.D = base64.RawURLEncoding.EncodeToString(priv.Seed()) default: - return rawKey{}, fmt.Errorf("%T: %w", k.privKey, ErrUnsupportedKeyType) + return rawKey{}, fmt.Errorf("%T: %w", k.Priv, ErrUnsupportedKeyType) } return rk, nil @@ -396,7 +396,7 @@ func FromPublicKey(pub crypto.PublicKey) (*PublicKey, error) { return nil, fmt.Errorf("%T: %w", pub, ErrUnsupportedKeyType) } - pk := &PublicKey{Key: cpk} + pk := &PublicKey{Pub: cpk} // Derive Alg from key type. switch key := pub.(type) { @@ -435,7 +435,7 @@ func FromPrivateKey(signer crypto.Signer, kid string) (*PrivateKey, error) { if err != nil { return nil, err } - return &PrivateKey{privKey: signer, KID: kid, Alg: alg}, nil + return &PrivateKey{Priv: signer, KID: kid, Alg: alg}, nil } // decodeOne parses a single rawKey wire struct into a [PublicKey]. @@ -577,13 +577,13 @@ func decodePrivate(kj rawKey) (*PrivateKey, error) { // newPublicKey creates a [PublicKey] from a crypto key, copying metadata // (KID, Use, Alg, KeyOps) from the rawKey. func (kj rawKey) newPublicKey(key CryptoPublicKey) *PublicKey { - return &PublicKey{Key: key, KID: kj.KID, Use: kj.Use, Alg: kj.Alg, KeyOps: kj.KeyOps} + return &PublicKey{Pub: key, KID: kj.KID, Use: kj.Use, Alg: kj.Alg, KeyOps: kj.KeyOps} } // newPrivateKey creates a [PrivateKey] from a crypto.Signer, copying metadata // (KID, Use, Alg, KeyOps) from the rawKey. func (kj rawKey) newPrivateKey(signer crypto.Signer) *PrivateKey { - return &PrivateKey{privKey: signer, KID: kj.KID, Use: kj.Use, Alg: kj.Alg, KeyOps: kj.KeyOps} + return &PrivateKey{Priv: signer, KID: kj.KID, Use: kj.Use, Alg: kj.Alg, KeyOps: kj.KeyOps} } // decodeB64Field decodes a base64url-encoded JWK field value, returning a diff --git a/auth/jwt/jwt_test.go b/auth/jwt/jwt_test.go index 199a8cf..9d8a8d1 100644 --- a/auth/jwt/jwt_test.go +++ b/auth/jwt/jwt_test.go @@ -125,7 +125,7 @@ func TestRoundTrip(t *testing.T) { t.Fatalf("Encode failed: %v", err) } - iss := goodVerifier(jwt.PublicKey{Key: &privKey.PublicKey, KID: "key-1"}) + iss := goodVerifier(jwt.PublicKey{Pub: &privKey.PublicKey, KID: "key-1"}) jws2, err := iss.VerifyJWT(token) if err != nil { @@ -174,7 +174,7 @@ func TestRoundTripRS256(t *testing.T) { t.Fatalf("Encode failed: %v", err) } - iss := goodVerifier(jwt.PublicKey{Key: &privKey.PublicKey, KID: "key-1"}) + iss := goodVerifier(jwt.PublicKey{Pub: &privKey.PublicKey, KID: "key-1"}) jws2, err := iss.VerifyJWT(token) if err != nil { @@ -215,7 +215,7 @@ func TestRoundTripEdDSA(t *testing.T) { t.Fatalf("Encode failed: %v", err) } - iss := goodVerifier(jwt.PublicKey{Key: pubKeyBytes, KID: "key-1"}) + iss := goodVerifier(jwt.PublicKey{Pub: pubKeyBytes, KID: "key-1"}) jws2, err := iss.VerifyJWT(token) if err != nil { @@ -256,7 +256,7 @@ func TestRoundTripES384(t *testing.T) { t.Fatalf("Encode failed: %v", err) } - iss := goodVerifier(jwt.PublicKey{Key: &privKey.PublicKey, KID: "key-1"}) + iss := goodVerifier(jwt.PublicKey{Pub: &privKey.PublicKey, KID: "key-1"}) jws2, err := iss.VerifyJWT(token) if err != nil { @@ -297,7 +297,7 @@ func TestRoundTripES512(t *testing.T) { t.Fatalf("Encode failed: %v", err) } - iss := goodVerifier(jwt.PublicKey{Key: &privKey.PublicKey, KID: "key-1"}) + iss := goodVerifier(jwt.PublicKey{Pub: &privKey.PublicKey, KID: "key-1"}) jws2, err := iss.VerifyJWT(token) if err != nil { @@ -321,7 +321,7 @@ func TestDecodeVerifyFlow(t *testing.T) { claims := goodClaims() token, _ := signer.SignToString(&claims) - iss, _ := jwt.NewVerifier([]jwt.PublicKey{{Key: &privKey.PublicKey, KID: "k"}}) + iss, _ := jwt.NewVerifier([]jwt.PublicKey{{Pub: &privKey.PublicKey, KID: "k"}}) jws2, err := jwt.Decode(token) if err != nil { @@ -353,7 +353,7 @@ func TestDecodeReturnsParsedOnSigFailure(t *testing.T) { token, _ := signer.SignToString(&claims) // Verifier has wrong public key - sig verification will fail. - iss, _ := jwt.NewVerifier([]jwt.PublicKey{{Key: &wrongKey.PublicKey, KID: "k"}}) + iss, _ := jwt.NewVerifier([]jwt.PublicKey{{Pub: &wrongKey.PublicKey, KID: "k"}}) // Decode always succeeds for well-formed tokens. result, err := jwt.Decode(token) @@ -384,7 +384,7 @@ func TestCustomValidation(t *testing.T) { claims.Email = "" token, _ := signer.SignToString(&claims) - iss := goodVerifier(jwt.PublicKey{Key: &privKey.PublicKey, KID: "k"}) + iss := goodVerifier(jwt.PublicKey{Pub: &privKey.PublicKey, KID: "k"}) jws2, err := jwt.Decode(token) if err != nil { t.Fatalf("Decode failed: %v", err) @@ -457,7 +457,7 @@ func TestVerifyWithoutValidation(t *testing.T) { c := goodClaims() token, _ := signer.SignToString(&c) - iss, _ := jwt.NewVerifier([]jwt.PublicKey{{Key: &privKey.PublicKey, KID: "k"}}) + iss, _ := jwt.NewVerifier([]jwt.PublicKey{{Pub: &privKey.PublicKey, KID: "k"}}) jws2, err := iss.VerifyJWT(token) if err != nil { @@ -481,7 +481,7 @@ func TestVerifierWrongKey(t *testing.T) { claims := goodClaims() token, _ := signer.SignToString(&claims) - iss := goodVerifier(jwt.PublicKey{Key: &wrongKey.PublicKey, KID: "k"}) + iss := goodVerifier(jwt.PublicKey{Pub: &wrongKey.PublicKey, KID: "k"}) parsed, err := jwt.Decode(token) if err != nil { @@ -500,7 +500,7 @@ func TestVerifierUnknownKid(t *testing.T) { claims := goodClaims() token, _ := signer.SignToString(&claims) - iss := goodVerifier(jwt.PublicKey{Key: &privKey.PublicKey, KID: "known-kid"}) + iss := goodVerifier(jwt.PublicKey{Pub: &privKey.PublicKey, KID: "known-kid"}) parsed, err := jwt.Decode(token) if err != nil { @@ -522,7 +522,7 @@ func TestVerifierIssMismatch(t *testing.T) { claims.Iss = "https://evil.example.com" token, _ := signer.SignToString(&claims) - iss := goodVerifier(jwt.PublicKey{Key: &privKey.PublicKey, KID: "k"}) + iss := goodVerifier(jwt.PublicKey{Pub: &privKey.PublicKey, KID: "k"}) // Decode+Verify succeeds - iss is not checked at the Verifier level. parsed, err := jwt.Decode(token) @@ -561,7 +561,7 @@ func TestVerifyTamperedAlg(t *testing.T) { claims := goodClaims() token, _ := signer.SignToString(&claims) - iss := goodVerifier(jwt.PublicKey{Key: &privKey.PublicKey, KID: "k"}) + iss := goodVerifier(jwt.PublicKey{Pub: &privKey.PublicKey, KID: "k"}) // Replace the protected header with one that has alg:"none". // The original ES256 signature stays - the signing input will mismatch. @@ -818,9 +818,9 @@ func TestKeyType(t *testing.T) { key jwt.PublicKey wantKty string }{ - {"EC P-256", jwt.PublicKey{Key: &ecKey.PublicKey}, "EC"}, - {"RSA 2048", jwt.PublicKey{Key: &rsaKey.PublicKey}, "RSA"}, - {"Ed25519", jwt.PublicKey{Key: edPub}, "OKP"}, + {"EC P-256", jwt.PublicKey{Pub: &ecKey.PublicKey}, "EC"}, + {"RSA 2048", jwt.PublicKey{Pub: &rsaKey.PublicKey}, "RSA"}, + {"Ed25519", jwt.PublicKey{Pub: edPub}, "OKP"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -927,9 +927,9 @@ func TestThumbprint(t *testing.T) { name string pub jwt.PublicKey }{ - {"EC P-256", jwt.PublicKey{Key: &ecKey.PublicKey}}, - {"RSA 2048", jwt.PublicKey{Key: &rsaKey.PublicKey}}, - {"Ed25519", jwt.PublicKey{Key: edPub}}, + {"EC P-256", jwt.PublicKey{Pub: &ecKey.PublicKey}}, + {"RSA 2048", jwt.PublicKey{Pub: &rsaKey.PublicKey}}, + {"Ed25519", jwt.PublicKey{Pub: edPub}}, } for _, tt := range tests { @@ -2108,8 +2108,8 @@ func TestDuplicateKIDRotation(t *testing.T) { // Verifier has both keys under the same KID. verifier, err := jwt.NewVerifier([]jwt.PublicKey{ - {Key: &oldKey.PublicKey, KID: sharedKID}, - {Key: &newKey.PublicKey, KID: sharedKID}, + {Pub: &oldKey.PublicKey, KID: sharedKID}, + {Pub: &newKey.PublicKey, KID: sharedKID}, }) if err != nil { t.Fatal(err) @@ -2156,8 +2156,8 @@ func TestNoKIDTriesAllKeys(t *testing.T) { // Verifier has wrongKey first, then rightKey. verifier, err := jwt.NewVerifier([]jwt.PublicKey{ - {Key: &wrongKey.PublicKey, KID: "wrong"}, - {Key: &rightKey.PublicKey, KID: "right"}, + {Pub: &wrongKey.PublicKey, KID: "wrong"}, + {Pub: &rightKey.PublicKey, KID: "right"}, }) if err != nil { t.Fatal(err) @@ -2191,7 +2191,7 @@ func TestEmptyKIDTokenEmptyKIDKey(t *testing.T) { // Verifier key also has empty KID. verifier, err := jwt.NewVerifier([]jwt.PublicKey{ - {Key: &rightKey.PublicKey, KID: ""}, + {Pub: &rightKey.PublicKey, KID: ""}, }) if err != nil { t.Fatal(err) @@ -2218,7 +2218,7 @@ func TestKIDTokenEmptyKIDKey(t *testing.T) { // Verifier has the same key material but with an empty KID. verifier, err := jwt.NewVerifier([]jwt.PublicKey{ - {Key: &rightKey.PublicKey, KID: ""}, + {Pub: &rightKey.PublicKey, KID: ""}, }) if err != nil { t.Fatal(err) @@ -2248,9 +2248,9 @@ func TestMultiKeyVerifier(t *testing.T) { // Create a verifier with all three public keys. verifier, err := jwt.NewVerifier([]jwt.PublicKey{ - {Key: &ecKey.PublicKey, KID: "ec-key"}, - {Key: &rsaKey.PublicKey, KID: "rsa-key"}, - {Key: edPub, KID: "ed-key"}, + {Pub: &ecKey.PublicKey, KID: "ec-key"}, + {Pub: &rsaKey.PublicKey, KID: "rsa-key"}, + {Pub: edPub, KID: "ed-key"}, }) if err != nil { t.Fatal(err) @@ -2372,7 +2372,7 @@ func TestVerifyTamperedPayload(t *testing.T) { claims := goodClaims() token, _ := signer.SignToString(&claims) - verifier := goodVerifier(jwt.PublicKey{Key: &privKey.PublicKey, KID: "k"}) + verifier := goodVerifier(jwt.PublicKey{Pub: &privKey.PublicKey, KID: "k"}) // Tamper with the payload: change the sub claim. parts := strings.SplitN(token, ".", 3) diff --git a/auth/jwt/keyfile/keyfile_test.go b/auth/jwt/keyfile/keyfile_test.go index 1d46a56..23a951b 100644 --- a/auth/jwt/keyfile/keyfile_test.go +++ b/auth/jwt/keyfile/keyfile_test.go @@ -228,7 +228,7 @@ func TestParsePublicJWK(t *testing.T) { if pk.KID == "" { t.Error("KID should be set") } - if pk.Key == nil { + if pk.Pub == nil { t.Error("Key should be set") } } diff --git a/auth/jwt/sign.go b/auth/jwt/sign.go index 7cd8d9b..6d8c136 100644 --- a/auth/jwt/sign.go +++ b/auth/jwt/sign.go @@ -63,13 +63,13 @@ func NewSigner(keys []*PrivateKey, retiredKeys ...PublicKey) (*Signer, error) { // Copy so the caller can't mutate after construction. ss := make([]PrivateKey, len(keys)) for i, k := range keys { - if k == nil || k.privKey == nil { + if k == nil || k.Priv == nil { return nil, fmt.Errorf("NewSigner: key[%d]: %w", i, ErrNoSigningKey) } ss[i] = *k // Derive algorithm from key type; validate caller's Alg if already set. - alg, _, _, err := signingParams(ss[i].privKey) + alg, _, _, err := signingParams(ss[i].Priv) if err != nil { return nil, fmt.Errorf("NewSigner: key[%d]: %w", i, err) } @@ -170,11 +170,11 @@ func (s *Signer) SignJWT(jws SignableJWT) error { pk = s.nextKey() hdr.KID = pk.KID } - if pk.privKey == nil { + if pk.Priv == nil { return fmt.Errorf("kid %q: %w", pk.KID, ErrNoSigningKey) } - alg, hash, ecKeySize, err := signingParams(pk.privKey) + alg, hash, ecKeySize, err := signingParams(pk.Priv) if err != nil { return err } @@ -191,7 +191,7 @@ func (s *Signer) SignJWT(jws SignableJWT) error { input := signingInputBytes(jws.GetProtected(), jws.GetPayload()) - sig, err := signBytes(pk.privKey, alg, hash, ecKeySize, input) + sig, err := signBytes(pk.Priv, alg, hash, ecKeySize, input) if err != nil { return err } @@ -216,13 +216,13 @@ func (s *Signer) SignJWT(jws SignableJWT) error { // produces an empty payload segment (used by ACME POST-as-GET). func (s *Signer) SignRaw(hdr Header, payload []byte) (*RawJWT, error) { pk := s.nextKey() - if pk.privKey == nil { + if pk.Priv == nil { return nil, fmt.Errorf("kid %q: %w", pk.KID, ErrNoSigningKey) } rfc := hdr.GetRFCHeader() - alg, hash, ecKeySize, err := signingParams(pk.privKey) + alg, hash, ecKeySize, err := signingParams(pk.Priv) if err != nil { return nil, err } @@ -241,7 +241,7 @@ func (s *Signer) SignRaw(hdr Header, payload []byte) (*RawJWT, error) { input := signingInputBytes([]byte(protectedB64), []byte(payloadB64)) - sig, err := signBytes(pk.privKey, alg, hash, ecKeySize, input) + sig, err := signBytes(pk.Priv, alg, hash, ecKeySize, input) if err != nil { return nil, err } @@ -330,21 +330,21 @@ func signBytes(signer crypto.Signer, alg string, hash crypto.Hash, ecKeySize int // validateSigningKey performs a test sign+verify round-trip to catch bad // keys at construction time rather than on first use. func validateSigningKey(pk *PrivateKey, pub *PublicKey) error { - alg, hash, ecKeySize, err := signingParams(pk.privKey) + alg, hash, ecKeySize, err := signingParams(pk.Priv) if err != nil { return err } testInput := []byte("jwt-key-validation") - sig, err := signBytes(pk.privKey, alg, hash, ecKeySize, testInput) + sig, err := signBytes(pk.Priv, alg, hash, ecKeySize, testInput) if err != nil { return fmt.Errorf("test sign: %w", err) } // Verify against the public key. h := RFCHeader{Alg: alg, KID: pk.KID} - if err := verifyOneKey(h, pub.Key, testInput, sig); err != nil { + if err := verifyOneKey(h, pub.Pub, testInput, sig); err != nil { return fmt.Errorf("test verify: %w", err) } return nil diff --git a/auth/jwt/tests/round-trip-go-jwt/round_trip_test.go b/auth/jwt/tests/round-trip-go-jwt/round_trip_test.go index 237d859..83c4ca8 100644 --- a/auth/jwt/tests/round-trip-go-jwt/round_trip_test.go +++ b/auth/jwt/tests/round-trip-go-jwt/round_trip_test.go @@ -264,7 +264,7 @@ func TestTheirSignOurVerify_EdDSA(t *testing.T) { pub := priv.Public().(ed25519.PublicKey) assertTheirSignOurVerify(t, gjwt.SigningMethodEdDSA, priv, "k1", - jwt.PublicKey{Key: pub, KID: "k1"}, "user-eddsa") + jwt.PublicKey{Pub: pub, KID: "k1"}, "user-eddsa") } func TestTheirSignOurVerify_ES256(t *testing.T) { @@ -274,7 +274,7 @@ func TestTheirSignOurVerify_ES256(t *testing.T) { } assertTheirSignOurVerify(t, gjwt.SigningMethodES256, priv, "k1", - jwt.PublicKey{Key: &priv.PublicKey, KID: "k1"}, "user-es256") + jwt.PublicKey{Pub: &priv.PublicKey, KID: "k1"}, "user-es256") } func TestTheirSignOurVerify_ES384(t *testing.T) { @@ -284,7 +284,7 @@ func TestTheirSignOurVerify_ES384(t *testing.T) { } assertTheirSignOurVerify(t, gjwt.SigningMethodES384, priv, "k1", - jwt.PublicKey{Key: &priv.PublicKey, KID: "k1"}, "user-es384") + jwt.PublicKey{Pub: &priv.PublicKey, KID: "k1"}, "user-es384") } func TestTheirSignOurVerify_ES512(t *testing.T) { @@ -294,7 +294,7 @@ func TestTheirSignOurVerify_ES512(t *testing.T) { } assertTheirSignOurVerify(t, gjwt.SigningMethodES512, priv, "k1", - jwt.PublicKey{Key: &priv.PublicKey, KID: "k1"}, "user-es512") + jwt.PublicKey{Pub: &priv.PublicKey, KID: "k1"}, "user-es512") } func TestTheirSignOurVerify_RS256(t *testing.T) { @@ -304,7 +304,7 @@ func TestTheirSignOurVerify_RS256(t *testing.T) { } assertTheirSignOurVerify(t, gjwt.SigningMethodRS256, priv, "k1", - jwt.PublicKey{Key: &priv.PublicKey, KID: "k1"}, "user-rs256") + jwt.PublicKey{Pub: &priv.PublicKey, KID: "k1"}, "user-rs256") } // --- Known key tests --- @@ -323,7 +323,7 @@ func TestKnownKeys(t *testing.T) { pub := priv.Public().(ed25519.PublicKey) kid := "known-ed" pk := mustPK(t, priv, kid) - pubKey := jwt.PublicKey{Key: pub, KID: kid} + pubKey := jwt.PublicKey{Pub: pub, KID: kid} assertOurSignTheirVerify(t, pk, gjwt.SigningMethodEdDSA, pub, "known-ed-ours") assertTheirSignOurVerify(t, gjwt.SigningMethodEdDSA, priv, kid, pubKey, "known-ed-theirs") }) @@ -335,7 +335,7 @@ func TestKnownKeys(t *testing.T) { } kid := "known-es256" pk := mustPK(t, priv, kid) - pubKey := jwt.PublicKey{Key: &priv.PublicKey, KID: kid} + pubKey := jwt.PublicKey{Pub: &priv.PublicKey, KID: kid} assertOurSignTheirVerify(t, pk, gjwt.SigningMethodES256, &priv.PublicKey, "known-es256-ours") assertTheirSignOurVerify(t, gjwt.SigningMethodES256, priv, kid, pubKey, "known-es256-theirs") }) @@ -347,7 +347,7 @@ func TestKnownKeys(t *testing.T) { } kid := "known-es384" pk := mustPK(t, priv, kid) - pubKey := jwt.PublicKey{Key: &priv.PublicKey, KID: kid} + pubKey := jwt.PublicKey{Pub: &priv.PublicKey, KID: kid} assertOurSignTheirVerify(t, pk, gjwt.SigningMethodES384, &priv.PublicKey, "known-es384-ours") assertTheirSignOurVerify(t, gjwt.SigningMethodES384, priv, kid, pubKey, "known-es384-theirs") }) @@ -359,7 +359,7 @@ func TestKnownKeys(t *testing.T) { } kid := "known-es512" pk := mustPK(t, priv, kid) - pubKey := jwt.PublicKey{Key: &priv.PublicKey, KID: kid} + pubKey := jwt.PublicKey{Pub: &priv.PublicKey, KID: kid} assertOurSignTheirVerify(t, pk, gjwt.SigningMethodES512, &priv.PublicKey, "known-es512-ours") assertTheirSignOurVerify(t, gjwt.SigningMethodES512, priv, kid, pubKey, "known-es512-theirs") }) @@ -371,7 +371,7 @@ func TestKnownKeys(t *testing.T) { } kid := "known-rs256" pk := mustPK(t, priv, kid) - pubKey := jwt.PublicKey{Key: &priv.PublicKey, KID: kid} + pubKey := jwt.PublicKey{Pub: &priv.PublicKey, KID: kid} assertOurSignTheirVerify(t, pk, gjwt.SigningMethodRS256, &priv.PublicKey, "known-rs256-ours") assertTheirSignOurVerify(t, gjwt.SigningMethodRS256, priv, kid, pubKey, "known-rs256-theirs") }) @@ -399,7 +399,7 @@ func TestStress(t *testing.T) { kid := fmt.Sprintf("s%d", i) stressIteration(t, i, mustPK(t, priv, kid), - jwt.PublicKey{Key: pub, KID: kid}, + jwt.PublicKey{Pub: pub, KID: kid}, gjwt.SigningMethodEdDSA, priv, pub) } }) @@ -414,7 +414,7 @@ func TestStress(t *testing.T) { kid := fmt.Sprintf("s%d", i) stressIteration(t, i, mustPK(t, priv, kid), - jwt.PublicKey{Key: &priv.PublicKey, KID: kid}, + jwt.PublicKey{Pub: &priv.PublicKey, KID: kid}, gjwt.SigningMethodES256, priv, &priv.PublicKey) } }) @@ -429,7 +429,7 @@ func TestStress(t *testing.T) { kid := fmt.Sprintf("s%d", i) stressIteration(t, i, mustPK(t, priv, kid), - jwt.PublicKey{Key: &priv.PublicKey, KID: kid}, + jwt.PublicKey{Pub: &priv.PublicKey, KID: kid}, gjwt.SigningMethodES384, priv, &priv.PublicKey) } }) @@ -444,7 +444,7 @@ func TestStress(t *testing.T) { kid := fmt.Sprintf("s%d", i) stressIteration(t, i, mustPK(t, priv, kid), - jwt.PublicKey{Key: &priv.PublicKey, KID: kid}, + jwt.PublicKey{Pub: &priv.PublicKey, KID: kid}, gjwt.SigningMethodES512, priv, &priv.PublicKey) } }) @@ -463,7 +463,7 @@ func TestStress(t *testing.T) { kid := fmt.Sprintf("s%d", i) stressIteration(t, i, mustPK(t, priv, kid), - jwt.PublicKey{Key: &priv.PublicKey, KID: kid}, + jwt.PublicKey{Pub: &priv.PublicKey, KID: kid}, gjwt.SigningMethodRS256, priv, &priv.PublicKey) } }) @@ -486,7 +486,7 @@ func TestJWKPrivateKeyRoundTrip(t *testing.T) { t.Fatal(err) } assertPrivateKeyRoundTrip(t, original, - gjwt.SigningMethodEdDSA, pub.Key.(ed25519.PublicKey)) + gjwt.SigningMethodEdDSA, pub.Pub.(ed25519.PublicKey)) }) t.Run("EC_P256", func(t *testing.T) { @@ -606,7 +606,7 @@ func TestJWKPublicKeyRoundTrip(t *testing.T) { t.Fatal(err) } assertPublicKeyRoundTrip(t, - jwt.PublicKey{Key: pub, KID: "ed-pub-rt"}, + jwt.PublicKey{Pub: pub, KID: "ed-pub-rt"}, signer, pub) }) @@ -620,7 +620,7 @@ func TestJWKPublicKeyRoundTrip(t *testing.T) { t.Fatal(err) } assertPublicKeyRoundTrip(t, - jwt.PublicKey{Key: &priv.PublicKey, KID: "ec256-pub-rt"}, + jwt.PublicKey{Pub: &priv.PublicKey, KID: "ec256-pub-rt"}, signer, &priv.PublicKey) }) @@ -634,7 +634,7 @@ func TestJWKPublicKeyRoundTrip(t *testing.T) { t.Fatal(err) } assertPublicKeyRoundTrip(t, - jwt.PublicKey{Key: &priv.PublicKey, KID: "ec384-pub-rt"}, + jwt.PublicKey{Pub: &priv.PublicKey, KID: "ec384-pub-rt"}, signer, &priv.PublicKey) }) @@ -648,7 +648,7 @@ func TestJWKPublicKeyRoundTrip(t *testing.T) { t.Fatal(err) } assertPublicKeyRoundTrip(t, - jwt.PublicKey{Key: &priv.PublicKey, KID: "ec521-pub-rt"}, + jwt.PublicKey{Pub: &priv.PublicKey, KID: "ec521-pub-rt"}, signer, &priv.PublicKey) }) @@ -662,7 +662,7 @@ func TestJWKPublicKeyRoundTrip(t *testing.T) { t.Fatal(err) } assertPublicKeyRoundTrip(t, - jwt.PublicKey{Key: &priv.PublicKey, KID: "rsa-pub-rt"}, + jwt.PublicKey{Pub: &priv.PublicKey, KID: "rsa-pub-rt"}, signer, &priv.PublicKey) }) } diff --git a/auth/jwt/tests/testkeys/testkeys.go b/auth/jwt/tests/testkeys/testkeys.go index 0fe9526..8239908 100644 --- a/auth/jwt/tests/testkeys/testkeys.go +++ b/auth/jwt/tests/testkeys/testkeys.go @@ -98,7 +98,7 @@ func GenerateEdDSA(kid string) KeySet { pub := priv.Public().(ed25519.PublicKey) return KeySet{ PrivKey: mustPK(priv, kid), - PubKey: jwt.PublicKey{Key: pub, KID: kid}, + PubKey: jwt.PublicKey{Pub: pub, KID: kid}, RawPriv: priv, RawPub: pub, KID: kid, AlgName: "EdDSA", } @@ -120,7 +120,7 @@ func generateEC(kid string, curve elliptic.Curve, alg string) KeySet { } return KeySet{ PrivKey: mustPK(priv, kid), - PubKey: jwt.PublicKey{Key: &priv.PublicKey, KID: kid}, + PubKey: jwt.PublicKey{Pub: &priv.PublicKey, KID: kid}, RawPriv: priv, RawPub: &priv.PublicKey, KID: kid, AlgName: alg, } @@ -134,7 +134,7 @@ func GenerateRS256(kid string) KeySet { } return KeySet{ PrivKey: mustPK(priv, kid), - PubKey: jwt.PublicKey{Key: &priv.PublicKey, KID: kid}, + PubKey: jwt.PublicKey{Pub: &priv.PublicKey, KID: kid}, RawPriv: priv, RawPub: &priv.PublicKey, KID: kid, AlgName: "RS256", } diff --git a/auth/jwt/verify.go b/auth/jwt/verify.go index 99133dd..7342e0c 100644 --- a/auth/jwt/verify.go +++ b/auth/jwt/verify.go @@ -58,7 +58,7 @@ func NewVerifier(keys []PublicKey) (*Verifier, error) { entries := seen[k.KID] dup := false for _, e := range entries { - if e.key.Equal(k.Key) { + if e.key.Equal(k.Pub) { dup = true break } @@ -66,7 +66,7 @@ func NewVerifier(keys []PublicKey) (*Verifier, error) { if dup { continue // identical key material, skip } - seen[k.KID] = append(entries, seenEntry{key: k.Key, index: len(deduped)}) + seen[k.KID] = append(entries, seenEntry{key: k.Pub, index: len(deduped)}) deduped = append(deduped, k) } return &Verifier{ @@ -134,7 +134,7 @@ func (v *Verifier) Verify(jws VerifiableJWT) error { // for the token's algorithm) since it's more informative. var bestErr error for _, pk := range candidates { - err := verifyOneKey(h, pk.Key, signingInput, sig) + err := verifyOneKey(h, pk.Pub, signingInput, sig) if err == nil { return nil }