github.com/hyperledger/aries-framework-go@v0.3.2/pkg/doc/jose/kid/resolver/resolver_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package resolver 8 9 import ( 10 "bytes" 11 "crypto" 12 "crypto/ecdsa" 13 "crypto/elliptic" 14 "crypto/rand" 15 "crypto/sha256" 16 "encoding/base64" 17 "encoding/json" 18 "errors" 19 "fmt" 20 "testing" 21 22 commonpb "github.com/google/tink/go/proto/common_go_proto" 23 "github.com/stretchr/testify/require" 24 25 cryptoapi "github.com/hyperledger/aries-framework-go/pkg/crypto" 26 "github.com/hyperledger/aries-framework-go/pkg/crypto/primitive/bbs12381g2pub" 27 "github.com/hyperledger/aries-framework-go/pkg/doc/did" 28 "github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk" 29 "github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk/jwksupport" 30 "github.com/hyperledger/aries-framework-go/pkg/kms" 31 mockdiddoc "github.com/hyperledger/aries-framework-go/pkg/mock/diddoc" 32 mockstorage "github.com/hyperledger/aries-framework-go/pkg/mock/storage" 33 mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr" 34 ) 35 36 func TestResolveDIDKey(t *testing.T) { 37 didKeyP256 := "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169" 38 39 didKeyResolver := &DIDKeyResolver{} 40 41 key, err := didKeyResolver.Resolve(didKeyP256) 42 require.NoError(t, err) 43 require.NotEmpty(t, key) 44 require.Equal(t, commonpb.EllipticCurveType_NIST_P256.String(), key.Curve) 45 require.Equal(t, "EC", key.Type) 46 } 47 48 func TestResolveStoreKey(t *testing.T) { 49 kid := "key-1" 50 expectedKey := &cryptoapi.PublicKey{ 51 KID: kid, 52 X: []byte("x"), 53 Y: []byte("y"), 54 Curve: "P-521", 55 Type: "EC", 56 } 57 58 mKey, err := json.Marshal(expectedKey) 59 require.NoError(t, err) 60 61 store := &mockstorage.MockStore{Store: make(map[string]mockstorage.DBEntry)} 62 63 t.Run("resolve success", func(t *testing.T) { 64 err = store.Put(kid, mKey) 65 require.NoError(t, err) 66 67 storeKeyResolver := &StoreResolver{Store: store} 68 69 key, e := storeKeyResolver.Resolve(kid) 70 require.NoError(t, e) 71 require.EqualValues(t, expectedKey, key) 72 }) 73 74 t.Run("resolve fail with Unmarshal error", func(t *testing.T) { 75 err = store.Put(kid, []byte("*")) 76 require.NoError(t, err) 77 78 storeKeyResolver := &StoreResolver{Store: store} 79 80 key, e := storeKeyResolver.Resolve(kid) 81 require.EqualError(t, e, "storeResolver: failed to unmarshal public key from DB: invalid character "+ 82 "'*' looking for beginning of value") 83 require.Empty(t, key) 84 }) 85 86 t.Run("resolve fail with Get error", func(t *testing.T) { 87 getFailErr := "get Fail" 88 failStore := &mockstorage.MockStore{ErrGet: errors.New(getFailErr)} 89 storeKeyResolver := &StoreResolver{Store: failStore} 90 91 key, e := storeKeyResolver.Resolve(kid) 92 require.EqualError(t, e, fmt.Sprintf("storeResolver: failed to resolve kid from store: %s", getFailErr)) 93 require.Empty(t, key) 94 }) 95 } 96 97 func TestDIDDocResolverKey(t *testing.T) { 98 t.Run("resolve with empty DID doc should fail", func(t *testing.T) { 99 docResolver := DIDDocResolver{} 100 _, err := docResolver.Resolve("") 101 require.EqualError(t, err, "didDocResolver: missing vdr registry") 102 }) 103 104 t.Run("success - resolve with valid DID doc with X25519 key as KeyAgreement", func(t *testing.T) { 105 didDoc := mockdiddoc.GetMockDIDDocWithDIDCommV2Bloc(t, "random") 106 docResolver := DIDDocResolver{VDRRegistry: &mockvdr.MockVDRegistry{ 107 ResolveValue: didDoc, 108 }} 109 110 pubKey, err := docResolver.Resolve("did:peer:random#key-4") 111 require.NoError(t, err) 112 require.NotEmpty(t, pubKey) 113 require.Equal(t, "X25519", pubKey.Curve) 114 require.Equal(t, "OKP", pubKey.Type) 115 require.EqualValues(t, didDoc.KeyAgreement[0].VerificationMethod.Value, pubKey.X) 116 }) 117 118 tests := []struct { 119 name string 120 curve elliptic.Curve 121 }{ 122 { 123 name: "success - resolve with valid DID doc with P-256 key as keyAgreement", 124 curve: elliptic.P256(), 125 }, 126 { 127 name: "success - resolve with valid DID doc with P-384 key as keyAgreement", 128 curve: elliptic.P384(), 129 }, 130 { 131 name: "success - resolve with valid DID doc with P-521 key as keyAgreement", 132 curve: elliptic.P521(), 133 }, 134 } 135 136 for _, tt := range tests { 137 tc := tt 138 t.Run(tc.name, func(t *testing.T) { 139 didDoc := mockdiddoc.GetMockDIDDocWithDIDCommV2Bloc(t, "random") 140 pk, err := ecdsa.GenerateKey(tc.curve, rand.Reader) 141 require.NoError(t, err) 142 143 jwkKey, err := jwksupport.JWKFromKey(&pk.PublicKey) 144 require.NoError(t, err) 145 146 tp, err := jwkKey.Thumbprint(crypto.SHA256) 147 require.NoError(t, err) 148 149 kmsKID := base64.RawURLEncoding.EncodeToString(tp) 150 151 vm, err := did.NewVerificationMethodFromJWK( 152 didDoc.KeyAgreement[0].VerificationMethod.ID, jsonWebKey2020, didDoc.ID, jwkKey) 153 require.NoError(t, err) 154 155 didDoc.KeyAgreement[0].VerificationMethod = *vm 156 157 docResolver := DIDDocResolver{VDRRegistry: &mockvdr.MockVDRegistry{ 158 ResolveValue: didDoc, 159 }} 160 161 pubKey, err := docResolver.Resolve("did:peer:random#key-4") 162 require.NoError(t, err) 163 require.NotEmpty(t, pubKey) 164 require.EqualValues(t, kmsKID, pubKey.KID) 165 require.Equal(t, tc.curve.Params().Name, pubKey.Curve) 166 require.Equal(t, "EC", pubKey.Type) 167 require.EqualValues(t, pk.PublicKey.X.Bytes(), pubKey.X) 168 require.EqualValues(t, pk.PublicKey.Y.Bytes(), pubKey.Y) 169 }) 170 } 171 172 t.Run("success - resolve with valid DID doc with X25519 key as JWK in keyAgreement", func(t *testing.T) { 173 didDoc := mockdiddoc.GetMockDIDDocWithDIDCommV2Bloc(t, "random") 174 175 x25519 := make([]byte, 32) 176 _, err := rand.Read(x25519) 177 require.NoError(t, err) 178 179 jwkKey, err := jwksupport.JWKFromX25519Key(x25519) 180 require.NoError(t, err) 181 182 vm, err := did.NewVerificationMethodFromJWK( 183 didDoc.KeyAgreement[0].VerificationMethod.ID, jsonWebKey2020, didDoc.ID, jwkKey) 184 require.NoError(t, err) 185 186 didDoc.KeyAgreement[0].VerificationMethod = *vm 187 188 docResolver := DIDDocResolver{VDRRegistry: &mockvdr.MockVDRegistry{ 189 ResolveValue: didDoc, 190 }} 191 192 pubKey, err := docResolver.Resolve("did:peer:random#key-4") 193 require.NoError(t, err) 194 require.NotEmpty(t, pubKey) 195 require.Equal(t, "X25519", pubKey.Curve) 196 require.Equal(t, "OKP", pubKey.Type) 197 require.EqualValues(t, x25519, pubKey.X) 198 199 t.Run("failure resolving with kid missing # key index", func(t *testing.T) { 200 _, err = docResolver.Resolve("did:peer:random") 201 require.EqualError(t, err, "didDocResolver: kid is not KeyAgreement.ID: 'did:peer:random'") 202 }) 203 204 t.Run("failure resolving with invalid verification method type", func(t *testing.T) { 205 didDoc.KeyAgreement[0].VerificationMethod.Type = "invalid" 206 207 _, err = docResolver.Resolve("did:peer:random#key-4") 208 require.EqualError(t, err, "didDocResolver: can't build key from KayAgreement with type: 'invalid'") 209 }) 210 211 t.Run("failure resolving with invalid JWK key in verification method", func(t *testing.T) { 212 var ( 213 invalidKey *bbs12381g2pub.PublicKey 214 mInvalidKey []byte 215 invalidJWK *jwk.JWK 216 ) 217 218 invalidKey, _, err = bbs12381g2pub.GenerateKeyPair(sha256.New, []byte{}) 219 require.NoError(t, err) 220 221 mInvalidKey, err = invalidKey.Marshal() 222 require.NoError(t, err) 223 224 invalidJWK, err = jwksupport.PubKeyBytesToJWK(mInvalidKey, kms.BLS12381G2) 225 require.NoError(t, err) 226 227 vm, err = did.NewVerificationMethodFromJWK( 228 didDoc.KeyAgreement[0].VerificationMethod.ID, jsonWebKey2020, didDoc.ID, invalidJWK) 229 require.NoError(t, err) 230 231 didDoc.KeyAgreement[0].VerificationMethod = *vm 232 233 _, err = docResolver.Resolve("did:peer:random#key-4") 234 require.EqualError(t, err, "didDocResolver: buildJWKKey: unsupported JWK format: (*bbs12381g2pub.PublicKey)") 235 }) 236 237 t.Run("failure resolving with invalid X25519 key in verification method", func(t *testing.T) { 238 vm = did.NewVerificationMethodFromBytes(didDoc.KeyAgreement[0].VerificationMethod.ID, x25519KeyAgreementKey2019, 239 didDoc.ID, bytes.Repeat([]byte{0}, 33)) // 33 is an invalid X25519 public key size. 240 241 didDoc.KeyAgreement[0].VerificationMethod = *vm 242 243 _, err = docResolver.Resolve("did:peer:random#key-4") 244 require.EqualError(t, err, "didDocResolver: buildX25519: createKID error:createKID: createX25519KID:"+ 245 " buildX25519JWK: invalid ECDH X25519 key") 246 }) 247 }) 248 }