github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/crypto/tencentcloudkms/kms.go (about)

     1  /*
     2  Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package tencentcloudkms
     8  
     9  import (
    10  	"fmt"
    11  
    12  	bccrypto "chainmaker.org/chainmaker/common/v2/crypto"
    13  	"chainmaker.org/chainmaker/common/v2/crypto/asym"
    14  	"chainmaker.org/chainmaker/common/v2/json"
    15  	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
    16  	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
    17  	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
    18  	kms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms/v20190118"
    19  )
    20  
    21  const (
    22  	MODE_DIGEST = "DIGEST"
    23  	MODE_RAW    = "RAW"
    24  
    25  	KEY_TYPE_SM2_SIGNATURE = "ASYMMETRIC_SIGN_VERIFY_SM2"
    26  
    27  	ALGORITHM_TYPE_SM2_SIGNATURE = "SM2DSA"
    28  )
    29  
    30  var keyTypeMap = map[string]string{
    31  	bccrypto.CRYPTO_ALGO_SM2: KEY_TYPE_SM2_SIGNATURE,
    32  }
    33  
    34  var keyTypeList = map[string]string{
    35  	KEY_TYPE_SM2_SIGNATURE: KEY_TYPE_SM2_SIGNATURE,
    36  }
    37  
    38  var algorithmTypeMap = map[string]string{
    39  	bccrypto.CRYPTO_ALGO_SM2: ALGORITHM_TYPE_SM2_SIGNATURE,
    40  }
    41  
    42  var algorithmTypeList = map[string]string{
    43  	ALGORITHM_TYPE_SM2_SIGNATURE: ALGORITHM_TYPE_SM2_SIGNATURE,
    44  }
    45  
    46  type KMSConfig struct {
    47  	SecretId      string
    48  	SecretKey     string
    49  	ServerAddress string
    50  	ServerRegion  string
    51  }
    52  
    53  type KMSPrivateKeyConfig struct {
    54  	KeyType  string
    55  	KeyId    string
    56  	KeyAlias string
    57  }
    58  
    59  func CreateConnection(kmsConfig *KMSConfig) (*kms.Client, error) {
    60  	credential := common.NewCredential(
    61  		kmsConfig.SecretId,
    62  		kmsConfig.SecretKey,
    63  	)
    64  	cpf := profile.NewClientProfile()
    65  	cpf.HttpProfile.Endpoint = kmsConfig.ServerAddress
    66  	return kms.NewClient(credential, kmsConfig.ServerRegion, cpf)
    67  }
    68  
    69  func ExportPublicKeyFromKMS(keyId string, client *kms.Client) (bccrypto.PublicKey, error) {
    70  	request := kms.NewGetPublicKeyRequest()
    71  
    72  	request.KeyId = common.StringPtr(keyId)
    73  
    74  	response, err := client.GetPublicKey(request)
    75  	if _, ok := err.(*errors.TencentCloudSDKError); ok {
    76  		return nil, fmt.Errorf("KMS API error: %s", err)
    77  	}
    78  	if err != nil {
    79  		return nil, fmt.Errorf("KMS error: %v", err)
    80  	}
    81  
    82  	return asym.PublicKeyFromPEM([]byte(*(response.Response.PublicKeyPem)))
    83  }
    84  
    85  func GenerateKeyPairFromKMS(client *kms.Client, keyAlias, keyType string) (bccrypto.PrivateKey, error) {
    86  	keyTypeKMS, ok := keyTypeList[keyType]
    87  	if !ok {
    88  		keyTypeKMS, ok = keyTypeMap[keyType]
    89  		if !ok {
    90  			return nil, fmt.Errorf("KMS error: unsupported algorithm")
    91  		}
    92  	}
    93  
    94  	algorithmTypeKMS, ok := algorithmTypeList[keyType]
    95  	if !ok {
    96  		algorithmTypeKMS, ok = algorithmTypeMap[keyType]
    97  		if !ok {
    98  			return nil, fmt.Errorf("KMS error: unsupported algorithm")
    99  		}
   100  	}
   101  
   102  	request := kms.NewCreateKeyRequest()
   103  
   104  	request.Alias = common.StringPtr(keyAlias)
   105  	request.KeyUsage = common.StringPtr(keyTypeKMS)
   106  	request.Type = common.Uint64Ptr(1)
   107  
   108  	response, err := client.CreateKey(request)
   109  	if _, ok := err.(*errors.TencentCloudSDKError); ok {
   110  		return nil, fmt.Errorf("KMS API error: %s", err)
   111  	}
   112  	if err != nil {
   113  		return nil, fmt.Errorf("KMS error: %v", err)
   114  	}
   115  
   116  	keyId := *(response.Response.KeyId)
   117  	pk, err := ExportPublicKeyFromKMS(keyId, client)
   118  	if err != nil {
   119  		return nil, err
   120  	}
   121  
   122  	sk := &PrivateKey{
   123  		kms:      client,
   124  		keyType:  algorithmTypeKMS,
   125  		keyId:    keyId,
   126  		keyAlias: keyAlias,
   127  		pubKey:   pk,
   128  	}
   129  	return sk, nil
   130  }
   131  
   132  func NewPrivateKey(client *kms.Client, keyConfig *KMSPrivateKeyConfig) (bccrypto.PrivateKey, error) {
   133  	keyTypeKMS, ok := algorithmTypeList[keyConfig.KeyType]
   134  	if !ok {
   135  		keyTypeKMS, ok = algorithmTypeMap[keyConfig.KeyType]
   136  		if !ok {
   137  			return nil, fmt.Errorf("KMS error: unsupported algorithm")
   138  		}
   139  	}
   140  
   141  	pk, err := ExportPublicKeyFromKMS(keyConfig.KeyId, client)
   142  	if err != nil {
   143  		return nil, err
   144  	}
   145  
   146  	sk := &PrivateKey{
   147  		kms:      client,
   148  		keyType:  keyTypeKMS,
   149  		keyId:    keyConfig.KeyId,
   150  		keyAlias: keyConfig.KeyAlias,
   151  		pubKey:   pk,
   152  	}
   153  	return sk, nil
   154  }
   155  
   156  func LoadPrivateKey(client *kms.Client, skInfo []byte) (bccrypto.PrivateKey, error) {
   157  	var skConfig KMSPrivateKeyConfig
   158  	err := json.Unmarshal(skInfo, &skConfig)
   159  	if err != nil {
   160  		return nil, fmt.Errorf("KMS error: unmarshal private key failed, %v", err)
   161  	}
   162  
   163  	return NewPrivateKey(client, &skConfig)
   164  }