From b0985390e4e64756582bebc8f17776a5a6870c7c Mon Sep 17 00:00:00 2001 From: Misha Sizov Date: Wed, 27 Jul 2022 11:52:47 +0300 Subject: [PATCH] create credentials trustblock Signed-off-by: Mykhailo Sizov --- pkg/doc/jwt/jwt_support.go | 59 +++++- .../features/verifiable_credential.feature | 15 +- .../interop_credential_10_secp384r1.jwt | 3 + .../interop_credential_11_secp384r1.jwt | 3 + .../interop_credential_12_secp384r1.jwt | 3 + ...1.jwt => interop_credential_1_ed25519.jwt} | 0 ...2.jwt => interop_credential_2_ed25519.jwt} | 0 ...3.jwt => interop_credential_3_ed25519.jwt} | 0 .../interop_credential_4_secp256k1.jwt | 3 + .../interop_credential_5_secp256k1.jwt | 3 + .../interop_credential_6_secp256k1.jwt | 3 + .../interop_credential_7_secp256r1.jwt | 3 + .../interop_credential_8_secp256r1.jwt | 3 + .../interop_credential_9_secp256r1.jwt | 3 + ...nterop_key.jwk => interop_key_ed25519.jwk} | 0 .../testdata/interop_key_secp256k1.jwk | 6 + .../testdata/interop_key_secp256r1.jwk | 6 + .../testdata/interop_key_secp384r1.jwk | 6 + test/bdd/pkg/verifiable/verifiable_steps.go | 190 +++++++++++++++--- 19 files changed, 275 insertions(+), 34 deletions(-) create mode 100644 test/bdd/pkg/verifiable/testdata/interop_credential_10_secp384r1.jwt create mode 100644 test/bdd/pkg/verifiable/testdata/interop_credential_11_secp384r1.jwt create mode 100644 test/bdd/pkg/verifiable/testdata/interop_credential_12_secp384r1.jwt rename test/bdd/pkg/verifiable/testdata/{interop_credential_1.jwt => interop_credential_1_ed25519.jwt} (100%) rename test/bdd/pkg/verifiable/testdata/{interop_credential_2.jwt => interop_credential_2_ed25519.jwt} (100%) rename test/bdd/pkg/verifiable/testdata/{interop_credential_3.jwt => interop_credential_3_ed25519.jwt} (100%) create mode 100644 test/bdd/pkg/verifiable/testdata/interop_credential_4_secp256k1.jwt create mode 100644 test/bdd/pkg/verifiable/testdata/interop_credential_5_secp256k1.jwt create mode 100644 test/bdd/pkg/verifiable/testdata/interop_credential_6_secp256k1.jwt create mode 100644 test/bdd/pkg/verifiable/testdata/interop_credential_7_secp256r1.jwt create mode 100644 test/bdd/pkg/verifiable/testdata/interop_credential_8_secp256r1.jwt create mode 100644 test/bdd/pkg/verifiable/testdata/interop_credential_9_secp256r1.jwt rename test/bdd/pkg/verifiable/testdata/{interop_key.jwk => interop_key_ed25519.jwk} (100%) create mode 100644 test/bdd/pkg/verifiable/testdata/interop_key_secp256k1.jwk create mode 100644 test/bdd/pkg/verifiable/testdata/interop_key_secp256r1.jwk create mode 100644 test/bdd/pkg/verifiable/testdata/interop_key_secp384r1.jwk diff --git a/pkg/doc/jwt/jwt_support.go b/pkg/doc/jwt/jwt_support.go index 07d82b9b2f..7d08597529 100644 --- a/pkg/doc/jwt/jwt_support.go +++ b/pkg/doc/jwt/jwt_support.go @@ -12,8 +12,10 @@ import ( "crypto/rand" "crypto/rsa" "errors" + "fmt" "github.com/hyperledger/aries-framework-go/pkg/doc/jose" + "github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier" ) // JoseED25519Signer is a Jose compliant signer. @@ -72,6 +74,55 @@ func NewEd25519Verifier(pubKey []byte) (*JoseEd25519Verifier, error) { return &JoseEd25519Verifier{pubKey: pubKey}, nil } +// JoseECDSAVerifier is a Jose compliant verifier. +type JoseECDSAVerifier struct { + alg string + publicKey *verifier.PublicKey + verifier verifier.SignatureVerifier +} + +// NewECDSAVerifier returns a Jose compliant verifier that can be passed as a verifier option to jwt.Parse(). +func NewECDSAVerifier(curve string, publicKey *verifier.PublicKey) *JoseECDSAVerifier { + var v verifier.SignatureVerifier + + var algorithm string + + switch curve { + case "secp256k1": + algorithm = "ES256K" + v = verifier.NewECDSASecp256k1SignatureVerifier() + case "secp256r1": + algorithm = "ES256" + v = verifier.NewECDSAES256SignatureVerifier() + case "secp384r1": + algorithm = "ES384" + v = verifier.NewECDSAES384SignatureVerifier() + case "secp521r1": + algorithm = "ES521" + v = verifier.NewECDSAES521SignatureVerifier() + } + + return &JoseECDSAVerifier{ + alg: algorithm, + publicKey: publicKey, + verifier: v, + } +} + +// Verify signingInput against signature. it validates that joseHeaders contains EdDSA alg for this implementation. +func (v JoseECDSAVerifier) Verify(joseHeaders jose.Headers, _, signingInput, signature []byte) error { + alg, ok := joseHeaders.Algorithm() + if !ok { + return errors.New("alg is not defined") + } + + if alg != v.alg { + return fmt.Errorf("alg is not %s", v.alg) + } + + return v.verifier.Verify(v.publicKey, signingInput, signature) +} + // RS256Signer is a Jose complient signer. type RS256Signer struct { privKey *rsa.PrivateKey @@ -139,14 +190,14 @@ func (v RS256Verifier) Verify(joseHeaders jose.Headers, _, signingInput, signatu } func verifyEd25519(jws string, pubKey ed25519.PublicKey) error { - verifier, err := NewEd25519Verifier(pubKey) + v, err := NewEd25519Verifier(pubKey) if err != nil { return err } sVerifier := jose.NewCompositeAlgSigVerifier(jose.AlgSignatureVerifier{ Alg: "EdDSA", - Verifier: verifier, + Verifier: v, }) token, err := Parse(jws, WithSignatureVerifier(sVerifier)) @@ -162,11 +213,11 @@ func verifyEd25519(jws string, pubKey ed25519.PublicKey) error { } func verifyRS256(jws string, pubKey *rsa.PublicKey) error { - verifier := NewRS256Verifier(pubKey) + v := NewRS256Verifier(pubKey) sVerifier := jose.NewCompositeAlgSigVerifier(jose.AlgSignatureVerifier{ Alg: "RS256", - Verifier: verifier, + Verifier: v, }) token, err := Parse(jws, WithSignatureVerifier(sVerifier)) diff --git a/test/bdd/features/verifiable_credential.feature b/test/bdd/features/verifiable_credential.feature index df09052816..779453f172 100644 --- a/test/bdd/features/verifiable_credential.feature +++ b/test/bdd/features/verifiable_credential.feature @@ -38,6 +38,15 @@ Feature: Issue Verifiable Credential @interop_jwt_verifiable Scenario: Load and verify Interop JWT credentials - When loading interop credential number "1" and verify it - And loading interop credential number "2" and verify it - And loading interop credential number "3" and verify it + When loading file "interop_credential_1_ed25519.jwt" signed using "Ed25519" and verify it + And loading file "interop_credential_2_ed25519.jwt" signed using "Ed25519" and verify it + And loading file "interop_credential_3_ed25519.jwt" signed using "Ed25519" and verify it + And loading file "interop_credential_4_secp256k1.jwt" signed using "secp256k1" and verify it + And loading file "interop_credential_5_secp256k1.jwt" signed using "secp256k1" and verify it + And loading file "interop_credential_6_secp256k1.jwt" signed using "secp256k1" and verify it + And loading file "interop_credential_7_secp256r1.jwt" signed using "secp256r1" and verify it + And loading file "interop_credential_8_secp256r1.jwt" signed using "secp256r1" and verify it + And loading file "interop_credential_9_secp256r1.jwt" signed using "secp256r1" and verify it + And loading file "interop_credential_10_secp384r1.jwt" signed using "secp384r1" and verify it + And loading file "interop_credential_11_secp384r1.jwt" signed using "secp384r1" and verify it + And loading file "interop_credential_12_secp384r1.jwt" signed using "secp384r1" and verify it diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_10_secp384r1.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_10_secp384r1.jwt new file mode 100644 index 0000000000..2cd7d36dd0 --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_credential_10_secp384r1.jwt @@ -0,0 +1,3 @@ +{ + "jwt": "eyJhbGciOiJFUzM4NCIsImtpZCI6ImRpZDpleGFtcGxlOjEyMyNrZXktMyJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZToxMjMiLCJzdWIiOnt9LCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIl0sInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmV4YW1wbGU6MTIzIiwiaXNzdWFuY2VEYXRlIjoiMjAyMS0wMS0wMVQxOToyMzoyNFoiLCJjcmVkZW50aWFsU3ViamVjdCI6e319LCJuYmYiOjE2MDk1MjkwMDR9.05C5qLfgoT_qIuePQw7wCbBneKYVLpNdTUzXXBAhVudFX57OAkyEM02FGs1vdQo2qWELgJ8eLa1s6mNNbdyCHJqIIpQIEkeX8H1-yQNohkuWTHgO55XF4GaoghmRaSeK" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_11_secp384r1.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_11_secp384r1.jwt new file mode 100644 index 0000000000..adb54f6486 --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_credential_11_secp384r1.jwt @@ -0,0 +1,3 @@ +{ + "jwt": "eyJhbGciOiJFUzM4NCIsImtpZCI6ImRpZDpleGFtcGxlOjEyMyNrZXktMyJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZToxMjMiLCJzdWIiOiJkaWQ6ZXhhbXBsZTo0NTYiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIix7IkB2b2NhYiI6Imh0dHBzOi8vZXhhbXBsZS5jb20vIyJ9XSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6ZXhhbXBsZToxMjMiLCJpc3N1YW5jZURhdGUiOiIyMDIxLTAxLTAxVDE5OjIzOjI0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAzMS0wMS0wMVQxOToyMzoyNFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDpleGFtcGxlOjQ1NiIsInR5cGUiOiJQZXJzb24ifX0sIm5iZiI6MTYwOTUyOTAwNCwiZXhwIjoxOTI1MDYxODA0fQ.I4r7B4-TsqNY5DaeQeTIrpVl7-3WGZJ6ikGwZ6wg9eKd3sDGTh7qwpydKFEpMC8n9yfJ6i7b6Ufngb3jy5X2_mrDNrbhtugnap4Xs-gkqRAuX8GZCkin7K_-_fVdAb-W" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_12_secp384r1.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_12_secp384r1.jwt new file mode 100644 index 0000000000..c07aeb3dd7 --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_credential_12_secp384r1.jwt @@ -0,0 +1,3 @@ +{ + "jwt": "eyJhbGciOiJFUzM4NCIsImtpZCI6ImRpZDpleGFtcGxlOjEyMyNrZXktMyJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZToxMjMiLCJzdWIiOiJkaWQ6ZXhhbXBsZTo0NTYiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIix7IkB2b2NhYiI6Imh0dHBzOi8vZXhhbXBsZS5jb20vIyJ9XSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6ZXhhbXBsZToxMjMiLCJpc3N1YW5jZURhdGUiOiIyMDIxLTAxLTAxVDE5OjIzOjI0WiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmV4YW1wbGU6NDU2In0sImV2aWRlbmNlIjpbeyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvZXZpZGVuY2UvZjJhZWVjOTctZmMwZC00MmJmLThjYTctMDU0ODE5MmQ0MjMxIiwidHlwZSI6WyJEb2N1bWVudFZlcmlmaWNhdGlvbiJdLCJ2ZXJpZmllciI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvaXNzdWVycy8xNCIsImV2aWRlbmNlRG9jdW1lbnQiOiJEcml2ZXJzTGljZW5zZSIsInN1YmplY3RQcmVzZW5jZSI6IlBoeXNpY2FsIiwiZG9jdW1lbnRQcmVzZW5jZSI6IlBoeXNpY2FsIn0seyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvZXZpZGVuY2UvZjJhZWVjOTctZmMwZC00MmJmLThjYTctMDU0ODE5MmR4eXphYiIsInR5cGUiOlsiU3VwcG9ydGluZ0FjdGl2aXR5Il0sInZlcmlmaWVyIjoiaHR0cHM6Ly9leGFtcGxlLmVkdS9pc3N1ZXJzLzE0IiwiZXZpZGVuY2VEb2N1bWVudCI6IkZsdWlkIER5bmFtaWNzIEZvY3VzIiwic3ViamVjdFByZXNlbmNlIjoiRGlnaXRhbCIsImRvY3VtZW50UHJlc2VuY2UiOiJEaWdpdGFsIn1dfSwibmJmIjoxNjA5NTI5MDA0fQ.R7qQYP4Fct02EkNlSuAghmTN-tBUgcmlV8pbBkqv41f6W2HxspYNsDfhCY2iV76_v0gbQsd97AS4_2j4YsA2QFGxZju6w2SjbvS3vdFluaPiXlv0X24zIlgpAmboHiHZ" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_1.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_1_ed25519.jwt similarity index 100% rename from test/bdd/pkg/verifiable/testdata/interop_credential_1.jwt rename to test/bdd/pkg/verifiable/testdata/interop_credential_1_ed25519.jwt diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_2.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_2_ed25519.jwt similarity index 100% rename from test/bdd/pkg/verifiable/testdata/interop_credential_2.jwt rename to test/bdd/pkg/verifiable/testdata/interop_credential_2_ed25519.jwt diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_3.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_3_ed25519.jwt similarity index 100% rename from test/bdd/pkg/verifiable/testdata/interop_credential_3.jwt rename to test/bdd/pkg/verifiable/testdata/interop_credential_3_ed25519.jwt diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_4_secp256k1.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_4_secp256k1.jwt new file mode 100644 index 0000000000..c3b77c0cd2 --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_credential_4_secp256k1.jwt @@ -0,0 +1,3 @@ +{ + "jwt": "eyJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6ZXhhbXBsZToxMjMja2V5LTEifQ.eyJpc3MiOiJkaWQ6ZXhhbXBsZToxMjMiLCJzdWIiOnt9LCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIl0sInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmV4YW1wbGU6MTIzIiwiaXNzdWFuY2VEYXRlIjoiMjAyMS0wMS0wMVQxOToyMzoyNFoiLCJjcmVkZW50aWFsU3ViamVjdCI6e319LCJuYmYiOjE2MDk1MjkwMDR9.YVL3RiZBtVgB8A1Et6GkPVrNH1SEe9hSoOho-wxPavwKTs7WxFliYQk9GNladKX_Gt6Js88mlwNMHWBStE7aug" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_5_secp256k1.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_5_secp256k1.jwt new file mode 100644 index 0000000000..06f5816b6f --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_credential_5_secp256k1.jwt @@ -0,0 +1,3 @@ +{ + "jwt": "eyJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6ZXhhbXBsZToxMjMja2V5LTEifQ.eyJpc3MiOiJkaWQ6ZXhhbXBsZToxMjMiLCJzdWIiOiJkaWQ6ZXhhbXBsZTo0NTYiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIix7IkB2b2NhYiI6Imh0dHBzOi8vZXhhbXBsZS5jb20vIyJ9XSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6ZXhhbXBsZToxMjMiLCJpc3N1YW5jZURhdGUiOiIyMDIxLTAxLTAxVDE5OjIzOjI0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAzMS0wMS0wMVQxOToyMzoyNFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDpleGFtcGxlOjQ1NiIsInR5cGUiOiJQZXJzb24ifX0sIm5iZiI6MTYwOTUyOTAwNCwiZXhwIjoxOTI1MDYxODA0fQ.hGbmzyTrGJNc21aHxbhaV-o-8j3p4w3Zj3mMXtYaA_IJvTgrAabtRqxhSQyVNYSv93BnxLr_7Qehdx6ym-ax9g" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_6_secp256k1.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_6_secp256k1.jwt new file mode 100644 index 0000000000..9468958ed6 --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_credential_6_secp256k1.jwt @@ -0,0 +1,3 @@ +{ + "jwt": "eyJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6ZXhhbXBsZToxMjMja2V5LTEifQ.eyJpc3MiOiJkaWQ6ZXhhbXBsZToxMjMiLCJzdWIiOiJkaWQ6ZXhhbXBsZTo0NTYiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIix7IkB2b2NhYiI6Imh0dHBzOi8vZXhhbXBsZS5jb20vIyJ9XSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6ZXhhbXBsZToxMjMiLCJpc3N1YW5jZURhdGUiOiIyMDIxLTAxLTAxVDE5OjIzOjI0WiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmV4YW1wbGU6NDU2In0sImV2aWRlbmNlIjpbeyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvZXZpZGVuY2UvZjJhZWVjOTctZmMwZC00MmJmLThjYTctMDU0ODE5MmQ0MjMxIiwidHlwZSI6WyJEb2N1bWVudFZlcmlmaWNhdGlvbiJdLCJ2ZXJpZmllciI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvaXNzdWVycy8xNCIsImV2aWRlbmNlRG9jdW1lbnQiOiJEcml2ZXJzTGljZW5zZSIsInN1YmplY3RQcmVzZW5jZSI6IlBoeXNpY2FsIiwiZG9jdW1lbnRQcmVzZW5jZSI6IlBoeXNpY2FsIn0seyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvZXZpZGVuY2UvZjJhZWVjOTctZmMwZC00MmJmLThjYTctMDU0ODE5MmR4eXphYiIsInR5cGUiOlsiU3VwcG9ydGluZ0FjdGl2aXR5Il0sInZlcmlmaWVyIjoiaHR0cHM6Ly9leGFtcGxlLmVkdS9pc3N1ZXJzLzE0IiwiZXZpZGVuY2VEb2N1bWVudCI6IkZsdWlkIER5bmFtaWNzIEZvY3VzIiwic3ViamVjdFByZXNlbmNlIjoiRGlnaXRhbCIsImRvY3VtZW50UHJlc2VuY2UiOiJEaWdpdGFsIn1dfSwibmJmIjoxNjA5NTI5MDA0fQ.GoHapgwZw1FXnZeNrUXNr8xDqec0yPDEN7SAslmgIYpoAByT9jvVsHChr1auGH5ffIPv2xtzindzMox0uvY6qw" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_7_secp256r1.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_7_secp256r1.jwt new file mode 100644 index 0000000000..f470de8349 --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_credential_7_secp256r1.jwt @@ -0,0 +1,3 @@ +{ + "jwt": "eyJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDpleGFtcGxlOjEyMyNrZXktMiJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZToxMjMiLCJzdWIiOnt9LCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIl0sInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmV4YW1wbGU6MTIzIiwiaXNzdWFuY2VEYXRlIjoiMjAyMS0wMS0wMVQxOToyMzoyNFoiLCJjcmVkZW50aWFsU3ViamVjdCI6e319LCJuYmYiOjE2MDk1MjkwMDR9.cXODOOr-lXftWixTpRL3SQcpfZi8Rluk7e_z1MUC9dnMVuILoqGAoEyG2ub5kCSU9xGxhGMP6Vf10kE-OhuhTQ" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_8_secp256r1.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_8_secp256r1.jwt new file mode 100644 index 0000000000..9184fb8f00 --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_credential_8_secp256r1.jwt @@ -0,0 +1,3 @@ +{ + "jwt": "eyJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDpleGFtcGxlOjEyMyNrZXktMiJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZToxMjMiLCJzdWIiOiJkaWQ6ZXhhbXBsZTo0NTYiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIix7IkB2b2NhYiI6Imh0dHBzOi8vZXhhbXBsZS5jb20vIyJ9XSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6ZXhhbXBsZToxMjMiLCJpc3N1YW5jZURhdGUiOiIyMDIxLTAxLTAxVDE5OjIzOjI0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAzMS0wMS0wMVQxOToyMzoyNFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDpleGFtcGxlOjQ1NiIsInR5cGUiOiJQZXJzb24ifX0sIm5iZiI6MTYwOTUyOTAwNCwiZXhwIjoxOTI1MDYxODA0fQ.mf-45FzLytSruzau03jbOZwmwEaGnSST0xAbwkPINSCTxShLBArSLCxHgDleHssezfUV1VAbbNslZ3Db0sn5qA" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/testdata/interop_credential_9_secp256r1.jwt b/test/bdd/pkg/verifiable/testdata/interop_credential_9_secp256r1.jwt new file mode 100644 index 0000000000..19a09660fb --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_credential_9_secp256r1.jwt @@ -0,0 +1,3 @@ +{ + "jwt": "eyJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDpleGFtcGxlOjEyMyNrZXktMiJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZToxMjMiLCJzdWIiOiJkaWQ6ZXhhbXBsZTo0NTYiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIix7IkB2b2NhYiI6Imh0dHBzOi8vZXhhbXBsZS5jb20vIyJ9XSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6ZXhhbXBsZToxMjMiLCJpc3N1YW5jZURhdGUiOiIyMDIxLTAxLTAxVDE5OjIzOjI0WiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmV4YW1wbGU6NDU2In0sImV2aWRlbmNlIjpbeyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvZXZpZGVuY2UvZjJhZWVjOTctZmMwZC00MmJmLThjYTctMDU0ODE5MmQ0MjMxIiwidHlwZSI6WyJEb2N1bWVudFZlcmlmaWNhdGlvbiJdLCJ2ZXJpZmllciI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvaXNzdWVycy8xNCIsImV2aWRlbmNlRG9jdW1lbnQiOiJEcml2ZXJzTGljZW5zZSIsInN1YmplY3RQcmVzZW5jZSI6IlBoeXNpY2FsIiwiZG9jdW1lbnRQcmVzZW5jZSI6IlBoeXNpY2FsIn0seyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5lZHUvZXZpZGVuY2UvZjJhZWVjOTctZmMwZC00MmJmLThjYTctMDU0ODE5MmR4eXphYiIsInR5cGUiOlsiU3VwcG9ydGluZ0FjdGl2aXR5Il0sInZlcmlmaWVyIjoiaHR0cHM6Ly9leGFtcGxlLmVkdS9pc3N1ZXJzLzE0IiwiZXZpZGVuY2VEb2N1bWVudCI6IkZsdWlkIER5bmFtaWNzIEZvY3VzIiwic3ViamVjdFByZXNlbmNlIjoiRGlnaXRhbCIsImRvY3VtZW50UHJlc2VuY2UiOiJEaWdpdGFsIn1dfSwibmJmIjoxNjA5NTI5MDA0fQ.VnZa5sbqel3Z3sJOwlssI9PqOGEyrVkiH1mtq_WCSe-FQ2QDHn59kxJRt4SGKQCYXq_fX0LxDLAYpIx8NdjKwQ" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/testdata/interop_key.jwk b/test/bdd/pkg/verifiable/testdata/interop_key_ed25519.jwk similarity index 100% rename from test/bdd/pkg/verifiable/testdata/interop_key.jwk rename to test/bdd/pkg/verifiable/testdata/interop_key_ed25519.jwk diff --git a/test/bdd/pkg/verifiable/testdata/interop_key_secp256k1.jwk b/test/bdd/pkg/verifiable/testdata/interop_key_secp256k1.jwk new file mode 100644 index 0000000000..20011ff7f9 --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_key_secp256k1.jwk @@ -0,0 +1,6 @@ +{ + "kty": "EC", + "crv": "secp256k1", + "x": "BuzCc8bUShI3GfVz-WLISZDGq7wnVB4h_nvNQcWn7Jw", + "y": "dLrbspB9PZvZF0dr42nCmF38192dQKglvB52IZBM-vs" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/testdata/interop_key_secp256r1.jwk b/test/bdd/pkg/verifiable/testdata/interop_key_secp256r1.jwk new file mode 100644 index 0000000000..799a13fe36 --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_key_secp256r1.jwk @@ -0,0 +1,6 @@ +{ + "kty": "EC", + "crv": "P-256", + "x": "40TexHWb6XTyuShaqhiazvmfxyK5zibbtOBXsQFKJg8", + "y": "SGIGDSRHOOYJntO1lIapw_vR1FP7SPBlmA_2aM9HoFU" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/testdata/interop_key_secp384r1.jwk b/test/bdd/pkg/verifiable/testdata/interop_key_secp384r1.jwk new file mode 100644 index 0000000000..8a725155c1 --- /dev/null +++ b/test/bdd/pkg/verifiable/testdata/interop_key_secp384r1.jwk @@ -0,0 +1,6 @@ +{ + "kty": "EC", + "crv": "P-384", + "x": "BiU_mGfa3uWMKrC4Q6EFvM5D5Qiz2orm7ABlIaC1iJWOuapQC9U_fbqrKwRFRepf", + "y": "_23qoYv94V-PSWzqQMnUqq1nu_MdE4fEIaAhCCYplAwlp4c3LKZDtkgQaPdF4kIT" +} \ No newline at end of file diff --git a/test/bdd/pkg/verifiable/verifiable_steps.go b/test/bdd/pkg/verifiable/verifiable_steps.go index 908a0b25bc..6875d9e725 100644 --- a/test/bdd/pkg/verifiable/verifiable_steps.go +++ b/test/bdd/pkg/verifiable/verifiable_steps.go @@ -46,60 +46,192 @@ import ( bddldcontext "github.com/hyperledger/aries-framework-go/test/bdd/pkg/ldcontext" ) -//go:embed testdata/interop_credential_1.jwt +//go:embed testdata/interop_credential_1_ed25519.jwt //nolint:lll // picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/spruce/credential-0--key-0-ed25519.vc-jwt.json -var credential1 string //nolint:gochecknoglobals +var credential1Ed25519 string //nolint:gochecknoglobals -//go:embed testdata/interop_credential_2.jwt +//go:embed testdata/interop_credential_2_ed25519.jwt //nolint:lll // picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/spruce/credential-1--key-0-ed25519.vc-jwt.json -var credential2 string //nolint:gochecknoglobals +var credential2Ed25519 string //nolint:gochecknoglobals -//go:embed testdata/interop_credential_3.jwt +//go:embed testdata/interop_credential_3_ed25519.jwt //nolint:lll // picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/spruce/credential-2--key-0-ed25519.vc-jwt.json -var credential3 string //nolint:gochecknoglobals +var credential3Ed25519 string //nolint:gochecknoglobals -//go:embed testdata/interop_key.jwk +//go:embed testdata/interop_credential_4_secp256k1.jwt +//nolint:lll +// picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/transmute/credential-0--key-1-secp256k1.vc-jwt.json +var credential4Secp256k1 string //nolint:gochecknoglobals + +//go:embed testdata/interop_credential_5_secp256k1.jwt +//nolint:lll +// picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/transmute/credential-1--key-1-secp256k1.vc-jwt.json +var credential5Secp256k1 string //nolint:gochecknoglobals + +//go:embed testdata/interop_credential_6_secp256k1.jwt +//nolint:lll +// picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/transmute/credential-2--key-1-secp256k1.vc-jwt.json +var credential6Secp256k1 string //nolint:gochecknoglobals + +//go:embed testdata/interop_credential_7_secp256r1.jwt +//nolint:lll +// picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/transmute/credential-0--key-2-secp256r1.vc-jwt.json +var credential7Secp256r1 string //nolint:gochecknoglobals + +//go:embed testdata/interop_credential_8_secp256r1.jwt +//nolint:lll +// picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/transmute/credential-1--key-2-secp256r1.vc-jwt.json +var credential8Secp256r1 string //nolint:gochecknoglobals + +//go:embed testdata/interop_credential_9_secp256r1.jwt +//nolint:lll +// picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/transmute/credential-2--key-2-secp256r1.vc-jwt.json +var credential9Secp256r1 string //nolint:gochecknoglobals + +//go:embed testdata/interop_credential_10_secp384r1.jwt +//nolint:lll +// picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/transmute/credential-0--key-3-secp384r1.vc-jwt.json +var credential10Secp384r1 string //nolint:gochecknoglobals + +//go:embed testdata/interop_credential_11_secp384r1.jwt +//nolint:lll +// picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/transmute/credential-1--key-3-secp384r1.vc-jwt.json +var credential11Secp384r1 string //nolint:gochecknoglobals + +//go:embed testdata/interop_credential_12_secp384r1.jwt +//nolint:lll +// picked up from https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/implementations/transmute/credential-2--key-3-secp384r1.vc-jwt.json +var credential12Secp384r1 string //nolint:gochecknoglobals + +//go:embed testdata/interop_key_ed25519.jwk // ref https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/keys/key-0-ed25519.json -var interopKey string //nolint:gochecknoglobals +var interopKeyEd25519 string //nolint:gochecknoglobals + +//go:embed testdata/interop_key_secp256k1.jwk +// ref https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/keys/key-1-secp256k1.json +var interopKeyECDSASecp256k1 string //nolint:gochecknoglobals + +//go:embed testdata/interop_key_secp256r1.jwk +// ref https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/keys/key-2-secp256r1.json +var interopKeyECDSASecp256r1 string //nolint:gochecknoglobals + +//go:embed testdata/interop_key_secp384r1.jwk +// ref https://github.com/decentralized-identity/JWS-Test-Suite/blob/main/data/keys/key-3-secp384r1.json +var interopKeyECDSASecp384r1 string //nolint:gochecknoglobals // SDKSteps is steps for verifiable credentials using client SDK. type SDKSteps struct { bddContext *context.BDDContext issuedVCBytes []byte secp256k1PrivKey *ecdsa.PrivateKey - joseVerifier jose.SignatureVerifier - interopPubKey *verifier.PublicKey - interopCreds map[string]string + joseVerifier map[string]jose.SignatureVerifier + interopPubKey map[string]*verifier.PublicKey + interopCreds map[string]map[string]string } // NewVerifiableCredentialSDKSteps creates steps for verifiable credential with SDK. func NewVerifiableCredentialSDKSteps() *SDKSteps { - jwkKey := &jwk.JWK{} + // Ed25519 + jwkEd25519 := getJWK([]byte(interopKeyEd25519)) + pubKeyEd25519 := getEd25519PublicKey(jwkEd25519) + // Secp256k1 + jwkSecp256k1 := getJWK([]byte(interopKeyECDSASecp256k1)) + pubKeySecp256k1 := getSecp256k1PublicKey(jwkSecp256k1) + // Secp256r1 + jwkSecp256r1 := getJWK([]byte(interopKeyECDSASecp256r1)) + pubKeySecp256r1 := getSecp256r1PublicKey(jwkSecp256r1) + // Secp384r1 + jwkSecp384r1 := getJWK([]byte(interopKeyECDSASecp384r1)) + pubKeySecp384r1 := getSecp384r1PublicKey(jwkSecp384r1) + + return &SDKSteps{ + joseVerifier: map[string]jose.SignatureVerifier{ + ed25519Signature: getEd25519Verifier(pubKeyEd25519.Value), + ecdsaSecp256k1Signature: jwt.NewECDSAVerifier(ecdsaSecp256k1Signature, pubKeySecp256k1), + ecdsaSecp256r1Signature: jwt.NewECDSAVerifier(ecdsaSecp256r1Signature, pubKeySecp256r1), + ecdsaSecp384r1Signature: jwt.NewECDSAVerifier(ecdsaSecp384r1Signature, pubKeySecp384r1), + }, + interopPubKey: map[string]*verifier.PublicKey{ + ed25519Signature: pubKeyEd25519, + ecdsaSecp256k1Signature: pubKeySecp256k1, + ecdsaSecp256r1Signature: pubKeySecp256r1, + ecdsaSecp384r1Signature: pubKeySecp384r1, + }, + interopCreds: map[string]map[string]string{ + ed25519Signature: { + "interop_credential_1_ed25519.jwt": credential1Ed25519, + "interop_credential_2_ed25519.jwt": credential2Ed25519, + "interop_credential_3_ed25519.jwt": credential3Ed25519, + }, + ecdsaSecp256k1Signature: { + "interop_credential_4_secp256k1.jwt": credential4Secp256k1, + "interop_credential_5_secp256k1.jwt": credential5Secp256k1, + "interop_credential_6_secp256k1.jwt": credential6Secp256k1, + }, + ecdsaSecp256r1Signature: { + "interop_credential_7_secp256r1.jwt": credential7Secp256r1, + "interop_credential_8_secp256r1.jwt": credential8Secp256r1, + "interop_credential_9_secp256r1.jwt": credential9Secp256r1, + }, + ecdsaSecp384r1Signature: { + "interop_credential_10_secp384r1.jwt": credential10Secp384r1, + "interop_credential_11_secp384r1.jwt": credential11Secp384r1, + "interop_credential_12_secp384r1.jwt": credential12Secp384r1, + }, + }, + } +} + +func getSecp256k1PublicKey(jwkKey *jwk.JWK) *verifier.PublicKey { + return &verifier.PublicKey{ + Type: ecdsaSecp256k1Signature, + JWK: jwkKey, + } +} + +func getSecp256r1PublicKey(jwkKey *jwk.JWK) *verifier.PublicKey { + return &verifier.PublicKey{ + Type: ecdsaSecp256r1Signature, + JWK: jwkKey, + } +} - err := jwkKey.UnmarshalJSON([]byte(interopKey)) +func getSecp384r1PublicKey(jwkKey *jwk.JWK) *verifier.PublicKey { + return &verifier.PublicKey{ + Type: ecdsaSecp384r1Signature, + JWK: jwkKey, + } +} + +func getEd25519Verifier(pubKey []byte) jose.SignatureVerifier { + v, err := jwt.NewEd25519Verifier(pubKey) if err != nil { panic(err) } - pubKey := &verifier.PublicKey{ - Type: "ed25519", + return v +} + +func getEd25519PublicKey(jwkKey *jwk.JWK) *verifier.PublicKey { + return &verifier.PublicKey{ + Type: ed25519Signature, Value: jwkKey.JSONWebKey.Key.(ed25519.PublicKey), JWK: jwkKey, } +} - v, err := jwt.NewEd25519Verifier(pubKey.Value) +func getJWK(jwkBytes []byte) *jwk.JWK { + jwkKey := &jwk.JWK{} + + err := jwkKey.UnmarshalJSON(jwkBytes) if err != nil { - return nil + panic(err) } - return &SDKSteps{ - joseVerifier: v, - interopPubKey: pubKey, - interopCreds: map[string]string{"1": credential1, "2": credential2, "3": credential3}, - } + return jwkKey } const ( @@ -109,7 +241,11 @@ const ( ldpJSONWebSignatureSecp256k1 = "JsonWebSignature2020 (secp256k1) Linked Data" ldpEcdsaSecp256k1Signature2019 = "EcdsaSecp256k1Signature2019 Linked Data" - jwsProof = "Ed25519 JWS" + jwsProof = "Ed25519 JWS" + ed25519Signature = "Ed25519" + ecdsaSecp256k1Signature = "secp256k1" + ecdsaSecp256r1Signature = "secp256r1" + ecdsaSecp384r1Signature = "secp384r1" ) // SetContext is called before every scenario is run with a fresh new context. @@ -120,7 +256,7 @@ func (s *SDKSteps) SetContext(ctx *context.BDDContext) { // RegisterSteps registers Verifiable Credential steps. func (s *SDKSteps) RegisterSteps(gs *godog.Suite) { gs.Step(`^"([^"]*)" issues credential at "([^"]*)" regarding "([^"]*)" to "([^"]*)" with "([^"]*)" proof$`, s.issueCredential) //nolint:lll - gs.Step(`^loading interop credential number "([^\"]*)" and verify it$`, s.loadInteropCredentialAndVerify) + gs.Step(`^loading file "([^\"]*)" signed using "([^\"]*)" and verify it$`, s.loadInteropCredentialAndVerify) gs.Step(`^"([^"]*)" receives the credential and verifies it$`, s.verifyCredential) } @@ -145,8 +281,8 @@ func (s *SDKSteps) issueCredential(issuer, issuedAt, subject, holder, proofType return nil } -func (s *SDKSteps) loadInteropCredentialAndVerify(claimID string) error { - credentialStr := s.interopCreds[claimID] +func (s *SDKSteps) loadInteropCredentialAndVerify(claimID, signature string) error { + credentialStr := s.interopCreds[signature][claimID] interopCred := &jwtCred{} err := json.Unmarshal([]byte(credentialStr), interopCred) @@ -154,7 +290,7 @@ func (s *SDKSteps) loadInteropCredentialAndVerify(claimID string) error { return err } - jwtCred, err := jwt.Parse(interopCred.JWT, jwt.WithSignatureVerifier(s.joseVerifier)) + jwtCred, err := jwt.Parse(interopCred.JWT, jwt.WithSignatureVerifier(s.joseVerifier[signature])) if jwtCred == nil { return fmt.Errorf("interop jwt cred was nil, err: %w", err) }