github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric/bccsp/sw/keys.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package sw
     8  
     9  import (
    10  	"crypto/elliptic"
    11  	"crypto/rand"
    12  	"encoding/asn1"
    13  	"encoding/pem"
    14  	"errors"
    15  	"fmt"
    16  	"github.com/hellobchain/newcryptosm/ecdsa"
    17  	"github.com/hellobchain/newcryptosm/sm2"
    18  	"github.com/hellobchain/newcryptosm/x509"
    19  )
    20  
    21  type pkcs8Info struct {
    22  	Version             int
    23  	PrivateKeyAlgorithm []asn1.ObjectIdentifier
    24  	PrivateKey          []byte
    25  }
    26  
    27  type ecPrivateKey struct {
    28  	Version       int
    29  	PrivateKey    []byte
    30  	NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
    31  	PublicKey     asn1.BitString        `asn1:"optional,explicit,tag:1"`
    32  }
    33  
    34  var (
    35  	oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
    36  	oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
    37  	oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
    38  	oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
    39  	oidNamedCurveSM2  = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301}
    40  )
    41  
    42  var oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
    43  var oidPublicKeySM2 = asn1.ObjectIdentifier{1, 2, 156, 197, 1, 301}
    44  
    45  func oidPublicKeyFromNamedCurve(curve elliptic.Curve) asn1.ObjectIdentifier {
    46  	switch curve {
    47  	case elliptic.P224():
    48  		return oidPublicKeyECDSA
    49  	case elliptic.P384():
    50  		return oidPublicKeyECDSA
    51  	case elliptic.P521():
    52  		return oidPublicKeyECDSA
    53  	case elliptic.P256():
    54  		return oidPublicKeyECDSA
    55  	case sm2.SM2():
    56  		return oidPublicKeySM2
    57  	}
    58  	return nil
    59  }
    60  
    61  func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
    62  	switch curve {
    63  	case elliptic.P224():
    64  		return oidNamedCurveP224, true
    65  	case elliptic.P256():
    66  		return oidNamedCurveP256, true
    67  	case elliptic.P384():
    68  		return oidNamedCurveP384, true
    69  	case elliptic.P521():
    70  		return oidNamedCurveP521, true
    71  	case sm2.SM2():
    72  		return oidNamedCurveSM2, true
    73  	}
    74  	return nil, false
    75  }
    76  
    77  func privateKeyToDER(privateKey *ecdsa.PrivateKey) ([]byte, error) {
    78  	if privateKey == nil {
    79  		return nil, errors.New("invalid ecdsa private key. It must be different from nil")
    80  	}
    81  
    82  	return x509.MarshalECPrivateKey(privateKey)
    83  }
    84  
    85  func privateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
    86  	// Validate inputs
    87  	if len(pwd) != 0 {
    88  		return privateKeyToEncryptedPEM(privateKey, pwd)
    89  	}
    90  	if privateKey == nil {
    91  		return nil, errors.New("invalid key. It must be different from nil")
    92  	}
    93  
    94  	switch k := privateKey.(type) {
    95  	case *ecdsa.PrivateKey:
    96  		if k == nil {
    97  			return nil, errors.New("invalid ecdsa private key. It must be different from nil")
    98  		}
    99  
   100  		// get the oid for the curve
   101  		oidNamedCurve, ok := oidFromNamedCurve(k.Curve)
   102  		if !ok {
   103  			return nil, errors.New("unknown elliptic curve")
   104  		}
   105  
   106  		// based on https://golang.org/src/crypto/x509/sec1.go
   107  		privateKeyBytes := k.D.Bytes()
   108  		paddedPrivateKey := make([]byte, (k.Curve.Params().N.BitLen()+7)/8)
   109  		copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes)
   110  		// omit NamedCurveOID for compatibility as it's optional
   111  		asn1Bytes, err := asn1.Marshal(ecPrivateKey{
   112  			Version:    1,
   113  			PrivateKey: paddedPrivateKey,
   114  			PublicKey:  asn1.BitString{Bytes: elliptic.Marshal(k.Curve, k.X, k.Y)},
   115  		})
   116  		if err != nil {
   117  			return nil, fmt.Errorf("error marshaling EC key to asn1: [%s]", err)
   118  		}
   119  
   120  		var pkcs8Key pkcs8Info
   121  		pkcs8Key.Version = 0
   122  		pkcs8Key.PrivateKeyAlgorithm = make([]asn1.ObjectIdentifier, 2)
   123  		pkcs8Key.PrivateKeyAlgorithm[0] = oidPublicKeyFromNamedCurve(k.Curve)
   124  		pkcs8Key.PrivateKeyAlgorithm[1] = oidNamedCurve
   125  		pkcs8Key.PrivateKey = asn1Bytes
   126  
   127  		pkcs8Bytes, err := asn1.Marshal(pkcs8Key)
   128  		if err != nil {
   129  			return nil, fmt.Errorf("error marshaling EC key to asn1: [%s]", err)
   130  		}
   131  		return pem.EncodeToMemory(
   132  			&pem.Block{
   133  				Type:  "PRIVATE KEY",
   134  				Bytes: pkcs8Bytes,
   135  			},
   136  		), nil
   137  
   138  	default:
   139  		return nil, errors.New("invalid key type. It must be *ecdsa.PrivateKey")
   140  	}
   141  }
   142  
   143  func privateKeyToEncryptedPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
   144  	if privateKey == nil {
   145  		return nil, errors.New("invalid private key. It must be different from nil")
   146  	}
   147  
   148  	switch k := privateKey.(type) {
   149  	case *ecdsa.PrivateKey:
   150  		if k == nil {
   151  			return nil, errors.New("invalid ecdsa private key. It must be different from nil")
   152  		}
   153  		raw, err := x509.MarshalECPrivateKey(k)
   154  		if err != nil {
   155  			return nil, err
   156  		}
   157  
   158  		block, err := x509.EncryptPEMBlock(
   159  			rand.Reader,
   160  			"PRIVATE KEY",
   161  			raw,
   162  			pwd,
   163  			x509.PEMCipherAES256)
   164  		if err != nil {
   165  			return nil, err
   166  		}
   167  
   168  		return pem.EncodeToMemory(block), nil
   169  
   170  	default:
   171  		return nil, errors.New("invalid key type. It must be *ecdsa.PrivateKey")
   172  	}
   173  }
   174  
   175  func derToPrivateKey(der []byte) (key interface{}, err error) {
   176  	if key, err = x509.ParsePKCS1PrivateKey(der); err == nil {
   177  		return key, nil
   178  	}
   179  
   180  	if key, err = x509.ParsePKCS8PrivateKey(der); err == nil {
   181  		switch key.(type) {
   182  		case *ecdsa.PrivateKey:
   183  			return
   184  		default:
   185  			return nil, errors.New("found unknown private key type in PKCS#8 wrapping")
   186  		}
   187  	}
   188  
   189  	if key, err = x509.ParseECPrivateKey(der); err == nil {
   190  		return
   191  	}
   192  
   193  	return nil, errors.New("invalid key type. The DER must contain an ecdsa.PrivateKey")
   194  }
   195  
   196  func pemToPrivateKey(raw []byte, pwd []byte) (interface{}, error) {
   197  	block, _ := pem.Decode(raw)
   198  	if block == nil {
   199  		return nil, fmt.Errorf("failed decoding PEM. Block must be different from nil [% x]", raw)
   200  	}
   201  
   202  	// TODO: derive from header the type of the key
   203  
   204  	if x509.IsEncryptedPEMBlock(block) {
   205  		if len(pwd) == 0 {
   206  			return nil, errors.New("encrypted Key. Need a password")
   207  		}
   208  
   209  		decrypted, err := x509.DecryptPEMBlock(block, pwd)
   210  		if err != nil {
   211  			return nil, fmt.Errorf("failed PEM decryption: [%s]", err)
   212  		}
   213  
   214  		key, err := derToPrivateKey(decrypted)
   215  		if err != nil {
   216  			return nil, err
   217  		}
   218  		return key, err
   219  	}
   220  
   221  	cert, err := derToPrivateKey(block.Bytes)
   222  	if err != nil {
   223  		return nil, err
   224  	}
   225  	return cert, err
   226  }
   227  
   228  func pemToAES(raw []byte, pwd []byte) ([]byte, error) {
   229  	if len(raw) == 0 {
   230  		return nil, errors.New("invalid PEM. It must be different from nil")
   231  	}
   232  	block, _ := pem.Decode(raw)
   233  	if block == nil {
   234  		return nil, fmt.Errorf("failed decoding PEM. Block must be different from nil [% x]", raw)
   235  	}
   236  
   237  	if x509.IsEncryptedPEMBlock(block) {
   238  		if len(pwd) == 0 {
   239  			return nil, errors.New("encrypted Key. Password must be different fom nil")
   240  		}
   241  
   242  		decrypted, err := x509.DecryptPEMBlock(block, pwd)
   243  		if err != nil {
   244  			return nil, fmt.Errorf("failed PEM decryption: [%s]", err)
   245  		}
   246  		return decrypted, nil
   247  	}
   248  
   249  	return block.Bytes, nil
   250  }
   251  
   252  func aesToPEM(raw []byte) []byte {
   253  	return pem.EncodeToMemory(&pem.Block{Type: "AES PRIVATE KEY", Bytes: raw})
   254  }
   255  
   256  func aesToEncryptedPEM(raw []byte, pwd []byte) ([]byte, error) {
   257  	if len(raw) == 0 {
   258  		return nil, errors.New("invalid aes key. It must be different from nil")
   259  	}
   260  	if len(pwd) == 0 {
   261  		return aesToPEM(raw), nil
   262  	}
   263  
   264  	block, err := x509.EncryptPEMBlock(
   265  		rand.Reader,
   266  		"AES PRIVATE KEY",
   267  		raw,
   268  		pwd,
   269  		x509.PEMCipherAES256)
   270  	if err != nil {
   271  		return nil, err
   272  	}
   273  
   274  	return pem.EncodeToMemory(block), nil
   275  }
   276  
   277  func pemToSM4(raw []byte, pwd []byte) ([]byte, error) {
   278  	if len(raw) == 0 {
   279  		return nil, errors.New("invalid PEM. It must be different from nil")
   280  	}
   281  	block, _ := pem.Decode(raw)
   282  	if block == nil {
   283  		return nil, fmt.Errorf("failed decoding PEM. Block must be different from nil [% x]", raw)
   284  	}
   285  
   286  	if x509.IsEncryptedPEMBlock(block) {
   287  		if len(pwd) == 0 {
   288  			return nil, errors.New("encrypted Key. Password must be different fom nil")
   289  		}
   290  
   291  		decrypted, err := x509.DecryptPEMBlock(block, pwd)
   292  		if err != nil {
   293  			return nil, fmt.Errorf("failed PEM decryption: [%s]", err)
   294  		}
   295  		return decrypted, nil
   296  	}
   297  
   298  	return block.Bytes, nil
   299  }
   300  
   301  // sm4toPEM encapsulates an SM4 key in the PEM format
   302  func sm4toPEM(raw []byte) []byte {
   303  	return pem.EncodeToMemory(&pem.Block{Type: "SM4 PRIVATE KEY", Bytes: raw})
   304  }
   305  
   306  // sm4toEncryptedPEM encapsulates an SM4 key in the encrypted PEM format
   307  func sm4toEncryptedPEM(raw []byte, pwd []byte) ([]byte, error) {
   308  	if len(raw) == 0 {
   309  		return nil, errors.New("Invalid sm4 key. It must be different from nil")
   310  	}
   311  	if len(pwd) == 0 {
   312  		return sm4toPEM(raw), nil
   313  	}
   314  
   315  	block, err := x509.EncryptPEMBlock(
   316  		rand.Reader,
   317  		"SM4 PRIVATE KEY",
   318  		raw,
   319  		pwd,
   320  		x509.PEMCipherSM4)
   321  
   322  	if err != nil {
   323  		return nil, err
   324  	}
   325  
   326  	return pem.EncodeToMemory(block), nil
   327  }
   328  
   329  func publicKeyToPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
   330  	if len(pwd) != 0 {
   331  		return publicKeyToEncryptedPEM(publicKey, pwd)
   332  	}
   333  
   334  	if publicKey == nil {
   335  		return nil, errors.New("invalid public key. It must be different from nil")
   336  	}
   337  
   338  	switch k := publicKey.(type) {
   339  	case *ecdsa.PublicKey:
   340  		if k == nil {
   341  			return nil, errors.New("invalid ecdsa public key. It must be different from nil")
   342  		}
   343  		PubASN1, err := x509.MarshalPKIXPublicKey(k)
   344  		if err != nil {
   345  			return nil, err
   346  		}
   347  
   348  		return pem.EncodeToMemory(
   349  			&pem.Block{
   350  				Type:  "PUBLIC KEY",
   351  				Bytes: PubASN1,
   352  			},
   353  		), nil
   354  
   355  	default:
   356  		return nil, errors.New("invalid key type. It must be *ecdsa.PublicKey")
   357  	}
   358  }
   359  
   360  func publicKeyToEncryptedPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
   361  	switch k := publicKey.(type) {
   362  	case *ecdsa.PublicKey:
   363  		if k == nil {
   364  			return nil, errors.New("invalid ecdsa public key. It must be different from nil")
   365  		}
   366  		raw, err := x509.MarshalPKIXPublicKey(k)
   367  		if err != nil {
   368  			return nil, err
   369  		}
   370  
   371  		block, err := x509.EncryptPEMBlock(
   372  			rand.Reader,
   373  			"PUBLIC KEY",
   374  			raw,
   375  			pwd,
   376  			x509.PEMCipherAES256)
   377  		if err != nil {
   378  			return nil, err
   379  		}
   380  
   381  		return pem.EncodeToMemory(block), nil
   382  	default:
   383  		return nil, errors.New("invalid key type. It must be *ecdsa.PublicKey")
   384  	}
   385  }
   386  
   387  func pemToPublicKey(raw []byte, pwd []byte) (interface{}, error) {
   388  	if len(raw) == 0 {
   389  		return nil, errors.New("invalid PEM. It must be different from nil")
   390  	}
   391  	block, _ := pem.Decode(raw)
   392  	if block == nil {
   393  		return nil, fmt.Errorf("failed decoding. Block must be different from nil [% x]", raw)
   394  	}
   395  
   396  	// TODO: derive from header the type of the key
   397  	if x509.IsEncryptedPEMBlock(block) {
   398  		if len(pwd) == 0 {
   399  			return nil, errors.New("encrypted Key. Password must be different from nil")
   400  		}
   401  
   402  		decrypted, err := x509.DecryptPEMBlock(block, pwd)
   403  		if err != nil {
   404  			return nil, fmt.Errorf("failed PEM decryption: [%s]", err)
   405  		}
   406  
   407  		key, err := derToPublicKey(decrypted)
   408  		if err != nil {
   409  			return nil, err
   410  		}
   411  		return key, err
   412  	}
   413  
   414  	cert, err := derToPublicKey(block.Bytes)
   415  	if err != nil {
   416  		return nil, err
   417  	}
   418  	return cert, err
   419  }
   420  
   421  func derToPublicKey(raw []byte) (pub interface{}, err error) {
   422  	if len(raw) == 0 {
   423  		return nil, errors.New("invalid DER. It must be different from nil")
   424  	}
   425  
   426  	key, err := x509.ParsePKIXPublicKey(raw)
   427  
   428  	return key, err
   429  }