diff --git a/keyutil/jwk.go b/keyutil/jwk.go index 3342946..7b8e3a8 100644 --- a/keyutil/jwk.go +++ b/keyutil/jwk.go @@ -33,21 +33,24 @@ func ReadJWK(jwkBytes []byte) (JWK, error) { }, nil } -// ReadJWKFromPEM converts a PEM encoded private key to JWK -func ReadJWKFromPEM(pkeyBytes []byte) (JWK, error) { +// ReadJWKFromPEM converts a PEM encoded private key to JWK. Use 'fields' to set additional fields like kty, and kid. alg is set based on the passed in PrivateKey. +func ReadJWKFromPEM(fields JWK, pkeyBytes []byte) (JWK, error) { pkey, err := ReadPrivateKey(pkeyBytes) if err != nil { return JWK{}, err } - return FromPrivateKey(pkey) + return FromPrivateKey(fields, pkey) } -func FromPrivateKey(pkey crypto.PrivateKey) (JWK, error) { +// FromPrivateKey creates a JWK from a crypto.PrivateKey. Use 'fields' to set additional fields like kty, and kid. alg is set based on the passed in PrivateKey. +func FromPrivateKey(fields JWK, pkey crypto.PrivateKey) (JWK, error) { switch key := pkey.(type) { case *ecdsa.PrivateKey: jwk := jwkEC{ jwk: jwk{ KeyType: "EC", + Algo: fields.Algorithm, + KeyID: fields.KeyID, }, Curve: key.Curve.Params().Name, X: octet{key.X}, @@ -59,8 +62,10 @@ func FromPrivateKey(pkey crypto.PrivateKey) (JWK, error) { return JWK{}, fmt.Errorf("Error marshalling JWK: %w", err) } return JWK{ - KeyType: "EC", - raw: out, + KeyType: "EC", + Algorithm: fields.Algorithm, + KeyID: fields.KeyID, + raw: out, }, nil default: return JWK{}, fmt.Errorf("Unsupported private key type '%T'", pkey) diff --git a/keyutil/jwk_test.go b/keyutil/jwk_test.go index 0727dcf..5e6fd28 100644 --- a/keyutil/jwk_test.go +++ b/keyutil/jwk_test.go @@ -77,10 +77,12 @@ func TestJWKMarshalRoundTrip(t *testing.T) { name string inputType string expectedErrContains string + keyid string }{ { name: "EC Key Round Trip", inputType: "EC", + keyid: "mykey_123", }, } @@ -95,7 +97,10 @@ func TestJWKMarshalRoundTrip(t *testing.T) { t.Fatal(err) } } - original, err := FromPrivateKey(pk) + original, err := FromPrivateKey(JWK{ + KeyID: tc.keyid, + }, pk) + if err != nil { if tc.expectedErrContains != "" { if !strings.Contains(err.Error(), tc.expectedErrContains) { @@ -120,11 +125,12 @@ func TestJWKMarshalRoundTrip(t *testing.T) { // Compare original and round-tripped JWKs Diff(t, original, roundTripped, "Round-tripped JWK differs from original", cmpopts.IgnoreUnexported(JWK{})) + Diff(t, tc.keyid, roundTripped.KeyID, "Round-tripped JWK differs from original", cmpopts.IgnoreUnexported(JWK{})) }) } } -func Diff(t *testing.T, expected, actual interface{}, msg string, opts ...cmp.Option) bool { +func Diff(t *testing.T, expected, actual any, msg string, opts ...cmp.Option) bool { if diff := cmp.Diff(expected, actual, opts...); diff != "" { t.Errorf("%s (-want +got):\n%s", msg, diff) return true