github.com/trustbloc/kms-go@v1.1.2/kms/localkms/privkey_import.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 "crypto/ecdsa" 12 "crypto/ed25519" 13 "fmt" 14 15 "github.com/golang/protobuf/proto" 16 "github.com/google/tink/go/keyset" 17 commonpb "github.com/google/tink/go/proto/common_go_proto" 18 ecdsapb "github.com/google/tink/go/proto/ecdsa_go_proto" 19 ed25519pb "github.com/google/tink/go/proto/ed25519_go_proto" 20 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 21 "github.com/trustbloc/bbs-signature-go/bbs12381g2pub" 22 23 "github.com/trustbloc/kms-go/spi/kms" 24 25 "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/composite/ecdh" 26 bbspb "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/proto/bbs_go_proto" 27 clpb "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/proto/cl_go_proto" 28 ecdhpb "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto" 29 secp256k1pb "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/proto/secp256k1_go_proto" 30 ) 31 32 const ( 33 ecdsaSignerTypeURL = "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey" 34 ed25519SignerTypeURL = "type.googleapis.com/google.crypto.tink.Ed25519PrivateKey" 35 bbsSignerKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.BBSPrivateKey" 36 secp256k1SignerTypeURL = "type.googleapis.com/google.crypto.tink.secp256k1PrivateKey" 37 nistpECDHKWPrivateKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.NistPEcdhKwPrivateKey" 38 ) 39 40 //nolint:funlen,gocyclo 41 func (l *LocalKMS) importECDSAKey(privKey *ecdsa.PrivateKey, kt kms.KeyType, 42 opts ...kms.PrivateKeyOpts) (string, *keyset.Handle, error) { 43 var params *ecdsapb.EcdsaParams 44 45 err := validECPrivateKey(privKey) 46 if err != nil { 47 return "", nil, fmt.Errorf("import private EC key failed: %w", err) 48 } 49 50 switch kt { 51 case kms.NISTP256ECDHKWType, kms.NISTP384ECDHKWType, kms.NISTP521ECDHKWType: 52 return l.buildAndImportECDSAPrivateKeyAsECDHKW(privKey, kt, opts...) 53 case kms.ECDSAP256TypeDER: 54 params = &ecdsapb.EcdsaParams{ 55 Curve: commonpb.EllipticCurveType_NIST_P256, 56 Encoding: ecdsapb.EcdsaSignatureEncoding_DER, 57 HashType: commonpb.HashType_SHA256, 58 } 59 case kms.ECDSAP384TypeDER: 60 params = &ecdsapb.EcdsaParams{ 61 Curve: commonpb.EllipticCurveType_NIST_P384, 62 Encoding: ecdsapb.EcdsaSignatureEncoding_DER, 63 HashType: commonpb.HashType_SHA384, 64 } 65 case kms.ECDSAP521TypeDER: 66 params = &ecdsapb.EcdsaParams{ 67 Curve: commonpb.EllipticCurveType_NIST_P521, 68 Encoding: ecdsapb.EcdsaSignatureEncoding_DER, 69 HashType: commonpb.HashType_SHA512, 70 } 71 case kms.ECDSAP256TypeIEEEP1363: 72 params = &ecdsapb.EcdsaParams{ 73 Curve: commonpb.EllipticCurveType_NIST_P256, 74 Encoding: ecdsapb.EcdsaSignatureEncoding_IEEE_P1363, 75 HashType: commonpb.HashType_SHA256, 76 } 77 case kms.ECDSAP384TypeIEEEP1363: 78 params = &ecdsapb.EcdsaParams{ 79 Curve: commonpb.EllipticCurveType_NIST_P384, 80 Encoding: ecdsapb.EcdsaSignatureEncoding_IEEE_P1363, 81 HashType: commonpb.HashType_SHA384, 82 } 83 case kms.ECDSAP521TypeIEEEP1363: 84 params = &ecdsapb.EcdsaParams{ 85 Curve: commonpb.EllipticCurveType_NIST_P521, 86 Encoding: ecdsapb.EcdsaSignatureEncoding_IEEE_P1363, 87 HashType: commonpb.HashType_SHA512, 88 } 89 case kms.ECDSASecp256k1DER: 90 return l.importSecp256K1Key(privKey, &secp256k1pb.Secp256K1Params{ 91 HashType: commonpb.HashType_SHA256, 92 Curve: secp256k1pb.BitcoinCurveType_SECP256K1, 93 Encoding: secp256k1pb.Secp256K1SignatureEncoding_Bitcoin_DER, 94 }) 95 case kms.ECDSASecp256k1IEEEP1363: 96 return l.importSecp256K1Key(privKey, &secp256k1pb.Secp256K1Params{ 97 HashType: commonpb.HashType_SHA256, 98 Curve: secp256k1pb.BitcoinCurveType_SECP256K1, 99 Encoding: secp256k1pb.Secp256K1SignatureEncoding_Bitcoin_IEEE_P1363, 100 }) 101 default: 102 return "", nil, fmt.Errorf("import private EC key failed: invalid ECDSA key type") 103 } 104 105 mKeyValue, err := getMarshalledECDSAPrivateKey(privKey, params) 106 if err != nil { 107 return "", nil, fmt.Errorf("import private EC key failed: %w", err) 108 } 109 110 ks := newKeySet(ecdsaSignerTypeURL, mKeyValue, tinkpb.KeyData_ASYMMETRIC_PRIVATE) 111 112 return l.importKeySet(ks, opts...) 113 } 114 115 func (l *LocalKMS) importSecp256K1Key(privKey *ecdsa.PrivateKey, params *secp256k1pb.Secp256K1Params, 116 opts ...kms.PrivateKeyOpts) (string, *keyset.Handle, error) { 117 mKeyValue, err := getMarshalledECDSASecp256K1PrivateKey(privKey, params) 118 if err != nil { 119 return "", nil, fmt.Errorf("import private EC secp256k1 key failed: %w", err) 120 } 121 122 ks := newKeySet(secp256k1SignerTypeURL, mKeyValue, tinkpb.KeyData_ASYMMETRIC_PRIVATE) 123 124 return l.importKeySet(ks, opts...) 125 } 126 127 func (l *LocalKMS) buildAndImportECDSAPrivateKeyAsECDHKW(privKey *ecdsa.PrivateKey, kt kms.KeyType, 128 opts ...kms.PrivateKeyOpts) (string, *keyset.Handle, error) { 129 var keyTemplate *tinkpb.KeyTemplate 130 131 switch kt { 132 case kms.NISTP256ECDHKWType: 133 keyTemplate = ecdh.NISTP256ECDHKWKeyTemplate() 134 case kms.NISTP384ECDHKWType: 135 keyTemplate = ecdh.NISTP384ECDHKWKeyTemplate() 136 case kms.NISTP521ECDHKWType: 137 keyTemplate = ecdh.NISTP521ECDHKWKeyTemplate() 138 } 139 140 keyFormat := new(ecdhpb.EcdhAeadKeyFormat) 141 142 err := proto.Unmarshal(keyTemplate.Value, keyFormat) 143 if err != nil { 144 return "", nil, fmt.Errorf("invalid key format") 145 } 146 147 priv := &ecdhpb.EcdhAeadPrivateKey{ 148 Version: 0, 149 KeyValue: privKey.D.Bytes(), 150 PublicKey: &ecdhpb.EcdhAeadPublicKey{ 151 Version: 0, 152 Params: keyFormat.Params, 153 X: privKey.PublicKey.X.Bytes(), 154 Y: privKey.PublicKey.Y.Bytes(), 155 }, 156 } 157 158 privBytes, err := proto.Marshal(priv) 159 if err != nil { 160 return "", nil, fmt.Errorf("marshal protobuf: %w", err) 161 } 162 163 ks := newKeySet(nistpECDHKWPrivateKeyTypeURL, privBytes, tinkpb.KeyData_ASYMMETRIC_PRIVATE) 164 165 return l.importKeySet(ks, opts...) 166 } 167 168 func (l *LocalKMS) importKeySet(ks *tinkpb.Keyset, opts ...kms.PrivateKeyOpts) (string, *keyset.Handle, error) { 169 ksID, err := l.writeImportedKey(ks, opts...) 170 if err != nil { 171 return "", nil, fmt.Errorf("import private EC key failed: %w", err) 172 } 173 174 kh, err := l.getKeySet(ksID) 175 if err != nil { 176 return ksID, nil, fmt.Errorf("import private EC key successful but failed to get key from store: %w", err) 177 } 178 179 return ksID, kh, nil 180 } 181 182 func getMarshalledECDSAPrivateKey(privKey *ecdsa.PrivateKey, params *ecdsapb.EcdsaParams) ([]byte, error) { 183 pubKeyProto := newProtoECDSAPublicKey(&privKey.PublicKey, params) 184 return proto.Marshal(newProtoECDSAPrivateKey(pubKeyProto, privKey.D.Bytes())) 185 } 186 187 func getMarshalledECDSASecp256K1PrivateKey(privKey *ecdsa.PrivateKey, 188 params *secp256k1pb.Secp256K1Params) ([]byte, error) { 189 pubKeyProto := newProtoSecp256K1PublicKey(&privKey.PublicKey, params) 190 return proto.Marshal(newProtoECDSASecp256K1PrivateKey(pubKeyProto, privKey.D.Bytes())) 191 } 192 193 func (l *LocalKMS) importEd25519Key(privKey ed25519.PrivateKey, kt kms.KeyType, 194 opts ...kms.PrivateKeyOpts) (string, *keyset.Handle, error) { 195 if privKey == nil { 196 return "", nil, fmt.Errorf("import private ED25519 key failed: private key is nil") 197 } 198 199 if kt != kms.ED25519Type { 200 return "", nil, fmt.Errorf("import private ED25519 key failed: invalid key type") 201 } 202 203 privKeyProto, err := newProtoEd25519PrivateKey(privKey) 204 if err != nil { 205 return "", nil, fmt.Errorf("import private ED25519 key failed: %w", err) 206 } 207 208 mKeyValue, err := proto.Marshal(privKeyProto) 209 if err != nil { 210 return "", nil, fmt.Errorf("import private ED25519 key failed: %w", err) 211 } 212 213 ks := newKeySet(ed25519SignerTypeURL, mKeyValue, tinkpb.KeyData_ASYMMETRIC_PRIVATE) 214 215 return l.importKeySet(ks, opts...) 216 } 217 218 func (l *LocalKMS) importBBSKey(privKey *bbs12381g2pub.PrivateKey, kt kms.KeyType, 219 opts ...kms.PrivateKeyOpts) (string, *keyset.Handle, error) { 220 if privKey == nil { 221 return "", nil, fmt.Errorf("import private BBS+ key failed: private key is nil") 222 } 223 224 if kt != kms.BLS12381G2Type { 225 return "", nil, fmt.Errorf("import private BBS+ key failed: invalid key type") 226 } 227 228 privKeyProto, err := newProtoBBSPrivateKey(privKey, kt) 229 if err != nil { 230 return "", nil, fmt.Errorf("import private BBS+ key failed: %w", err) 231 } 232 233 mKeyValue, err := proto.Marshal(privKeyProto) 234 if err != nil { 235 return "", nil, fmt.Errorf("import private BBS+ key failed: %w", err) 236 } 237 238 ks := newKeySet(bbsSignerKeyTypeURL, mKeyValue, tinkpb.KeyData_ASYMMETRIC_PRIVATE) 239 240 return l.importKeySet(ks, opts...) 241 } 242 243 func validECPrivateKey(privateKey *ecdsa.PrivateKey) error { 244 if privateKey == nil { 245 return fmt.Errorf("private key is nil") 246 } 247 248 if privateKey.X == nil { 249 return fmt.Errorf("private key's public key is missing x coordinate") 250 } 251 252 if privateKey.Y == nil { 253 return fmt.Errorf("private key's public key is missing y coordinate") 254 } 255 256 if privateKey.D == nil { 257 return fmt.Errorf("private key data is missing") 258 } 259 260 return nil 261 } 262 263 // newProtoECDSAPrivateKey creates a ECDSAPrivateKey with the specified parameters. 264 func newProtoECDSAPrivateKey(publicKey *ecdsapb.EcdsaPublicKey, keyValue []byte) *ecdsapb.EcdsaPrivateKey { 265 return &ecdsapb.EcdsaPrivateKey{ 266 Version: 0, 267 PublicKey: publicKey, 268 KeyValue: keyValue, 269 } 270 } 271 272 // newProtoECDSASecp256K1PrivateKey creates a Secp256K1PrivateKey with the specified parameters. 273 func newProtoECDSASecp256K1PrivateKey(publicKey *secp256k1pb.Secp256K1PublicKey, 274 keyValue []byte) *secp256k1pb.Secp256K1PrivateKey { 275 return &secp256k1pb.Secp256K1PrivateKey{ 276 Version: 0, 277 PublicKey: publicKey, 278 KeyValue: keyValue, 279 } 280 } 281 282 func newProtoEd25519PrivateKey(privateKey ed25519.PrivateKey) (*ed25519pb.Ed25519PrivateKey, error) { 283 pubKey, ok := (privateKey.Public()).(ed25519.PublicKey) 284 if !ok { 285 return nil, fmt.Errorf("public key from private key is not ed25519.PublicKey") 286 } 287 288 publicProto := &ed25519pb.Ed25519PublicKey{ 289 Version: 0, 290 KeyValue: pubKey, 291 } 292 293 return &ed25519pb.Ed25519PrivateKey{ 294 Version: 0, 295 PublicKey: publicProto, 296 KeyValue: privateKey.Seed(), 297 }, nil 298 } 299 300 func newProtoBBSPrivateKey(privateKey *bbs12381g2pub.PrivateKey, kt kms.KeyType) (*bbspb.BBSPrivateKey, error) { 301 publicKey := privateKey.PublicKey() 302 303 pubKeyBytes, err := publicKey.Marshal() 304 if err != nil { 305 return nil, err 306 } 307 308 publicProto := &bbspb.BBSPublicKey{ 309 Version: 0, 310 Params: buidBBSParams(kt), 311 KeyValue: pubKeyBytes, 312 } 313 314 privKeyBytes, err := privateKey.Marshal() 315 if err != nil { 316 return nil, err 317 } 318 319 return &bbspb.BBSPrivateKey{ 320 Version: 0, 321 PublicKey: publicProto, 322 KeyValue: privKeyBytes, 323 }, nil 324 } 325 326 func buidBBSParams(kt kms.KeyType) *bbspb.BBSParams { 327 if kt == kms.BLS12381G2Type { 328 return &bbspb.BBSParams{ 329 HashType: commonpb.HashType_SHA256, 330 Curve: bbspb.BBSCurveType_BLS12_381, 331 Group: bbspb.GroupField_G2, 332 } 333 } 334 335 return nil 336 } 337 338 func buidCLCredDefParams(kt kms.KeyType, opts ...kms.KeyOpts) *clpb.CLCredDefParams { 339 if kt == kms.CLCredDefType { 340 keyOpts := kms.NewKeyOpt() 341 342 for _, opt := range opts { 343 opt(keyOpts) 344 } 345 346 return &clpb.CLCredDefParams{ 347 Attrs: keyOpts.Attrs(), 348 } 349 } 350 351 return nil 352 } 353 354 func (l *LocalKMS) writeImportedKey(ks *tinkpb.Keyset, opts ...kms.PrivateKeyOpts) (string, error) { 355 serializedKeyset, err := proto.Marshal(ks) 356 if err != nil { 357 return "", fmt.Errorf("invalid keyset data") 358 } 359 360 encrypted, err := l.primaryKeyEnvAEAD.Encrypt(serializedKeyset, []byte{}) 361 if err != nil { 362 return "", fmt.Errorf("encrypted failed: %w", err) 363 } 364 365 ksInfo, err := getKeysetInfo(ks) 366 if err != nil { 367 return "", fmt.Errorf("cannot get keyset info: %w", err) 368 } 369 370 encryptedKeyset := &tinkpb.EncryptedKeyset{ 371 EncryptedKeyset: encrypted, 372 KeysetInfo: ksInfo, 373 } 374 375 buf := new(bytes.Buffer) 376 jsonKeysetWriter := keyset.NewJSONWriter(buf) 377 378 err = jsonKeysetWriter.WriteEncrypted(encryptedKeyset) 379 if err != nil { 380 return "", fmt.Errorf("failed to write keyset as json: %w", err) 381 } 382 383 return writeToStore(l.store, buf, opts...) 384 } 385 386 func getKeysetInfo(ks *tinkpb.Keyset) (*tinkpb.KeysetInfo, error) { 387 if ks == nil { 388 return nil, fmt.Errorf("keyset is nil") 389 } 390 391 var keyInfos []*tinkpb.KeysetInfo_KeyInfo 392 393 for _, key := range ks.Key { 394 info, err := getKeyInfo(key) 395 if err != nil { 396 return nil, err 397 } 398 399 keyInfos = append(keyInfos, info) 400 } 401 402 return &tinkpb.KeysetInfo{ 403 PrimaryKeyId: ks.PrimaryKeyId, 404 KeyInfo: keyInfos, 405 }, nil 406 } 407 408 func getKeyInfo(key *tinkpb.Keyset_Key) (*tinkpb.KeysetInfo_KeyInfo, error) { 409 if key == nil { 410 return nil, fmt.Errorf("keyset key is nil") 411 } 412 413 return &tinkpb.KeysetInfo_KeyInfo{ 414 TypeUrl: key.KeyData.TypeUrl, 415 Status: key.Status, 416 KeyId: key.KeyId, 417 OutputPrefixType: key.OutputPrefixType, 418 }, nil 419 }