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  }