github.com/trustbloc/kms-go@v1.1.2/kms/localkms/pubkey_reader.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/elliptic" 12 "crypto/x509" 13 "fmt" 14 15 "github.com/golang/protobuf/proto" 16 "github.com/google/tink/go/insecurecleartextkeyset" 17 "github.com/google/tink/go/keyset" 18 commonpb "github.com/google/tink/go/proto/common_go_proto" 19 ecdsapb "github.com/google/tink/go/proto/ecdsa_go_proto" 20 ed25519pb "github.com/google/tink/go/proto/ed25519_go_proto" 21 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 22 "github.com/google/tink/go/subtle" 23 24 "github.com/trustbloc/kms-go/spi/kms" 25 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 secp256k1pb "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/proto/secp256k1_go_proto" 29 secp256k1subtle "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/secp256k1/subtle" 30 ) 31 32 // PublicKeyBytesToHandle will create and return a key handle for pubKey of type kt 33 // it returns an error if it failed creating the key handle 34 // Note: The key handle created is not stored in the KMS, it's only useful to execute the crypto primitive 35 // associated with it. 36 func PublicKeyBytesToHandle(pubKey []byte, kt kms.KeyType, opts ...kms.KeyOpts) (*keyset.Handle, error) { 37 if len(pubKey) == 0 { 38 return nil, fmt.Errorf("pubKey is empty") 39 } 40 41 marshalledKey, tURL, err := getMarshalledProtoKeyAndKeyURL(pubKey, kt, opts...) 42 if err != nil { 43 return nil, fmt.Errorf("error getting marshalled proto key: %w", err) 44 } 45 46 ks := newKeySet(tURL, marshalledKey, tinkpb.KeyData_ASYMMETRIC_PUBLIC) 47 48 memReader := &keyset.MemReaderWriter{Keyset: ks} 49 50 parsedHandle, err := insecurecleartextkeyset.Read(memReader) 51 if err != nil { 52 return nil, fmt.Errorf("failed to create key handle: %w", err) 53 } 54 55 return parsedHandle, nil 56 } 57 58 func newKeySet(tURL string, marshalledKey []byte, keyMaterialType tinkpb.KeyData_KeyMaterialType) *tinkpb.Keyset { 59 keyData := &tinkpb.KeyData{ 60 TypeUrl: tURL, 61 Value: marshalledKey, 62 KeyMaterialType: keyMaterialType, 63 } 64 65 return &tinkpb.Keyset{ 66 Key: []*tinkpb.Keyset_Key{ 67 { 68 KeyData: keyData, 69 Status: tinkpb.KeyStatusType_ENABLED, 70 KeyId: 1, 71 // since we're building the key from raw key bytes, then must use raw key prefix type 72 OutputPrefixType: tinkpb.OutputPrefixType_RAW, 73 }, 74 }, 75 PrimaryKeyId: 1, 76 } 77 } 78 79 //nolint:funlen,gocyclo 80 func getMarshalledProtoKeyAndKeyURL(pubKey []byte, kt kms.KeyType, 81 opts ...kms.KeyOpts) ([]byte, string, error) { 82 var ( 83 tURL string 84 keyValue []byte 85 err error 86 ) 87 88 switch kt { 89 case kms.ECDSAP256TypeDER: 90 tURL = ecdsaVerifierTypeURL 91 92 keyValue, err = getMarshalledECDSADERKey( 93 pubKey, 94 "NIST_P256", 95 commonpb.EllipticCurveType_NIST_P256, 96 commonpb.HashType_SHA256) 97 if err != nil { 98 return nil, "", err 99 } 100 case kms.ECDSAP384TypeDER: 101 tURL = ecdsaVerifierTypeURL 102 103 keyValue, err = getMarshalledECDSADERKey( 104 pubKey, 105 "NIST_P384", 106 commonpb.EllipticCurveType_NIST_P384, 107 commonpb.HashType_SHA384) 108 if err != nil { 109 return nil, "", err 110 } 111 case kms.ECDSAP521TypeDER: 112 tURL = ecdsaVerifierTypeURL 113 114 keyValue, err = getMarshalledECDSADERKey( 115 pubKey, 116 "NIST_P521", 117 commonpb.EllipticCurveType_NIST_P521, 118 commonpb.HashType_SHA512) 119 if err != nil { 120 return nil, "", err 121 } 122 case kms.ECDSAP256TypeIEEEP1363: 123 tURL = ecdsaVerifierTypeURL 124 125 keyValue, err = getMarshalledECDSAIEEEP1363Key( 126 pubKey, 127 "NIST_P256", 128 commonpb.EllipticCurveType_NIST_P256, 129 commonpb.HashType_SHA256) 130 if err != nil { 131 return nil, "", err 132 } 133 case kms.ECDSAP384TypeIEEEP1363: 134 tURL = ecdsaVerifierTypeURL 135 136 keyValue, err = getMarshalledECDSAIEEEP1363Key( 137 pubKey, 138 "NIST_P384", 139 commonpb.EllipticCurveType_NIST_P384, 140 commonpb.HashType_SHA384) 141 if err != nil { 142 return nil, "", err 143 } 144 case kms.ECDSAP521TypeIEEEP1363: 145 tURL = ecdsaVerifierTypeURL 146 147 keyValue, err = getMarshalledECDSAIEEEP1363Key( 148 pubKey, 149 "NIST_P521", 150 commonpb.EllipticCurveType_NIST_P521, 151 commonpb.HashType_SHA512) 152 if err != nil { 153 return nil, "", err 154 } 155 case kms.ED25519Type: 156 tURL = ed25519VerifierTypeURL 157 pubKeyProto := new(ed25519pb.Ed25519PublicKey) 158 pubKeyProto.Version = 0 159 pubKeyProto.KeyValue = make([]byte, len(pubKey)) 160 copy(pubKeyProto.KeyValue, pubKey) 161 162 keyValue, err = proto.Marshal(pubKeyProto) 163 if err != nil { 164 return nil, "", err 165 } 166 case kms.BLS12381G2Type: 167 tURL = bbsVerifierKeyTypeURL 168 pubKeyProto := new(bbspb.BBSPublicKey) 169 pubKeyProto.Version = 0 170 pubKeyProto.Params = buidBBSParams(kt) 171 pubKeyProto.KeyValue = make([]byte, len(pubKey)) 172 copy(pubKeyProto.KeyValue, pubKey) 173 174 keyValue, err = proto.Marshal(pubKeyProto) 175 if err != nil { 176 return nil, "", err 177 } 178 case kms.CLCredDefType: 179 tURL = clCredDefKeyTypeURL 180 pubKeyProto := new(clpb.CLCredDefPublicKey) 181 pubKeyProto.Version = 0 182 pubKeyProto.Params = buidCLCredDefParams(kt, opts...) 183 pubKeyProto.KeyValue = make([]byte, len(pubKey)) 184 copy(pubKeyProto.KeyValue, pubKey) 185 186 keyValue, err = proto.Marshal(pubKeyProto) 187 if err != nil { 188 return nil, "", err 189 } 190 case kms.ECDSASecp256k1DER: 191 tURL = secp256k1VerifierTypeURL 192 193 keyValue, err = getMarshalledECDSASecp256K1DERKey( 194 pubKey, 195 "SECP256K1", 196 secp256k1pb.BitcoinCurveType_SECP256K1, 197 commonpb.HashType_SHA256) 198 if err != nil { 199 return nil, "", err 200 } 201 case kms.ECDSASecp256k1IEEEP1363: 202 tURL = secp256k1VerifierTypeURL 203 204 keyValue, err = getMarshalledECDSASecp256K1IEEEP1363Key( 205 pubKey, 206 "SECP256K1", 207 secp256k1pb.BitcoinCurveType_SECP256K1, 208 commonpb.HashType_SHA256) 209 if err != nil { 210 return nil, "", err 211 } 212 default: 213 return nil, "", fmt.Errorf("invalid key type") 214 } 215 216 return keyValue, tURL, nil 217 } 218 219 func getMarshalledECDSADERKey(marshaledPubKey []byte, curveName string, c commonpb.EllipticCurveType, 220 h commonpb.HashType) ([]byte, error) { 221 curve := subtle.GetCurve(curveName) 222 if curve == nil { 223 return nil, fmt.Errorf("undefined curve") 224 } 225 226 pubKey, err := x509.ParsePKIXPublicKey(marshaledPubKey) 227 if err != nil { 228 return nil, err 229 } 230 231 ecPubKey, ok := pubKey.(*ecdsa.PublicKey) 232 if !ok { 233 return nil, fmt.Errorf("public key reader: not an ecdsa public key") 234 } 235 236 params := &ecdsapb.EcdsaParams{ 237 Curve: c, 238 Encoding: ecdsapb.EcdsaSignatureEncoding_DER, 239 HashType: h, 240 } 241 242 return getMarshalledECDSAKey(ecPubKey, params) 243 } 244 245 func getMarshalledECDSASecp256K1DERKey(marshaledPubKey []byte, curveName string, c secp256k1pb.BitcoinCurveType, 246 h commonpb.HashType) ([]byte, error) { 247 curve := secp256k1subtle.GetCurve(curveName) 248 if curve == nil { 249 return nil, fmt.Errorf("undefined curve") 250 } 251 252 pubKey, err := x509.ParsePKIXPublicKey(marshaledPubKey) 253 if err != nil { 254 return nil, err 255 } 256 257 ecPubKey, ok := pubKey.(*ecdsa.PublicKey) 258 if !ok { 259 return nil, fmt.Errorf("public key reader: not an ecdsa public key") 260 } 261 262 params := &secp256k1pb.Secp256K1Params{ 263 Curve: c, 264 Encoding: secp256k1pb.Secp256K1SignatureEncoding_Bitcoin_DER, 265 HashType: h, 266 } 267 268 return getMarshalledSecp256Key(ecPubKey, params) 269 } 270 271 func getMarshalledECDSAIEEEP1363Key(marshaledPubKey []byte, curveName string, c commonpb.EllipticCurveType, 272 h commonpb.HashType) ([]byte, error) { 273 curve := subtle.GetCurve(curveName) 274 if curve == nil { 275 return nil, fmt.Errorf("undefined curve") 276 } 277 278 x, y := elliptic.Unmarshal(curve, marshaledPubKey) 279 280 if x == nil || y == nil { 281 return nil, fmt.Errorf("failed to unamrshal public ecdsa key") 282 } 283 284 params := &ecdsapb.EcdsaParams{ 285 Curve: c, 286 Encoding: ecdsapb.EcdsaSignatureEncoding_IEEE_P1363, 287 HashType: h, 288 } 289 290 return getMarshalledECDSAKey(&ecdsa.PublicKey{X: x, Y: y, Curve: curve}, params) 291 } 292 293 func getMarshalledECDSASecp256K1IEEEP1363Key(marshaledPubKey []byte, curveName string, c secp256k1pb.BitcoinCurveType, 294 h commonpb.HashType) ([]byte, error) { 295 curve := secp256k1subtle.GetCurve(curveName) 296 if curve == nil { 297 return nil, fmt.Errorf("undefined curve") 298 } 299 300 x, y := elliptic.Unmarshal(curve, marshaledPubKey) 301 302 if x == nil || y == nil { 303 return nil, fmt.Errorf("failed to unamrshal public ecdsa key") 304 } 305 306 params := &secp256k1pb.Secp256K1Params{ 307 Curve: c, 308 Encoding: secp256k1pb.Secp256K1SignatureEncoding_Bitcoin_IEEE_P1363, 309 HashType: h, 310 } 311 312 return getMarshalledSecp256Key(&ecdsa.PublicKey{X: x, Y: y, Curve: curve}, params) 313 } 314 315 func getMarshalledECDSAKey(ecPubKey *ecdsa.PublicKey, params *ecdsapb.EcdsaParams) ([]byte, error) { 316 return proto.Marshal(newProtoECDSAPublicKey(ecPubKey, params)) 317 } 318 319 func getMarshalledSecp256Key(ecPubKey *ecdsa.PublicKey, params *secp256k1pb.Secp256K1Params) ([]byte, error) { 320 return proto.Marshal(newProtoSecp256K1PublicKey(ecPubKey, params)) 321 } 322 323 func newProtoECDSAPublicKey(ecPubKey *ecdsa.PublicKey, params *ecdsapb.EcdsaParams) *ecdsapb.EcdsaPublicKey { 324 return &ecdsapb.EcdsaPublicKey{ 325 Version: 0, 326 X: ecPubKey.X.Bytes(), 327 Y: ecPubKey.Y.Bytes(), 328 Params: params, 329 } 330 } 331 332 func newProtoSecp256K1PublicKey(ecPubKey *ecdsa.PublicKey, 333 params *secp256k1pb.Secp256K1Params) *secp256k1pb.Secp256K1PublicKey { 334 return &secp256k1pb.Secp256K1PublicKey{ 335 Version: 0, 336 X: ecPubKey.X.Bytes(), 337 Y: ecPubKey.Y.Bytes(), 338 Params: params, 339 } 340 }