github.com/trustbloc/kms-go@v1.1.2/crypto/tinkcrypto/unwrap_support_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package tinkcrypto
     8  
     9  import (
    10  	"crypto/ed25519"
    11  	"crypto/elliptic"
    12  	"crypto/rand"
    13  	"testing"
    14  
    15  	"github.com/golang/protobuf/proto"
    16  	"github.com/google/tink/go/aead"
    17  	hybrid "github.com/google/tink/go/hybrid/subtle"
    18  	"github.com/google/tink/go/keyset"
    19  	commonpb "github.com/google/tink/go/proto/common_go_proto"
    20  	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
    21  	"github.com/google/tink/go/subtle/random"
    22  	"github.com/google/tink/go/testkeyset"
    23  	"github.com/google/tink/go/testutil"
    24  	"github.com/stretchr/testify/require"
    25  
    26  	"github.com/trustbloc/kms-go/util/cryptoutil"
    27  
    28  	ecdhpb "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto"
    29  )
    30  
    31  func Test_ExtractPrivKey(t *testing.T) {
    32  	_, err := extractPrivKey(nil)
    33  	require.EqualError(t, err, "extractPrivKey: kh is nil")
    34  
    35  	badKey, err := keyset.NewHandle(aead.AES256GCMKeyTemplate())
    36  	require.NoError(t, err)
    37  
    38  	_, err = extractPrivKey(badKey)
    39  	require.EqualError(t, err, "extractPrivKey: can't extract unsupported private key 'type.googleapis.com/"+
    40  		"google.crypto.tink.AesGcmKey'")
    41  
    42  	require.PanicsWithValue(t, "keyset.Handle: keyset must be non nil", func() {
    43  		_, _ = extractPrivKey(&keyset.Handle{}) //nolint:errcheck // Expected to panic
    44  	})
    45  
    46  	badPrivateKeyProto := generateECDHAEADPrivateKey(t, commonpb.EllipticCurveType_CURVE25519, // <-- invalid EC curve
    47  		ecdhpb.KeyType_EC, aead.AES128GCMKeyTemplate(), random.GetRandomBytes(32))
    48  
    49  	badPrivMarshalledProto, err := proto.Marshal(badPrivateKeyProto)
    50  	require.NoError(t, err)
    51  
    52  	badPrivKey := testutil.NewKey(
    53  		testutil.NewKeyData(nistPECDHKWPrivateKeyTypeURL, badPrivMarshalledProto, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
    54  		tinkpb.KeyStatusType_ENABLED, 15, tinkpb.OutputPrefixType_RAW)
    55  
    56  	privKeys := []*tinkpb.Keyset_Key{badPrivKey}
    57  	privKeyset := testutil.NewKeyset(privKeys[0].KeyId, privKeys)
    58  	khPriv, err := testkeyset.NewHandle(privKeyset)
    59  	require.NoError(t, err)
    60  
    61  	_, err = extractPrivKey(khPriv)
    62  	require.EqualError(t, err, "extractPrivKey: invalid key: unsupported curve")
    63  
    64  	badPrivateKeyProto = generateECDHAEADPrivateKey(t, commonpb.EllipticCurveType_NIST_P256, // <-- invalid OKP curve
    65  		ecdhpb.KeyType_OKP, aead.XChaCha20Poly1305KeyTemplate(),
    66  		random.GetRandomBytes(32))
    67  
    68  	badPrivMarshalledProto, err = proto.Marshal(badPrivateKeyProto)
    69  	require.NoError(t, err)
    70  
    71  	badPrivKey = testutil.NewKey(
    72  		testutil.NewKeyData(x25519ECDHKWPrivateKeyTypeURL, badPrivMarshalledProto, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
    73  		tinkpb.KeyStatusType_ENABLED, 15, tinkpb.OutputPrefixType_RAW)
    74  
    75  	privKeys = []*tinkpb.Keyset_Key{badPrivKey}
    76  	privKeyset = testutil.NewKeyset(privKeys[0].KeyId, privKeys)
    77  	khPriv, err = testkeyset.NewHandle(privKeyset)
    78  	require.NoError(t, err)
    79  
    80  	_, err = extractPrivKey(khPriv)
    81  	require.EqualError(t, err, "extractPrivKey: invalid key curve")
    82  }
    83  
    84  // generateECDHAEADPrivateKey generates a new EC key pair and returns the private key proto.
    85  func generateECDHAEADPrivateKey(t *testing.T, c commonpb.EllipticCurveType, kt ecdhpb.KeyType, encT *tinkpb.KeyTemplate,
    86  	cek []byte) *ecdhpb.EcdhAeadPrivateKey {
    87  	t.Helper()
    88  
    89  	ptfmt := commonpb.EcPointFormat_UNCOMPRESSED
    90  
    91  	if ecdhpb.KeyType_OKP.String() == kt.String() {
    92  		return buildXChachaKey(t, ptfmt, encT, c, cek)
    93  	}
    94  
    95  	// don't set curve from c because we want the wrong c value to be set in the key
    96  	// generate a P-256 key by default
    97  	// curve, err := hybrid.GetCurve(c.String())
    98  	// require.NoError(t, err)
    99  
   100  	pvt, err := hybrid.GenerateECDHKeyPair(elliptic.P256())
   101  	require.NoError(t, err)
   102  
   103  	pubK := ecdhAEADPublicKey(t, c, ptfmt, kt, encT, pvt.PublicKey.Point.X.Bytes(), pvt.PublicKey.Point.Y.Bytes(), cek)
   104  
   105  	return ecdhesAEADPrivateKey(t, pubK, pvt.D.Bytes())
   106  }
   107  
   108  func buildXChachaKey(t *testing.T, ptfmt commonpb.EcPointFormat, encT *tinkpb.KeyTemplate, c commonpb.EllipticCurveType,
   109  	cek []byte) *ecdhpb.EcdhAeadPrivateKey {
   110  	pub, pvt, err := ed25519.GenerateKey(rand.Reader)
   111  	require.NoError(t, err)
   112  
   113  	x25519Pub, err := cryptoutil.PublicEd25519toCurve25519(pub)
   114  	require.NoError(t, err)
   115  
   116  	x25519Pvt, err := cryptoutil.SecretEd25519toCurve25519(pvt)
   117  	require.NoError(t, err)
   118  
   119  	params := &ecdhpb.EcdhAeadParams{
   120  		KwParams: &ecdhpb.EcdhKwParams{
   121  			KeyType:   ecdhpb.KeyType_OKP,
   122  			CurveType: c,
   123  		},
   124  		EncParams: &ecdhpb.EcdhAeadEncParams{
   125  			AeadEnc: encT,
   126  			CEK:     cek,
   127  		},
   128  		EcPointFormat: ptfmt,
   129  	}
   130  
   131  	return &ecdhpb.EcdhAeadPrivateKey{
   132  		Version:  0,
   133  		KeyValue: x25519Pvt,
   134  		PublicKey: &ecdhpb.EcdhAeadPublicKey{
   135  			Version: 0,
   136  			Params:  params,
   137  			X:       x25519Pub,
   138  		},
   139  	}
   140  }
   141  
   142  // ecdhAEADPublicKey returns a EcdhAeadPublicKey with specified parameters.
   143  func ecdhAEADPublicKey(t *testing.T, c commonpb.EllipticCurveType, ptfmt commonpb.EcPointFormat, kt ecdhpb.KeyType,
   144  	encT *tinkpb.KeyTemplate, x, y, cek []byte) *ecdhpb.EcdhAeadPublicKey {
   145  	t.Helper()
   146  
   147  	return &ecdhpb.EcdhAeadPublicKey{
   148  		Version: 0,
   149  		Params: &ecdhpb.EcdhAeadParams{
   150  			KwParams: &ecdhpb.EcdhKwParams{
   151  				CurveType: c,
   152  				KeyType:   kt,
   153  			},
   154  			EncParams: &ecdhpb.EcdhAeadEncParams{
   155  				AeadEnc: encT,
   156  				CEK:     cek,
   157  			},
   158  			EcPointFormat: ptfmt,
   159  		},
   160  		X: x,
   161  		Y: y,
   162  	}
   163  }
   164  
   165  // ecdhesAEADPrivateKey returns a EcdhAeadPrivateKey with specified parameters.
   166  func ecdhesAEADPrivateKey(t *testing.T, p *ecdhpb.EcdhAeadPublicKey, d []byte) *ecdhpb.EcdhAeadPrivateKey {
   167  	t.Helper()
   168  
   169  	return &ecdhpb.EcdhAeadPrivateKey{
   170  		Version:   0,
   171  		PublicKey: p,
   172  		KeyValue:  d,
   173  	}
   174  }
   175  
   176  func TestNoopAEAD_Decrypt(t *testing.T) {
   177  	n := noopAEAD{}
   178  
   179  	plainText, err := n.Decrypt([]byte("test"), nil)
   180  	require.NoError(t, err)
   181  	require.EqualValues(t, "test", plainText)
   182  }
   183  
   184  func TestPrivKeyWriter_Write(t *testing.T) {
   185  	p := privKeyWriter{}
   186  
   187  	err := p.Write(nil)
   188  	require.EqualError(t, err, "privKeyWriter: write function not supported")
   189  }