github.com/emmansun/gmsm@v0.29.1/pkcs8/pkcs8.go (about)

     1  // Package pkcs8 implements functions to parse and convert private keys in PKCS#8 format with ShangMi(SM) support, as defined in RFC5208 and RFC5958.
     2  package pkcs8
     3  
     4  import (
     5  	"crypto/ecdsa"
     6  	"crypto/rand"
     7  	"crypto/rsa"
     8  	"crypto/x509/pkix"
     9  	"encoding/asn1"
    10  	"encoding/pem"
    11  	"errors"
    12  
    13  	"github.com/emmansun/gmsm/pkcs"
    14  	"github.com/emmansun/gmsm/sm2"
    15  	"github.com/emmansun/gmsm/sm9"
    16  	"github.com/emmansun/gmsm/smx509"
    17  )
    18  
    19  type Opts = pkcs.PBES2Opts
    20  type PBKDF2Opts = pkcs.PBKDF2Opts
    21  type ScryptOpts = pkcs.ScryptOpts
    22  
    23  var DefaultOpts = pkcs.DefaultOpts
    24  var SM3 = pkcs.SM3
    25  var SHA1 = pkcs.SHA1
    26  var SHA224 = pkcs.SHA224
    27  var SHA256 = pkcs.SHA256
    28  var SHA384 = pkcs.SHA384
    29  var SHA512 = pkcs.SHA512
    30  var SHA512_224 = pkcs.SHA512_224
    31  var SHA512_256 = pkcs.SHA512_256
    32  
    33  // for encrypted private-key information
    34  type encryptedPrivateKeyInfo struct {
    35  	EncryptionAlgorithm pkix.AlgorithmIdentifier
    36  	EncryptedData       []byte
    37  }
    38  
    39  var (
    40  	ErrUnsupportedPBES = errors.New("pkcs8: only part of PBES1/PBES2 supported")
    41  	ErrUnexpectedKeyType = errors.New("pkcs8: unexpected key type")
    42  )
    43  
    44  // ParsePrivateKey parses a DER-encoded PKCS#8 private key.
    45  // Password can be nil.
    46  // This is equivalent to ParsePKCS8PrivateKey.
    47  func ParsePrivateKey(der []byte, password []byte) (any, pkcs.KDFParameters, error) {
    48  	// No password provided, assume the private key is unencrypted
    49  	if len(password) == 0 {
    50  		privateKey, err := smx509.ParsePKCS8PrivateKey(der)
    51  		return privateKey, nil, err
    52  	}
    53  
    54  	// Use the password provided to decrypt the private key
    55  	var privKey encryptedPrivateKeyInfo
    56  	if _, err := asn1.Unmarshal(der, &privKey); err != nil {
    57  		if block, _ := pem.Decode(der); block != nil {
    58  			return nil, nil, errors.New("pkcs8: this method just supports DER-encoded key")
    59  		}
    60  		return nil, nil, errors.New("pkcs8: only PKCS #5 v2.0 supported")
    61  	}
    62  
    63  	var kdfParams pkcs.KDFParameters
    64  	var decryptedKey []byte
    65  	var err error
    66  	switch {
    67  	case pkcs.IsPBES2(privKey.EncryptionAlgorithm) || pkcs.IsSMPBES(privKey.EncryptionAlgorithm):
    68  		var params pkcs.PBES2Params
    69  		if _, err := asn1.Unmarshal(privKey.EncryptionAlgorithm.Parameters.FullBytes, &params); err != nil {
    70  			return nil, nil, errors.New("pkcs8: invalid PBES2 parameters")
    71  		}
    72  		decryptedKey, kdfParams, err = params.Decrypt(password, privKey.EncryptedData)
    73  	case pkcs.IsPBES1(privKey.EncryptionAlgorithm):
    74  		pbes1 := &pkcs.PBES1{Algorithm: privKey.EncryptionAlgorithm}
    75  		decryptedKey, kdfParams, err = pbes1.Decrypt(password, privKey.EncryptedData)
    76  	default:
    77  		return nil, nil, ErrUnsupportedPBES
    78  	}
    79  	if err != nil {
    80  		return nil, nil, err
    81  	}
    82  	key, err := smx509.ParsePKCS8PrivateKey(decryptedKey)
    83  	if err != nil {
    84  		return nil, nil, err
    85  	}
    86  	return key, kdfParams, nil
    87  }
    88  
    89  // MarshalPrivateKey encodes a private key into DER-encoded PKCS#8 with the given options.
    90  // Password can be nil.
    91  func MarshalPrivateKey(priv any, password []byte, encrypter pkcs.PBESEncrypter) ([]byte, error) {
    92  	if len(password) == 0 {
    93  		return smx509.MarshalPKCS8PrivateKey(priv)
    94  	}
    95  
    96  	if encrypter == nil {
    97  		encrypter = DefaultOpts
    98  	}
    99  
   100  	// Convert private key into PKCS8 format
   101  	pkey, err := smx509.MarshalPKCS8PrivateKey(priv)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	encryptionAlgorithm, encryptedKey, err := encrypter.Encrypt(rand.Reader, password, pkey)
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  
   111  	encryptedPkey := encryptedPrivateKeyInfo{
   112  		EncryptionAlgorithm: *encryptionAlgorithm,
   113  		EncryptedData:       encryptedKey,
   114  	}
   115  
   116  	return asn1.Marshal(encryptedPkey)
   117  }
   118  
   119  // ParsePKCS8PrivateKey parses encrypted/unencrypted private keys in PKCS#8 format.
   120  // To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
   121  func ParsePKCS8PrivateKey(der []byte, v ...[]byte) (any, error) {
   122  	var password []byte
   123  	if len(v) > 0 {
   124  		password = v[0]
   125  	}
   126  	privateKey, _, err := ParsePrivateKey(der, password)
   127  	return privateKey, err
   128  }
   129  
   130  // ParsePKCS8PrivateKeyRSA parses encrypted/unencrypted private keys in PKCS#8 format.
   131  // To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
   132  func ParsePKCS8PrivateKeyRSA(der []byte, v ...[]byte) (*rsa.PrivateKey, error) {
   133  	key, err := ParsePKCS8PrivateKey(der, v...)
   134  	if err != nil {
   135  		return nil, err
   136  	}
   137  	typedKey, ok := key.(*rsa.PrivateKey)
   138  	if !ok {
   139  		return nil, ErrUnexpectedKeyType
   140  	}
   141  	return typedKey, nil
   142  }
   143  
   144  // ParsePKCS8PrivateKeyECDSA parses encrypted/unencrypted private keys in PKCS#8 format.
   145  // To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
   146  func ParsePKCS8PrivateKeyECDSA(der []byte, v ...[]byte) (*ecdsa.PrivateKey, error) {
   147  	key, err := ParsePKCS8PrivateKey(der, v...)
   148  	if err != nil {
   149  		return nil, err
   150  	}
   151  	typedKey, ok := key.(*ecdsa.PrivateKey)
   152  	if !ok {
   153  		return nil, ErrUnexpectedKeyType
   154  	}
   155  	return typedKey, nil
   156  }
   157  
   158  // ParsePKCS8PrivateKeySM2 parses encrypted/unencrypted SM2 private key in PKCS#8 format.
   159  // To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
   160  func ParsePKCS8PrivateKeySM2(der []byte, v ...[]byte) (*sm2.PrivateKey, error) {
   161  	key, err := ParsePKCS8PrivateKey(der, v...)
   162  	if err != nil {
   163  		return nil, err
   164  	}
   165  	typedKey, ok := key.(*sm2.PrivateKey)
   166  	if !ok {
   167  		return nil, ErrUnexpectedKeyType
   168  	}
   169  	return typedKey, nil
   170  }
   171  
   172  // ParseSM9SignMasterPrivateKey parses encrypted/unencrypted SM9 sign master private key in PKCS#8 format.
   173  // To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
   174  func ParseSM9SignMasterPrivateKey(der []byte, v ...[]byte) (*sm9.SignMasterPrivateKey, error) {
   175  	key, err := ParsePKCS8PrivateKey(der, v...)
   176  	if err != nil {
   177  		return nil, err
   178  	}
   179  	typedKey, ok := key.(*sm9.SignMasterPrivateKey)
   180  	if !ok {
   181  		return nil, ErrUnexpectedKeyType
   182  	}
   183  	return typedKey, nil
   184  }
   185  
   186  // ParseSM9SignPrivateKey parses encrypted/unencrypted SM9 sign private key in PKCS#8 format.
   187  // To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
   188  func ParseSM9SignPrivateKey(der []byte, v ...[]byte) (*sm9.SignPrivateKey, error) {
   189  	key, err := ParsePKCS8PrivateKey(der, v...)
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  	typedKey, ok := key.(*sm9.SignPrivateKey)
   194  	if !ok {
   195  		return nil, ErrUnexpectedKeyType
   196  	}
   197  	return typedKey, nil
   198  }
   199  
   200  // ParseSM9EncryptMasterPrivateKey parses encrypted/unencrypted SM9 encrypt master private key in PKCS#8 format.
   201  // To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
   202  func ParseSM9EncryptMasterPrivateKey(der []byte, v ...[]byte) (*sm9.EncryptMasterPrivateKey, error) {
   203  	key, err := ParsePKCS8PrivateKey(der, v...)
   204  	if err != nil {
   205  		return nil, err
   206  	}
   207  	typedKey, ok := key.(*sm9.EncryptMasterPrivateKey)
   208  	if !ok {
   209  		return nil, ErrUnexpectedKeyType
   210  	}
   211  	return typedKey, nil
   212  }
   213  
   214  // ParseSM9EncryptPrivateKey parses encrypted/unencrypted SM9 encrypt private key in PKCS#8 format.
   215  // To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
   216  func ParseSM9EncryptPrivateKey(der []byte, v ...[]byte) (*sm9.EncryptPrivateKey, error) {
   217  	key, err := ParsePKCS8PrivateKey(der, v...)
   218  	if err != nil {
   219  		return nil, err
   220  	}
   221  	typedKey, ok := key.(*sm9.EncryptPrivateKey)
   222  	if !ok {
   223  		return nil, ErrUnexpectedKeyType
   224  	}
   225  	return typedKey, nil
   226  }
   227  
   228  // ConvertPrivateKeyToPKCS8 converts the private key into PKCS#8 format.
   229  // To encrypt the private key, the password of []byte type should be provided as the second parameter.
   230  func ConvertPrivateKeyToPKCS8(priv any, v ...[]byte) ([]byte, error) {
   231  	var password []byte
   232  	if len(v) > 0 {
   233  		password = v[0]
   234  	}
   235  	return MarshalPrivateKey(priv, password, nil)
   236  }