ref!(auth/jwt): rename PublicKey.Pub and PrivateKey.Priv

This commit is contained in:
AJ ONeal 2026-08-18 01:17:24 -06:00
parent 1d16cabf87
commit 82ac1e4721
No known key found for this signature in database
5 changed files with 51 additions and 51 deletions

View File

@ -808,7 +808,7 @@ func TestCov_KeyType(t *testing.T) {
{fakeKey{}, ""}, {fakeKey{}, ""},
} }
for _, tt := range tests { for _, tt := range tests {
pk := PublicKey{Key: tt.key} pk := PublicKey{Pub: tt.key}
if got := pk.KeyType(); got != tt.expect { if got := pk.KeyType(); got != tt.expect {
t.Errorf("KeyType(%T)=%q want %q", tt.key, 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) { t.Run("unsupported", func(t *testing.T) {
pk := PublicKey{Key: fakeKey{}} pk := PublicKey{Pub: fakeKey{}}
_, err := pk.Thumbprint() _, err := pk.Thumbprint()
if !errors.Is(err, ErrUnsupportedKeyType) { if !errors.Is(err, ErrUnsupportedKeyType) {
t.Fatalf("expected ErrUnsupportedKeyType, got %v", err) t.Fatalf("expected ErrUnsupportedKeyType, got %v", err)
@ -963,7 +963,7 @@ func TestCov_PrivateKey_PublicKey(t *testing.T) {
}) })
t.Run("bad_signer", func(t *testing.T) { t.Run("bad_signer", func(t *testing.T) {
// signer whose Public() returns a non-CryptoPublicKey // 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() _, err := pk.PublicKey()
if !errors.Is(err, ErrSanityFail) { if !errors.Is(err, ErrSanityFail) {
t.Fatalf("expected ErrSanityFail, got %v", err) t.Fatalf("expected ErrSanityFail, got %v", err)
@ -980,8 +980,8 @@ func TestCov_NewPrivateKey(t *testing.T) {
t.Fatal("expected auto KID") t.Fatal("expected auto KID")
} }
// Should be Ed25519 // Should be Ed25519
if _, ok := pk.privKey.(ed25519.PrivateKey); !ok { if _, ok := pk.Priv.(ed25519.PrivateKey); !ok {
t.Fatalf("expected Ed25519, got %T", pk.privKey) t.Fatalf("expected Ed25519, got %T", pk.Priv)
} }
} }
@ -1294,7 +1294,7 @@ func TestCov_toPublicKeyOps(t *testing.T) {
} }
func TestCov_encode_Unsupported(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) { if !errors.Is(err, ErrUnsupportedKeyType) {
t.Fatalf("expected ErrUnsupportedKeyType, got %v", err) t.Fatalf("expected ErrUnsupportedKeyType, got %v", err)
} }
@ -1304,7 +1304,7 @@ func TestCov_encodePrivate_Unsupported(t *testing.T) {
// Signer whose Public() returns a real ed25519 key but signer type is custom // Signer whose Public() returns a real ed25519 key but signer type is custom
edKey := mustEdKey(t) edKey := mustEdKey(t)
pk := PrivateKey{ pk := PrivateKey{
privKey: fakeSigner{pub: edKey.Public()}, Priv: fakeSigner{pub: edKey.Public()},
KID: "test", KID: "test",
} }
_, err := encodePrivate(pk) _, err := encodePrivate(pk)
@ -1316,7 +1316,7 @@ func TestCov_encodePrivate_Unsupported(t *testing.T) {
func TestCov_encodePrivate_RSA_NoPrimes(t *testing.T) { func TestCov_encodePrivate_RSA_NoPrimes(t *testing.T) {
rsaKey := mustRSAKey(t) rsaKey := mustRSAKey(t)
rsaKey.Primes = nil // remove primes rsaKey.Primes = nil // remove primes
pk := PrivateKey{privKey: rsaKey, KID: "test"} pk := PrivateKey{Priv: rsaKey, KID: "test"}
rk, err := encodePrivate(pk) rk, err := encodePrivate(pk)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -2690,7 +2690,7 @@ func TestCov_PublicKey_MarshalJSON(t *testing.T) {
} }
// Error path: unsupported key // Error path: unsupported key
bad := PublicKey{Key: fakeKey{}} bad := PublicKey{Pub: fakeKey{}}
_, err = json.Marshal(bad) _, err = json.Marshal(bad)
if err == nil { if err == nil {
t.Fatal("expected error for unsupported key") t.Fatal("expected error for unsupported key")
@ -2847,7 +2847,7 @@ func TestCov_decodeOne_RSA(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if pk.Key == nil { if pk.Pub == nil {
t.Fatal("expected key") t.Fatal("expected key")
} }
} }
@ -2869,7 +2869,7 @@ func TestCov_decodePrivate_RSA(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if priv.privKey == nil { if priv.Priv == nil {
t.Fatal("expected private key") t.Fatal("expected private key")
} }
} }
@ -2884,7 +2884,7 @@ func TestCov_decodePrivate_EC(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if priv.privKey == nil { if priv.Priv == nil {
t.Fatal("expected private key") t.Fatal("expected private key")
} }
} }

View File

@ -33,9 +33,9 @@ type CryptoPublicKey interface {
// //
// PublicKey is the in-memory representation of a JWK. // PublicKey is the in-memory representation of a JWK.
// [PublicKey.KeyType] returns the JWK kty string ("EC", "RSA", or "OKP"). // [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 *ecdsa.PublicKey: // ...
// case *rsa.PublicKey: // ... // case *rsa.PublicKey: // ...
// case ed25519.PublicKey: // ... // case ed25519.PublicKey: // ...
@ -44,7 +44,7 @@ type CryptoPublicKey interface {
// For signing keys, use [PrivateKey] instead - it holds the [crypto.Signer] // For signing keys, use [PrivateKey] instead - it holds the [crypto.Signer]
// and derives a PublicKey on demand. // and derives a PublicKey on demand.
type PublicKey struct { type PublicKey struct {
Key CryptoPublicKey Pub CryptoPublicKey
KID string KID string
Use string Use string
Alg string Alg string
@ -54,9 +54,9 @@ type PublicKey struct {
// KeyType returns the JWK "kty" string for the key: "EC", "RSA", or "OKP". // KeyType returns the JWK "kty" string for the key: "EC", "RSA", or "OKP".
// Returns "" if the key type is unrecognized. // 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" // case *ecdsa.PublicKey: // kty "EC"
// // key is *ecdsa.PublicKey // // key is *ecdsa.PublicKey
// case *rsa.PublicKey: // kty "RSA" // case *rsa.PublicKey: // kty "RSA"
@ -67,7 +67,7 @@ type PublicKey struct {
// // unrecognized key type // // unrecognized key type
// } // }
func (k PublicKey) KeyType() string { func (k PublicKey) KeyType() string {
switch k.Key.(type) { switch k.Pub.(type) {
case *ecdsa.PublicKey: case *ecdsa.PublicKey:
return "EC" return "EC"
case *rsa.PublicKey: case *rsa.PublicKey:
@ -163,7 +163,7 @@ func (k PublicKey) Thumbprint() (string, error) {
// //
// Use [FromPrivateKey] to construct. // Use [FromPrivateKey] to construct.
type PrivateKey struct { type PrivateKey struct {
privKey crypto.Signer Priv crypto.Signer
KID string KID string
Use string Use string
Alg string Alg string
@ -179,12 +179,12 @@ type PrivateKey struct {
// known CryptoPublicKey type - this should never happen for keys created // known CryptoPublicKey type - this should never happen for keys created
// through this library. // through this library.
func (k *PrivateKey) PublicKey() (*PublicKey, error) { func (k *PrivateKey) PublicKey() (*PublicKey, error) {
pub, ok := k.privKey.Public().(CryptoPublicKey) pub, ok := k.Priv.Public().(CryptoPublicKey)
if !ok { 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{ return &PublicKey{
Key: pub, Pub: pub,
KID: k.KID, KID: k.KID,
Use: k.Use, Use: k.Use,
Alg: k.Alg, Alg: k.Alg,
@ -242,7 +242,7 @@ func NewPrivateKey() (*PrivateKey, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("NewPrivateKey: generate Ed25519 key: %w", err) return nil, fmt.Errorf("NewPrivateKey: generate Ed25519 key: %w", err)
} }
pk := &PrivateKey{privKey: priv} pk := &PrivateKey{Priv: priv}
kid, err := pk.Thumbprint() kid, err := pk.Thumbprint()
if err != nil { if err != nil {
return nil, fmt.Errorf("NewPrivateKey: compute thumbprint: %w", err) return nil, fmt.Errorf("NewPrivateKey: compute thumbprint: %w", err)
@ -313,7 +313,7 @@ type WellKnownJWKs struct {
func encode(k PublicKey) (rawKey, error) { func encode(k PublicKey) (rawKey, error) {
rk := rawKey{KID: k.KID, Use: k.Use, Alg: k.Alg, KeyOps: k.KeyOps} 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: case *ecdsa.PublicKey:
ci, err := ecInfo(key.Curve) ci, err := ecInfo(key.Curve)
if err != nil { if err != nil {
@ -343,7 +343,7 @@ func encode(k PublicKey) (rawKey, error) {
return rk, nil return rk, nil
default: default:
return rawKey{}, fmt.Errorf("%T: %w", k.Key, ErrUnsupportedKeyType) return rawKey{}, fmt.Errorf("%T: %w", k.Pub, ErrUnsupportedKeyType)
} }
} }
@ -360,7 +360,7 @@ func encodePrivate(k PrivateKey) (rawKey, error) {
return rawKey{}, err return rawKey{}, err
} }
switch priv := k.privKey.(type) { switch priv := k.Priv.(type) {
case *ecdsa.PrivateKey: case *ecdsa.PrivateKey:
dBytes, err := priv.Bytes() dBytes, err := priv.Bytes()
if err != nil { if err != nil {
@ -385,7 +385,7 @@ func encodePrivate(k PrivateKey) (rawKey, error) {
rk.D = base64.RawURLEncoding.EncodeToString(priv.Seed()) rk.D = base64.RawURLEncoding.EncodeToString(priv.Seed())
default: default:
return rawKey{}, fmt.Errorf("%T: %w", k.privKey, ErrUnsupportedKeyType) return rawKey{}, fmt.Errorf("%T: %w", k.Priv, ErrUnsupportedKeyType)
} }
return rk, nil return rk, nil
@ -402,7 +402,7 @@ func FromPublicKey(pub crypto.PublicKey) (*PublicKey, error) {
return nil, fmt.Errorf("%T: %w", pub, ErrUnsupportedKeyType) return nil, fmt.Errorf("%T: %w", pub, ErrUnsupportedKeyType)
} }
pk := &PublicKey{Key: cpk} pk := &PublicKey{Pub: cpk}
// Derive Alg from key type. // Derive Alg from key type.
switch key := pub.(type) { switch key := pub.(type) {
@ -441,7 +441,7 @@ func FromPrivateKey(signer crypto.Signer, kid string) (*PrivateKey, error) {
if err != nil { if err != nil {
return nil, err 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]. // decodeOne parses a single rawKey wire struct into a [PublicKey].
@ -579,13 +579,13 @@ func decodePrivate(kj rawKey) (*PrivateKey, error) {
// newPublicKey creates a [PublicKey] from a crypto key, copying metadata // newPublicKey creates a [PublicKey] from a crypto key, copying metadata
// (KID, Use, Alg, KeyOps) from the rawKey. // (KID, Use, Alg, KeyOps) from the rawKey.
func (kj rawKey) newPublicKey(key CryptoPublicKey) *PublicKey { 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 // newPrivateKey creates a [PrivateKey] from a crypto.Signer, copying metadata
// (KID, Use, Alg, KeyOps) from the rawKey. // (KID, Use, Alg, KeyOps) from the rawKey.
func (kj rawKey) newPrivateKey(signer crypto.Signer) *PrivateKey { 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 // decodeB64Field decodes a base64url-encoded JWK field value, returning a

View File

@ -228,7 +228,7 @@ func TestParsePublicJWK(t *testing.T) {
if pk.KID == "" { if pk.KID == "" {
t.Error("KID should be set") t.Error("KID should be set")
} }
if pk.Key == nil { if pk.Pub == nil {
t.Error("Key should be set") t.Error("Key should be set")
} }
} }

View File

@ -65,13 +65,13 @@ func NewSigner(keys []*PrivateKey, retiredKeys ...PublicKey) (*Signer, error) {
// Copy so the caller can't mutate after construction. // Copy so the caller can't mutate after construction.
ss := make([]PrivateKey, len(keys)) ss := make([]PrivateKey, len(keys))
for i, k := range 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) return nil, fmt.Errorf("NewSigner: key[%d]: %w", i, ErrNoSigningKey)
} }
ss[i] = *k ss[i] = *k
// Derive algorithm from key type; validate caller's Alg if already set. // 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 { if err != nil {
return nil, fmt.Errorf("NewSigner: key[%d]: %w", i, err) return nil, fmt.Errorf("NewSigner: key[%d]: %w", i, err)
} }
@ -168,11 +168,11 @@ func (s *Signer) SignJWT(jws SignableJWT) error {
pk = s.nextKey() pk = s.nextKey()
hdr.KID = pk.KID hdr.KID = pk.KID
} }
if pk.privKey == nil { if pk.Priv == nil {
return fmt.Errorf("kid %q: %w", pk.KID, ErrNoSigningKey) 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 { if err != nil {
return err return err
} }
@ -189,7 +189,7 @@ func (s *Signer) SignJWT(jws SignableJWT) error {
input := signingInputBytes(jws.GetProtected(), jws.GetPayload()) 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 { if err != nil {
return err return err
} }
@ -214,13 +214,13 @@ func (s *Signer) SignJWT(jws SignableJWT) error {
// produces an empty payload segment (used by ACME POST-as-GET). // produces an empty payload segment (used by ACME POST-as-GET).
func (s *Signer) SignRaw(hdr Header, payload []byte) (*RawJWT, error) { func (s *Signer) SignRaw(hdr Header, payload []byte) (*RawJWT, error) {
pk := s.nextKey() pk := s.nextKey()
if pk.privKey == nil { if pk.Priv == nil {
return nil, fmt.Errorf("kid %q: %w", pk.KID, ErrNoSigningKey) return nil, fmt.Errorf("kid %q: %w", pk.KID, ErrNoSigningKey)
} }
rfc := hdr.GetRFCHeader() rfc := hdr.GetRFCHeader()
alg, hash, ecKeySize, err := signingParams(pk.privKey) alg, hash, ecKeySize, err := signingParams(pk.Priv)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -239,7 +239,7 @@ func (s *Signer) SignRaw(hdr Header, payload []byte) (*RawJWT, error) {
input := signingInputBytes([]byte(protectedB64), []byte(payloadB64)) 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 { if err != nil {
return nil, err return nil, err
} }
@ -328,21 +328,21 @@ func signBytes(signer crypto.Signer, alg string, hash crypto.Hash, ecKeySize int
// validateSigningKey performs a test sign+verify round-trip to catch bad // validateSigningKey performs a test sign+verify round-trip to catch bad
// keys at construction time rather than on first use. // keys at construction time rather than on first use.
func validateSigningKey(pk *PrivateKey, pub *PublicKey) error { func validateSigningKey(pk *PrivateKey, pub *PublicKey) error {
alg, hash, ecKeySize, err := signingParams(pk.privKey) alg, hash, ecKeySize, err := signingParams(pk.Priv)
if err != nil { if err != nil {
return err return err
} }
testInput := []byte("jwt-key-validation") 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 { if err != nil {
return fmt.Errorf("test sign: %w", err) return fmt.Errorf("test sign: %w", err)
} }
// Verify against the public key. // Verify against the public key.
h := RFCHeader{Alg: alg, KID: pk.KID} 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 fmt.Errorf("test verify: %w", err)
} }
return nil return nil

View File

@ -60,7 +60,7 @@ func NewVerifier(keys []PublicKey) (*Verifier, error) {
entries := seen[k.KID] entries := seen[k.KID]
dup := false dup := false
for _, e := range entries { for _, e := range entries {
if e.key.Equal(k.Key) { if e.key.Equal(k.Pub) {
dup = true dup = true
break break
} }
@ -68,7 +68,7 @@ func NewVerifier(keys []PublicKey) (*Verifier, error) {
if dup { if dup {
continue // identical key material, skip 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) deduped = append(deduped, k)
} }
return &Verifier{ return &Verifier{
@ -136,7 +136,7 @@ func (v *Verifier) Verify(jws VerifiableJWT) error {
// for the token's algorithm) since it's more informative. // for the token's algorithm) since it's more informative.
var bestErr error var bestErr error
for _, pk := range candidates { for _, pk := range candidates {
err := verifyOneKey(h, pk.Key, signingInput, sig) err := verifyOneKey(h, pk.Pub, signingInput, sig)
if err == nil { if err == nil {
return nil return nil
} }