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  }