github.com/hyperledger/aries-framework-go@v0.3.2/pkg/doc/util/didsignjwt/signjwt_test.go (about)

     1  /*
     2  Copyright Avast Software. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package didsignjwt
     8  
     9  import (
    10  	"fmt"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto"
    17  	"github.com/hyperledger/aries-framework-go/pkg/doc/did"
    18  	vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
    19  	"github.com/hyperledger/aries-framework-go/pkg/internal/test/makemockdoc"
    20  	"github.com/hyperledger/aries-framework-go/pkg/kms"
    21  	"github.com/hyperledger/aries-framework-go/pkg/kms/localkms"
    22  	mockstorage "github.com/hyperledger/aries-framework-go/pkg/mock/storage"
    23  	mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr"
    24  	"github.com/hyperledger/aries-framework-go/pkg/secretlock"
    25  	"github.com/hyperledger/aries-framework-go/pkg/secretlock/noop"
    26  	"github.com/hyperledger/aries-framework-go/pkg/vdr/key"
    27  )
    28  
    29  const (
    30  	defaultKID = "#key-1"
    31  	defaultDID = "did:test:foo"
    32  )
    33  
    34  func TestSignVerify(t *testing.T) {
    35  	keyManager := createKMS(t)
    36  
    37  	cr, e := tinkcrypto.New()
    38  	require.NoError(t, e)
    39  
    40  	staticDIDDocs := map[string]*did.Doc{}
    41  
    42  	defaultVDR := &mockvdr.MockVDRegistry{
    43  		ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
    44  			if strings.HasPrefix(didID, "did:key:") {
    45  				k := key.New()
    46  
    47  				d, err := k.Read(didID)
    48  				if err != nil {
    49  					return nil, err
    50  				}
    51  
    52  				return d, nil
    53  			} else if doc, ok := staticDIDDocs[didID]; ok {
    54  				return &did.DocResolution{DIDDocument: doc}, nil
    55  			}
    56  
    57  			return nil, fmt.Errorf("did not found")
    58  		},
    59  	}
    60  
    61  	doc := makemockdoc.MakeMockDoc(t, keyManager, defaultDID, kms.ECDSAP256TypeIEEEP1363)
    62  	staticDIDDocs[defaultDID] = doc
    63  
    64  	testClaims := map[string]interface{}{
    65  		"foo": "bar",
    66  		"baz": []string{"a", "b", "c"},
    67  	}
    68  
    69  	t.Run("success", func(t *testing.T) {
    70  		t.Run("use specified key", func(t *testing.T) {
    71  			result, err := SignJWT(nil, testClaims, defaultDID+defaultKID, UseDefaultSigner(keyManager, cr), defaultVDR)
    72  			require.NoError(t, err)
    73  			require.NotEmpty(t, result)
    74  
    75  			require.NoError(t, VerifyJWT(result, defaultVDR))
    76  		})
    77  
    78  		t.Run("default to first assertionmethod", func(t *testing.T) {
    79  			result, err := SignJWT(nil, testClaims, defaultDID, UseDefaultSigner(keyManager, cr), defaultVDR)
    80  			require.NoError(t, err)
    81  			require.NotEmpty(t, result)
    82  
    83  			require.NoError(t, VerifyJWT(result, defaultVDR))
    84  		})
    85  
    86  		t.Run("use EdDSA", func(t *testing.T) {
    87  			mockDoc := makemockdoc.MakeMockDoc(t, keyManager, defaultDID, kms.ED25519Type)
    88  
    89  			customVDR := &mockvdr.MockVDRegistry{
    90  				ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
    91  					return &did.DocResolution{DIDDocument: mockDoc}, nil
    92  				},
    93  			}
    94  
    95  			result, err := SignJWT(nil, testClaims, defaultDID+defaultKID, UseDefaultSigner(keyManager, cr), customVDR)
    96  			require.NoError(t, err)
    97  			require.NotEmpty(t, result)
    98  
    99  			require.NoError(t, VerifyJWT(result, customVDR))
   100  		})
   101  	})
   102  
   103  	t.Run("failure", func(t *testing.T) {
   104  		t.Run("invalid verification method ID", func(t *testing.T) {
   105  			_, e = SignJWT(nil, testClaims, "did:foo:bar#keyID#extraKeyID", UseDefaultSigner(keyManager, cr), defaultVDR)
   106  			require.Error(t, e)
   107  			require.Contains(t, e.Error(), "invalid verification method format")
   108  		})
   109  
   110  		t.Run("DID not found in VDR", func(t *testing.T) {
   111  			_, e = SignJWT(nil, testClaims, "did:missing:unknown#keyID", UseDefaultSigner(keyManager, cr), defaultVDR)
   112  			require.Error(t, e)
   113  			require.Contains(t, e.Error(), "failed to resolve signing DID")
   114  		})
   115  
   116  		t.Run("verification method is invalid", func(t *testing.T) {
   117  			brokenDID := "did:broken:doc"
   118  			brokenVMID := "brokenVM"
   119  
   120  			mockDoc := &did.Doc{
   121  				ID: brokenDID,
   122  				VerificationMethod: []did.VerificationMethod{
   123  					{
   124  						ID:   brokenVMID,
   125  						Type: "unsupported type",
   126  					},
   127  				},
   128  			}
   129  
   130  			_, e = SignJWT(nil, testClaims, brokenDID+"#"+brokenVMID, UseDefaultSigner(keyManager, cr),
   131  				&mockvdr.MockVDRegistry{
   132  					ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
   133  						return &did.DocResolution{DIDDocument: mockDoc}, nil
   134  					},
   135  				})
   136  			require.Error(t, e)
   137  			require.Contains(t, e.Error(), "parsing verification method")
   138  		})
   139  
   140  		t.Run("can't get KMS KID", func(t *testing.T) {
   141  			mockDoc := &did.Doc{
   142  				ID: defaultDID,
   143  				VerificationMethod: []did.VerificationMethod{
   144  					{
   145  						ID:   defaultKID,
   146  						Type: ed25519VerificationKey2018,
   147  						// key value is empty, so jwkkid.CreateKID fails
   148  					},
   149  				},
   150  			}
   151  
   152  			_, e = SignJWT(nil, testClaims, defaultDID+defaultKID, UseDefaultSigner(keyManager, cr),
   153  				&mockvdr.MockVDRegistry{
   154  					ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
   155  						return &did.DocResolution{DIDDocument: mockDoc}, nil
   156  					},
   157  				})
   158  			require.Error(t, e)
   159  			require.Contains(t, e.Error(), "determining the internal ID of the signing key")
   160  		})
   161  
   162  		t.Run("key not in KMS", func(t *testing.T) {
   163  			wrongKMS := createKMS(t)
   164  
   165  			// signing key is saved in the wrong kms
   166  			mockDoc := makemockdoc.MakeMockDoc(t, wrongKMS, defaultDID, kms.ECDSAP256TypeIEEEP1363)
   167  
   168  			// instead of the kms passed in here
   169  			_, e = SignJWT(nil, testClaims, defaultDID, UseDefaultSigner(keyManager, cr),
   170  				&mockvdr.MockVDRegistry{
   171  					ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
   172  						return &did.DocResolution{DIDDocument: mockDoc}, nil
   173  					},
   174  				})
   175  			require.Error(t, e)
   176  			require.Contains(t, e.Error(), "fetching the signing key from the key manager")
   177  		})
   178  
   179  		t.Run("signing error", func(t *testing.T) {
   180  			kmgr := createKMS(t)
   181  
   182  			badPayload := map[string]interface{}{
   183  				"foo": new(chan int), // can't marshal
   184  			}
   185  
   186  			mockDoc := makemockdoc.MakeMockDoc(t, kmgr, defaultDID, kms.ECDSAP256TypeIEEEP1363)
   187  
   188  			_, e = SignJWT(nil, badPayload, defaultDID+defaultKID, UseDefaultSigner(kmgr, cr),
   189  				&mockvdr.MockVDRegistry{
   190  					ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
   191  						return &did.DocResolution{DIDDocument: mockDoc}, nil
   192  					},
   193  				})
   194  			require.Error(t, e)
   195  			require.Contains(t, e.Error(), "signing JWT")
   196  		})
   197  
   198  		t.Run("verification error", func(t *testing.T) {
   199  			result, err := SignJWT(nil, testClaims, defaultDID+defaultKID, UseDefaultSigner(keyManager, cr), defaultVDR)
   200  			require.NoError(t, err)
   201  			require.NotEmpty(t, result)
   202  
   203  			err = VerifyJWT(result, &mockvdr.MockVDRegistry{})
   204  			require.Error(t, err)
   205  			require.Contains(t, err.Error(), "jwt verification failed")
   206  		})
   207  	})
   208  }
   209  
   210  func createKMS(t *testing.T) kms.KeyManager {
   211  	kmsStore, err := kms.NewAriesProviderWrapper(mockstorage.NewMockStoreProvider())
   212  	require.NoError(t, err)
   213  
   214  	keyManager, err := localkms.New("local-lock://test/master/key/", &kmsProvider{
   215  		kmsStore:          kmsStore,
   216  		secretLockService: &noop.NoLock{},
   217  	})
   218  	require.NoError(t, err)
   219  
   220  	return keyManager
   221  }
   222  
   223  type kmsProvider struct {
   224  	kmsStore          kms.Store
   225  	secretLockService secretlock.Service
   226  }
   227  
   228  func (k *kmsProvider) StorageProvider() kms.Store {
   229  	return k.kmsStore
   230  }
   231  
   232  func (k *kmsProvider) SecretLock() secretlock.Service {
   233  	return k.secretLockService
   234  }