github.com/trustbloc/kms-go@v1.1.2/kms/localkms/pubkey_export_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 "bytes" 11 "testing" 12 13 "github.com/google/tink/go/aead" 14 "github.com/google/tink/go/hybrid" 15 "github.com/google/tink/go/keyset" 16 commonpb "github.com/google/tink/go/proto/common_go_proto" 17 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 18 "github.com/google/tink/go/signature" 19 "github.com/stretchr/testify/require" 20 21 "github.com/trustbloc/kms-go/spi/kms" 22 23 "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/bbs" 24 ) 25 26 func TestPubKeyExportAndRead(t *testing.T) { 27 p256DERTemplate, err := getKeyTemplate(kms.ECDSAP256TypeDER) 28 require.NoError(t, err) 29 30 p384DERTemplate, err := getKeyTemplate(kms.ECDSAP384TypeDER) 31 require.NoError(t, err) 32 33 p521DERTemplate, err := getKeyTemplate(kms.ECDSAP521TypeDER) 34 require.NoError(t, err) 35 36 flagTests := []struct { 37 tcName string 38 keyType kms.KeyType 39 keyTemplate *tinkpb.KeyTemplate 40 doSign bool 41 }{ 42 { 43 tcName: "export then read ECDSAP256DER public key", 44 keyType: kms.ECDSAP256TypeDER, 45 keyTemplate: p256DERTemplate, 46 doSign: true, 47 }, 48 { 49 tcName: "export then read ECDSAP384DER public key", 50 keyType: kms.ECDSAP384TypeDER, 51 keyTemplate: p384DERTemplate, 52 doSign: true, 53 }, 54 { 55 tcName: "export then read ECDSAP521DER public key", 56 keyType: kms.ECDSAP521TypeDER, 57 keyTemplate: p521DERTemplate, 58 doSign: true, 59 }, 60 { 61 tcName: "export then read ECDSAP256IEEEP1363 public key", 62 keyType: kms.ECDSAP256TypeIEEEP1363, 63 keyTemplate: createECDSAIEEE1363KeyTemplate(commonpb.HashType_SHA256, commonpb.EllipticCurveType_NIST_P256), 64 doSign: true, 65 }, 66 { 67 tcName: "export then read ECDSAP384IEEEP1363 public key", 68 keyType: kms.ECDSAP384TypeIEEEP1363, 69 keyTemplate: createECDSAIEEE1363KeyTemplate(commonpb.HashType_SHA384, commonpb.EllipticCurveType_NIST_P384), 70 doSign: true, 71 }, 72 { 73 tcName: "export then read ECDSAP521IEEEP1363 public key", 74 keyType: kms.ECDSAP521TypeIEEEP1363, 75 keyTemplate: createECDSAIEEE1363KeyTemplate(commonpb.HashType_SHA512, commonpb.EllipticCurveType_NIST_P521), 76 doSign: true, 77 }, 78 { 79 tcName: "export then read ED25519 public key", 80 keyType: kms.ED25519Type, 81 keyTemplate: signature.ED25519KeyWithoutPrefixTemplate(), 82 doSign: true, 83 }, 84 { 85 tcName: "export then read BBS+ BLS12381G2 public key", 86 keyType: kms.BLS12381G2Type, 87 keyTemplate: bbs.BLS12381G2KeyTemplate(), 88 doSign: true, 89 }, 90 } 91 92 for _, tc := range flagTests { 93 tt := tc 94 t.Run(tt.tcName, func(t *testing.T) { 95 exportedKeyBytes, origKH := exportRawPublicKeyBytes(t, tt.keyTemplate, false) 96 97 kh, err := PublicKeyBytesToHandle(exportedKeyBytes, tt.keyType) 98 require.NoError(t, err) 99 require.NotEmpty(t, kh) 100 101 if tt.doSign { 102 if tt.keyType == kms.BLS12381G2Type { 103 msg1 := []byte("Lorem ipsum dolor sit amet,") 104 msg2 := []byte("consectetur adipiscing elit.") 105 msg := [][]byte{msg1, msg2} 106 signer, err := bbs.NewSigner(origKH) 107 require.NoError(t, err) 108 require.NotEmpty(t, signer) 109 110 s, err := signer.Sign(msg) 111 require.NoError(t, err) 112 require.NotEmpty(t, s) 113 114 verifier, err := bbs.NewVerifier(kh) 115 require.NoError(t, err) 116 require.NotEmpty(t, verifier) 117 118 err = verifier.Verify(msg, s) 119 require.NoError(t, err) 120 121 nonce := []byte("somenonce") 122 proof, err := verifier.DeriveProof(msg, s, nonce, []int{1}) 123 require.NoError(t, err) 124 require.NotEmpty(t, proof) 125 126 err = verifier.VerifyProof([][]byte{msg2}, proof, nonce) 127 require.NoError(t, err) 128 129 return 130 } 131 // test signing with origKH then verifying with kh read from exported public key 132 msg := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit.") 133 signer, err := signature.NewSigner(origKH) 134 require.NoError(t, err) 135 require.NotEmpty(t, signer) 136 137 s, err := signer.Sign(msg) 138 require.NoError(t, err) 139 require.NotEmpty(t, s) 140 141 verifier, err := signature.NewVerifier(kh) 142 require.NoError(t, err) 143 require.NotEmpty(t, verifier) 144 145 err = verifier.Verify(s, msg) 146 require.NoError(t, err) 147 } 148 }) 149 } 150 } 151 152 func exportRawPublicKeyBytes(t *testing.T, keyTemplate *tinkpb.KeyTemplate, expectError bool) ([]byte, *keyset.Handle) { 153 t.Helper() 154 155 kh, err := keyset.NewHandle(keyTemplate) 156 require.NoError(t, err) 157 require.NotEmpty(t, kh) 158 159 pubKH, err := kh.Public() 160 require.NoError(t, err) 161 require.NotEmpty(t, pubKH) 162 163 buf := new(bytes.Buffer) 164 pubKeyWriter := NewWriter(buf) 165 require.NotEmpty(t, pubKeyWriter) 166 167 err = pubKH.WriteWithNoSecrets(pubKeyWriter) 168 169 if expectError { 170 require.Error(t, err) 171 return nil, kh 172 } 173 174 require.NoError(t, err) 175 require.NotEmpty(t, buf.Bytes()) 176 177 return buf.Bytes(), kh 178 } 179 180 func TestNegativeCases(t *testing.T) { 181 t.Run("test publicKeyBytesToHandle with empty pubKey", func(t *testing.T) { 182 kh, err := PublicKeyBytesToHandle([]byte{}, kms.ECDSAP256TypeIEEEP1363) 183 require.EqualError(t, err, "pubKey is empty") 184 require.Empty(t, kh) 185 }) 186 187 t.Run("test publicKeyBytesToHandle with empty KeyType", func(t *testing.T) { 188 kh, err := PublicKeyBytesToHandle([]byte{1}, "") 189 require.EqualError(t, err, "error getting marshalled proto key: invalid key type") 190 require.Empty(t, kh) 191 }) 192 193 t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP256TypeDER", func(t *testing.T) { 194 kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP256TypeDER) 195 require.EqualError(t, err, "error getting marshalled proto key: asn1: syntax error: truncated tag or length") 196 require.Empty(t, kh) 197 }) 198 199 t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP256TypeIEEEP1363", func(t *testing.T) { 200 kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP256TypeIEEEP1363) 201 require.EqualError(t, err, "error getting marshalled proto key: failed to unamrshal public ecdsa key") 202 require.Empty(t, kh) 203 }) 204 205 t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP384TypeDER", func(t *testing.T) { 206 kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP384TypeDER) 207 require.EqualError(t, err, "error getting marshalled proto key: asn1: syntax error: truncated tag or length") 208 require.Empty(t, kh) 209 }) 210 211 t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP384TypeIEEEP1363", func(t *testing.T) { 212 kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP384TypeIEEEP1363) 213 require.EqualError(t, err, "error getting marshalled proto key: failed to unamrshal public ecdsa key") 214 require.Empty(t, kh) 215 }) 216 217 t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP521TypeDER", func(t *testing.T) { 218 kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP521TypeDER) 219 require.EqualError(t, err, "error getting marshalled proto key: asn1: syntax error: truncated tag or length") 220 require.Empty(t, kh) 221 }) 222 223 t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP521TypeIEEEP1363", func(t *testing.T) { 224 kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP521TypeIEEEP1363) 225 require.EqualError(t, err, "error getting marshalled proto key: failed to unamrshal public ecdsa key") 226 require.Empty(t, kh) 227 }) 228 229 t.Run("test getMarshalledECDSAKey with empty curveName", func(t *testing.T) { 230 kh, err := getMarshalledECDSADERKey([]byte{}, 231 "", 232 commonpb.EllipticCurveType_NIST_P521, 233 commonpb.HashType_SHA512) 234 require.EqualError(t, err, "undefined curve") 235 require.Empty(t, kh) 236 }) 237 238 t.Run("test getMarshalledECDSAKey with empty curveName", func(t *testing.T) { 239 kh, err := getMarshalledECDSAIEEEP1363Key([]byte{}, 240 "", 241 commonpb.EllipticCurveType_NIST_P521, 242 commonpb.HashType_SHA512) 243 require.EqualError(t, err, "undefined curve") 244 require.Empty(t, kh) 245 }) 246 247 t.Run("test exportRawPublicKeyBytes with an unsupported key template", func(t *testing.T) { 248 exportedKeyBytes, _ := exportRawPublicKeyBytes(t, hybrid.ECIESHKDFAES128GCMKeyTemplate(), true) 249 require.Empty(t, exportedKeyBytes) 250 }) 251 252 t.Run("test export with symmetric key should fail", func(t *testing.T) { 253 kt := aead.AES256GCMKeyTemplate() 254 kh, err := keyset.NewHandle(kt) 255 require.NoError(t, err) 256 require.NotEmpty(t, kh) 257 258 buf := new(bytes.Buffer) 259 pubKeyWriter := NewWriter(buf) 260 require.NotEmpty(t, pubKeyWriter) 261 262 err = kh.Write(pubKeyWriter, &NoLockMock{}) 263 require.Error(t, err) 264 require.Empty(t, buf.Bytes()) 265 }) 266 } 267 268 // NoLockMock is a mock lock service that does no encryption/decryption of plaintext and implements tink.AEAD interface. 269 type NoLockMock struct{} 270 271 // Encrypt is a mock function of AEAD.Encrypt(). 272 func (s *NoLockMock) Encrypt(pt, aad []byte) ([]byte, error) { 273 return pt, nil 274 } 275 276 // Decrypt is a mock function of AEAD.Decrypt(). 277 func (s *NoLockMock) Decrypt(req, aad []byte) ([]byte, error) { 278 return req, nil 279 }