github.com/trustbloc/kms-go@v1.1.2/kms/localkms/privkey_import_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package localkms
     8  
     9  import (
    10  	"crypto/ecdsa"
    11  	"crypto/ed25519"
    12  	"crypto/elliptic"
    13  	"crypto/rand"
    14  	"fmt"
    15  	"math/big"
    16  	"testing"
    17  
    18  	"github.com/golang/mock/gomock"
    19  	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
    20  	"github.com/stretchr/testify/require"
    21  
    22  	"github.com/trustbloc/kms-go/spi/kms"
    23  
    24  	"github.com/trustbloc/kms-go/spi/secretlock"
    25  
    26  	mocksecretlock "github.com/trustbloc/kms-go/mock/secretlock"
    27  	"github.com/trustbloc/kms-go/secretlock/noop"
    28  )
    29  
    30  func TestImportECDSAKeyWithInvalidKey(t *testing.T) {
    31  	k := createKMS(t)
    32  	errPrefix := "import private EC key failed: "
    33  
    34  	_, _, err := k.importECDSAKey(nil, kms.ECDSAP256TypeDER)
    35  	require.EqualError(t, err, errPrefix+"private key is nil")
    36  
    37  	privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    38  	require.NoError(t, err)
    39  
    40  	_, _, err = k.importECDSAKey(privKey, kms.AES128GCM)
    41  	require.EqualError(t, err, errPrefix+"invalid ECDSA key type", "importECDSAKey should fail with "+
    42  		"unsupported key type")
    43  }
    44  
    45  func TestImportEd25519KeyWitnInvalidKey(t *testing.T) {
    46  	k := createKMS(t)
    47  	errPrefix := "import private ED25519 key failed: "
    48  
    49  	_, privKey, err := ed25519.GenerateKey(rand.Reader)
    50  	require.NoError(t, err)
    51  
    52  	_, _, err = k.importEd25519Key(privKey, kms.ECDSAP256TypeDER)
    53  	require.EqualError(t, err, errPrefix+"invalid key type")
    54  
    55  	_, _, err = k.importEd25519Key(nil, kms.ED25519Type)
    56  	require.EqualError(t, err, errPrefix+"private key is nil")
    57  }
    58  
    59  func TestImportKeySetInvalid(t *testing.T) {
    60  	ctrl := gomock.NewController(t)
    61  	defer ctrl.Finish()
    62  
    63  	errPrefix := "import private EC key failed: "
    64  
    65  	flagTests := []struct {
    66  		tcName        string
    67  		kmsProvider   kms.Provider
    68  		ks            *tinkpb.Keyset
    69  		expectedError string
    70  	}{
    71  		{
    72  			tcName: "call importKeySet with nil keyset",
    73  			kmsProvider: &mockProvider{
    74  				storage: newInMemoryKMSStore(),
    75  				secretLock: &mocksecretlock.MockSecretLock{
    76  					ValEncrypt: "",
    77  					ValDecrypt: "",
    78  				},
    79  			},
    80  			expectedError: errPrefix + "invalid keyset data",
    81  		},
    82  		{
    83  			tcName: "call importKeySet with bad secretLock Encrypt",
    84  			kmsProvider: &mockProvider{
    85  				storage: newInMemoryKMSStore(),
    86  				secretLock: &mocksecretlock.MockSecretLock{
    87  					ValEncrypt: "",
    88  					ErrEncrypt: fmt.Errorf("bad encryption"),
    89  					ValDecrypt: "",
    90  				},
    91  			},
    92  			expectedError: errPrefix + "encrypted failed: bad encryption",
    93  			ks: &tinkpb.Keyset{
    94  				PrimaryKeyId: 1,
    95  				Key:          nil,
    96  			},
    97  		},
    98  		{
    99  			tcName: "call importKeySet with bad storage getKeySet call",
   100  			kmsProvider: &goMockProvider{
   101  				storage: newInMemoryKMSStore(),
   102  				secretLock: &mocksecretlock.MockSecretLock{
   103  					ValEncrypt: "",
   104  					ValDecrypt: "",
   105  				},
   106  			},
   107  			expectedError: "import private EC key successful but failed to get key from store:",
   108  			ks: &tinkpb.Keyset{
   109  				PrimaryKeyId: 1,
   110  				Key:          nil,
   111  			},
   112  		},
   113  	}
   114  
   115  	for _, tt := range flagTests {
   116  		tc := tt
   117  		t.Run(tc.tcName, func(t *testing.T) {
   118  			k, err := New(testMasterKeyURI, tc.kmsProvider)
   119  			require.NoError(t, err)
   120  
   121  			_, _, err = k.importKeySet(tc.ks)
   122  			if tc.tcName == "call importKeySet with bad storage getKeySet call" {
   123  				require.Contains(t, err.Error(), tc.expectedError)
   124  				return
   125  			}
   126  
   127  			require.EqualError(t, err, tc.expectedError)
   128  		})
   129  	}
   130  }
   131  
   132  func TestGetKeysetInfoInvalid(t *testing.T) {
   133  	_, err := getKeysetInfo(nil)
   134  	require.EqualError(t, err, "keyset is nil")
   135  
   136  	_, err = getKeysetInfo(&tinkpb.Keyset{
   137  		PrimaryKeyId: 1,
   138  		Key:          []*tinkpb.Keyset_Key{nil},
   139  	})
   140  	require.EqualError(t, err, "keyset key is nil")
   141  }
   142  
   143  func TestValidECPrivateKey(t *testing.T) {
   144  	err := validECPrivateKey(&ecdsa.PrivateKey{})
   145  	require.EqualError(t, err, "private key's public key is missing x coordinate")
   146  
   147  	err = validECPrivateKey(&ecdsa.PrivateKey{
   148  		PublicKey: ecdsa.PublicKey{
   149  			X: new(big.Int),
   150  		},
   151  	})
   152  	require.EqualError(t, err, "private key's public key is missing y coordinate")
   153  
   154  	err = validECPrivateKey(&ecdsa.PrivateKey{
   155  		PublicKey: ecdsa.PublicKey{
   156  			X: new(big.Int),
   157  			Y: new(big.Int),
   158  		},
   159  	})
   160  	require.EqualError(t, err, "private key data is missing")
   161  
   162  	err = validECPrivateKey(&ecdsa.PrivateKey{
   163  		PublicKey: ecdsa.PublicKey{
   164  			X: new(big.Int),
   165  			Y: new(big.Int),
   166  		},
   167  		D: new(big.Int),
   168  	},
   169  	)
   170  	require.NoError(t, err)
   171  }
   172  
   173  func createKMS(t *testing.T) *LocalKMS {
   174  	t.Helper()
   175  
   176  	p := &mockProvider{
   177  		storage:    newInMemoryKMSStore(),
   178  		secretLock: &noop.NoLock{},
   179  	}
   180  
   181  	k, err := New(testMasterKeyURI, p)
   182  	require.NoError(t, err)
   183  
   184  	return k
   185  }
   186  
   187  // mockProvider mocks a provider for KMS storage.
   188  type goMockProvider struct {
   189  	storage    kms.Store
   190  	secretLock secretlock.Service
   191  }
   192  
   193  func (m *goMockProvider) StorageProvider() kms.Store {
   194  	return m.storage
   195  }
   196  
   197  func (m *goMockProvider) SecretLock() secretlock.Service {
   198  	return m.secretLock
   199  }