From 5f893b08f8f6475f01ffdf3ad8569337b797a0b8 Mon Sep 17 00:00:00 2001 From: Micah Parks <66095735+MicahParks@users.noreply.github.com> Date: Wed, 3 Jan 2024 19:47:23 -0500 Subject: [PATCH] Consistent optional behavior for X.509 certificate thumbprints (#12) --- jwk.go | 7 +++++++ jwk_test.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/jwk.go b/jwk.go index 4343b5b..9bdf63a 100644 --- a/jwk.go +++ b/jwk.go @@ -301,6 +301,13 @@ func (j JWK) Validate() error { return fmt.Errorf("failed to marshal JSON Web Key: %w", errors.Join(ErrJWKValidation, err)) } + if j.marshal.X5T == "" { + marshalled.X5T = "" + } + if j.marshal.X5TS256 == "" { + marshalled.X5TS256 = "" + } + ok := reflect.DeepEqual(j.marshal, marshalled) if !ok { return fmt.Errorf("%w: marshaled JWK does not match original JWK", ErrJWKValidation) diff --git a/jwk_test.go b/jwk_test.go index 5dd075e..cceca73 100644 --- a/jwk_test.go +++ b/jwk_test.go @@ -38,6 +38,65 @@ func TestJSON(t *testing.T) { testJSON(ctx, t, jwks) } +func TestMissingThumbprint(t *testing.T) { + testCases := []struct { + name string + missingX5T bool + missingX5TS256 bool + }{ + { + name: "MissingX5T", + missingX5T: true, + }, + { + name: "MissingX5T#S256", + missingX5TS256: true, + }, + { + name: "MissingX5TAndX5T#S256", + missingX5T: true, + missingX5TS256: true, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + block, _ := pem.Decode([]byte(ed25519Cert)) + cert, err := LoadCertificate(block.Bytes) + if err != nil { + t.Fatalf("Failed to load certificate. %s", err) + } + metadata := JWKMetadataOptions{ + KID: myKeyID, + } + x509Options := JWKX509Options{ + X5C: []*x509.Certificate{cert}, + } + options := JWKOptions{ + Metadata: metadata, + X509: x509Options, + } + jwk, err := NewJWKFromKey(cert.PublicKey, options) + if err != nil { + t.Fatalf("Failed to create JWK from key. %s", err) + } + marshal := jwk.Marshal() + if tc.missingX5T { + marshal.X5T = "" + } + if tc.missingX5TS256 { + marshal.X5TS256 = "" + } + jwk, err = NewJWKFromMarshal(marshal, JWKMarshalOptions{}, JWKValidateOptions{}) + if err != nil { + t.Fatalf("Failed to create JWK from marshal. %s", err) + } + if jwk.Marshal().KID != myKeyID { + t.Fatalf("Incorrect KID. %s", jwk.Marshal().KID) + } + }) + } +} + func testJSON(ctx context.Context, t *testing.T, jwks Storage) { b, err := base64.RawURLEncoding.DecodeString(x25519PrivateKey) if err != nil {