gitee.com/lh-her-team/common@v1.5.1/crypto/x509/pkcs8.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package x509
     6  
     7  import (
     8  	"crypto/ecdsa"
     9  	"crypto/rsa"
    10  	"crypto/x509/pkix"
    11  	"encoding/asn1"
    12  	"errors"
    13  	"fmt"
    14  
    15  	"github.com/tjfoc/gmsm/sm2"
    16  	tjx509 "github.com/tjfoc/gmsm/x509"
    17  )
    18  
    19  // pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See
    20  // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn
    21  // and RFC 5208.
    22  type pkcs8 struct {
    23  	Version    int
    24  	Algo       pkix.AlgorithmIdentifier
    25  	PrivateKey []byte
    26  	// optional attributes omitted.
    27  }
    28  
    29  // ParsePKCS8PrivateKey parses an unencrypted, PKCS#8 private key.
    30  // See RFC 5208.
    31  func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
    32  	var privKey pkcs8
    33  	if _, err := asn1.Unmarshal(der, &privKey); err != nil {
    34  		return nil, err
    35  	}
    36  	switch {
    37  	case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA):
    38  		return parsePKCS8PrivateKeyRSA(&privKey)
    39  	case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA):
    40  		return parsePKCS8PrivateKeyECDSA(&privKey)
    41  	case privKey.Algo.Algorithm.Equal(oidPublicKeySM2):
    42  		return parsePKCS8PrivateKeySM2(&privKey)
    43  	default:
    44  		return nil, fmt.Errorf(
    45  			"x509: PKCS#8 wrapping contained private key with unknown algorithm: %v",
    46  			privKey.Algo.Algorithm,
    47  		)
    48  	}
    49  }
    50  
    51  func parsePKCS8PrivateKeyRSA(privKey *pkcs8) (key interface{}, err error) {
    52  	key, err = ParsePKCS1PrivateKey(privKey.PrivateKey)
    53  	if err != nil {
    54  		return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error())
    55  	}
    56  	return key, nil
    57  }
    58  
    59  func parsePKCS8PrivateKeyECDSA(privKey *pkcs8) (key interface{}, err error) {
    60  	bytes := privKey.Algo.Parameters.FullBytes
    61  	namedCurveOID := new(asn1.ObjectIdentifier)
    62  	if _, err = asn1.Unmarshal(bytes, namedCurveOID); err != nil {
    63  		namedCurveOID = nil
    64  	}
    65  	if namedCurveOID != nil && namedCurveOID.Equal(oidNamedCurveSm2) {
    66  		key, err = tjx509.ParseSm2PrivateKey(privKey.PrivateKey)
    67  		if err != nil {
    68  			return nil, errors.New("x509: failed to parse sm2 private key embedded in PKCS#8: " + err.Error())
    69  		}
    70  	} else {
    71  		key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey)
    72  		if err != nil {
    73  			return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error())
    74  		}
    75  	}
    76  	return key, nil
    77  }
    78  
    79  // nolint: ineffassign
    80  func parsePKCS8PrivateKeySM2(privKey *pkcs8) (key interface{}, err error) {
    81  	bytes := privKey.Algo.Parameters.FullBytes
    82  	namedCurveOID := new(asn1.ObjectIdentifier)
    83  	if _, err = asn1.Unmarshal(bytes, namedCurveOID); err != nil {
    84  		namedCurveOID = nil
    85  	}
    86  	key, err = tjx509.ParseSm2PrivateKey(privKey.PrivateKey)
    87  	if err != nil {
    88  		return nil, errors.New("x509: failed to parse sm2 private key embedded in PKCS#8: " + err.Error())
    89  	}
    90  	return key, nil
    91  }
    92  
    93  // MarshalPKCS8PrivateKey converts a private key to PKCS#8 encoded form.
    94  // The following key types are supported: *rsa.PrivateKey, *ecdsa.PrivateKey.
    95  // Unsupported key types result in an error.
    96  //
    97  // See RFC 5208.
    98  func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) {
    99  	var privKey pkcs8
   100  	switch k := key.(type) {
   101  	case *rsa.PrivateKey:
   102  		privKey.Algo = pkix.AlgorithmIdentifier{
   103  			Algorithm:  oidPublicKeyRSA,
   104  			Parameters: asn1.NullRawValue,
   105  		}
   106  		privKey.PrivateKey = MarshalPKCS1PrivateKey(k)
   107  	case *ecdsa.PrivateKey:
   108  		oid, ok := oidFromNamedCurve(k.Curve)
   109  		if !ok {
   110  			return nil, errors.New("x509: unknown curve while marshalling to PKCS#8")
   111  		}
   112  		oidBytes, err := asn1.Marshal(oid)
   113  		if err != nil {
   114  			return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
   115  		}
   116  		privKey.Algo = pkix.AlgorithmIdentifier{
   117  			Algorithm: oidPublicKeyECDSA,
   118  			Parameters: asn1.RawValue{
   119  				FullBytes: oidBytes,
   120  			},
   121  		}
   122  		if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil {
   123  			return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
   124  		}
   125  	case *sm2.PrivateKey:
   126  		oid, ok := oidFromNamedCurve(k.Curve)
   127  		if !ok {
   128  			return nil, errors.New("x509: unknown curve while marshalling to PKCS#8")
   129  		}
   130  		oidBytes, err := asn1.Marshal(oid)
   131  		if err != nil {
   132  			return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
   133  		}
   134  		privKey.Algo = pkix.AlgorithmIdentifier{
   135  			Algorithm: oidPublicKeyECDSA,
   136  			Parameters: asn1.RawValue{
   137  				FullBytes: oidBytes,
   138  			},
   139  		}
   140  		if privKey.PrivateKey, err = tjx509.MarshalSm2UnecryptedPrivateKey(k); err != nil {
   141  			return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
   142  		}
   143  	default:
   144  		return nil, fmt.Errorf("x509: unknown key type while marshalling PKCS#8: %T", key)
   145  	}
   146  	return asn1.Marshal(privKey)
   147  }