gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/x509/sec1.go (about)

     1  // Copyright 2012 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  /*
     8  x509/sec1.go 椭圆曲线公私钥与其SEC 1, ASN.1 DER字节数组之间的相互转换
     9  目前支持sm2, ecdsa
    10  
    11  ParseECPrivateKey : 将SEC 1, ASN.1 DER格式字节数组转为EC(椭圆曲线)私钥
    12  MarshalECPrivateKey : 将EC(椭圆曲线)私钥转为SEC 1, ASN.1 DER格式字节数组
    13  */
    14  
    15  import (
    16  	"crypto/ecdsa"
    17  	"crypto/elliptic"
    18  	"encoding/asn1"
    19  	"errors"
    20  	"fmt"
    21  	"gitee.com/zhaochuninhefei/gmgo/ecdsa_ext"
    22  	"math/big"
    23  
    24  	"gitee.com/zhaochuninhefei/gmgo/sm2"
    25  )
    26  
    27  const ecPrivKeyVersion = 1
    28  
    29  // ecPrivateKey 椭圆曲线私钥结构体, 添加用于识别私钥类型的字段(目前支持sm2/ecdsa/ecdsa_ext)
    30  //  ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure.
    31  // References:
    32  //   RFC 5915
    33  //   SEC1 - http://www.secg.org/sec1-v2.pdf
    34  // Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in
    35  // most cases it is not.
    36  type ecPrivateKey struct {
    37  	Version       int
    38  	PrivateKey    []byte
    39  	NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
    40  	PublicKey     asn1.BitString        `asn1:"optional,explicit,tag:1"`
    41  
    42  	// 用于识别私钥类型的字段
    43  	PrivType string `asn1:"optional,explicit,tag:2"`
    44  }
    45  
    46  // ParseECPrivateKey 将SEC 1, ASN.1 DER格式字节数组转为EC(椭圆曲线)私钥
    47  // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey
    48  //
    49  // ParseECPrivateKey parses an EC private key in SEC 1, ASN.1 DER form.
    50  // This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY".
    51  func ParseECPrivateKey(der []byte) (interface{}, error) {
    52  	return parseECPrivateKey(nil, der)
    53  }
    54  
    55  // MarshalECPrivateKey 将EC(椭圆曲线)私钥转为SEC 1, ASN.1 DER格式字节数组
    56  // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey
    57  //
    58  // MarshalECPrivateKey converts an EC private key to SEC 1, ASN.1 DER form.
    59  //
    60  // This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY".
    61  // For a more flexible key format which is not EC specific, use
    62  // MarshalPKCS8PrivateKey.
    63  func MarshalECPrivateKey(key interface{}) ([]byte, error) {
    64  	switch priv := key.(type) {
    65  	case *ecdsa.PrivateKey:
    66  		oid, ok := oidFromNamedCurve(priv.Curve)
    67  		if !ok {
    68  			return nil, errors.New("gmx509.MarshalECPrivateKey: unknown elliptic curve")
    69  		}
    70  		if oid.Equal(oidNamedCurveP256SM2) {
    71  			return nil, errors.New("gmx509.MarshalECPrivateKey: not ecdsa curves")
    72  		}
    73  		privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8)
    74  		return asn1.Marshal(ecPrivateKey{
    75  			Version:       ecPrivKeyVersion,
    76  			PrivateKey:    priv.D.FillBytes(privateKey),
    77  			NamedCurveOID: oid,
    78  			PublicKey:     asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)},
    79  			PrivType:      "ecdsa",
    80  		})
    81  	case *ecdsa_ext.PrivateKey:
    82  		oid, ok := oidFromNamedCurve(priv.Curve)
    83  		if !ok {
    84  			return nil, errors.New("gmx509.MarshalECPrivateKey: unknown elliptic curve")
    85  		}
    86  		if oid.Equal(oidNamedCurveP256SM2) {
    87  			return nil, errors.New("gmx509.MarshalECPrivateKey: not ecdsa curves")
    88  		}
    89  		privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8)
    90  		return asn1.Marshal(ecPrivateKey{
    91  			Version:       ecPrivKeyVersion,
    92  			PrivateKey:    priv.D.FillBytes(privateKey),
    93  			NamedCurveOID: oid,
    94  			PublicKey:     asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)},
    95  			PrivType:      "ecdsa_ext",
    96  		})
    97  	case *sm2.PrivateKey:
    98  		oid, ok := oidFromNamedCurve(priv.Curve)
    99  		if !ok {
   100  			return nil, errors.New("gmx509.MarshalECPrivateKey: unknown elliptic curve")
   101  		}
   102  		if !oid.Equal(oidNamedCurveP256SM2) {
   103  			return nil, errors.New("gmx509.MarshalECPrivateKey: not sm2 curve")
   104  		}
   105  		privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8)
   106  		return asn1.Marshal(ecPrivateKey{
   107  			Version:       ecPrivKeyVersion,
   108  			PrivateKey:    priv.D.FillBytes(privateKey),
   109  			NamedCurveOID: oid,
   110  			PublicKey:     asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)},
   111  			PrivType:      "sm2",
   112  		})
   113  		// var ecPriv ecPrivateKey
   114  		// ecPriv.Version = ecPrivKeyVersion
   115  		// ecPriv.NamedCurveOID = oidNamedCurveP256SM2
   116  		// ecPriv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}
   117  		// ecPriv.PrivateKey = priv.D.Bytes()
   118  		// return asn1.Marshal(ecPriv)
   119  	}
   120  	return nil, errors.New("x509: failed to marshalECPrivateKeyWithOID: Unknown PrivateKey")
   121  }
   122  
   123  // parseECPrivateKey根据namedCurveOID获取对应的椭圆曲线,并将SEC 1, ASN.1 DER格式字节数组转为EC(椭圆曲线)私钥
   124  // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey
   125  //
   126  // parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure.
   127  // The OID for the named curve may be provided from another source (such as
   128  // the PKCS8 container) - if it is provided then use this instead of the OID
   129  // that may exist in the EC private key structure.
   130  func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key interface{}, err error) {
   131  	var privKey ecPrivateKey
   132  	// 尝试将 der 反序列化到 privKey
   133  	if _, err := asn1.Unmarshal(der, &privKey); err != nil {
   134  		if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil {
   135  			return nil, errors.New("gmx509.parseECPrivateKey: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)")
   136  		}
   137  		if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil {
   138  			return nil, errors.New("gmx509.parseECPrivateKey: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
   139  		}
   140  		return nil, fmt.Errorf("gmx509.parseECPrivateKey: failed to parse EC private key: %s", err.Error())
   141  	}
   142  	// 检查版本
   143  	if privKey.Version != ecPrivKeyVersion {
   144  		return nil, fmt.Errorf("gmx509.parseECPrivateKey: unknown EC private key version %d", privKey.Version)
   145  	}
   146  	var curve elliptic.Curve
   147  	// namedCurveOID有可能为nil,因为ecdsa在其序列化(pkcs8.go的MarshalPKCS8PrivateKey)分支里并没有传入oid到序列化结构中去。
   148  	if namedCurveOID != nil {
   149  		// 根据namedCurveOID获取曲线
   150  		curve = namedCurveFromOID(*namedCurveOID)
   151  	} else {
   152  		// namedCurveOID为空则使用私钥的NamedCurveOID
   153  		curve = namedCurveFromOID(privKey.NamedCurveOID)
   154  	}
   155  	if curve == nil {
   156  		return nil, errors.New("gmx509.parseECPrivateKey: unknown elliptic curve")
   157  	}
   158  	// 检查私钥数值是否小于曲线参数N
   159  	k := new(big.Int).SetBytes(privKey.PrivateKey)
   160  	curveOrder := curve.Params().N
   161  	if k.Cmp(curveOrder) >= 0 {
   162  		return nil, errors.New("gmx509.parseECPrivateKey: invalid elliptic curve private key value")
   163  	}
   164  	// 根据曲线选择生成对应完整私钥
   165  	switch curve {
   166  	case sm2.P256Sm2():
   167  		priv := new(sm2.PrivateKey)
   168  		priv.Curve = curve
   169  		priv.D = k
   170  		privateKey := make([]byte, (curveOrder.BitLen()+7)/8)
   171  		// Some private keys have leading zero padding. This is invalid
   172  		// according to [SEC1], but this code will ignore it.
   173  		for len(privKey.PrivateKey) > len(privateKey) {
   174  			if privKey.PrivateKey[0] != 0 {
   175  				return nil, errors.New("gmx509.parseECPrivateKey: invalid private key length")
   176  			}
   177  			privKey.PrivateKey = privKey.PrivateKey[1:]
   178  		}
   179  		// Some private keys remove all leading zeros, this is also invalid
   180  		// according to [SEC1] but since OpenSSL used to do this, we ignore
   181  		// this too.
   182  		copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
   183  		priv.X, priv.Y = curve.ScalarBaseMult(privateKey)
   184  		return priv, nil
   185  	case elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521():
   186  		switch privKey.PrivType {
   187  		case "ecdsa", "":
   188  			priv := new(ecdsa.PrivateKey)
   189  			priv.Curve = curve
   190  			priv.D = k
   191  			privateKey := make([]byte, (curveOrder.BitLen()+7)/8)
   192  			// Some private keys have leading zero padding. This is invalid
   193  			// according to [SEC1], but this code will ignore it.
   194  			for len(privKey.PrivateKey) > len(privateKey) {
   195  				if privKey.PrivateKey[0] != 0 {
   196  					return nil, errors.New("gmx509.parseECPrivateKey: invalid private key length")
   197  				}
   198  				privKey.PrivateKey = privKey.PrivateKey[1:]
   199  			}
   200  			// Some private keys remove all leading zeros, this is also invalid
   201  			// according to [SEC1] but since OpenSSL used to do this, we ignore
   202  			// this too.
   203  			copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
   204  			priv.X, priv.Y = curve.ScalarBaseMult(privateKey)
   205  			return priv, nil
   206  		case "ecdsa_ext":
   207  			priv := new(ecdsa_ext.PrivateKey)
   208  			priv.Curve = curve
   209  			priv.D = k
   210  			privateKey := make([]byte, (curveOrder.BitLen()+7)/8)
   211  			// Some private keys have leading zero padding. This is invalid
   212  			// according to [SEC1], but this code will ignore it.
   213  			for len(privKey.PrivateKey) > len(privateKey) {
   214  				if privKey.PrivateKey[0] != 0 {
   215  					return nil, errors.New("gmx509.parseECPrivateKey: invalid private key length")
   216  				}
   217  				privKey.PrivateKey = privKey.PrivateKey[1:]
   218  			}
   219  			// Some private keys remove all leading zeros, this is also invalid
   220  			// according to [SEC1] but since OpenSSL used to do this, we ignore
   221  			// this too.
   222  			copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
   223  			priv.X, priv.Y = curve.ScalarBaseMult(privateKey)
   224  			return priv, nil
   225  		}
   226  	}
   227  	return nil, errors.New("gmx509.parseECPrivateKey: failed to parseECPrivateKey: Unknown curve")
   228  }
   229  
   230  // marshalECPrivateKeyWithOID根据oid将EC(椭圆曲线)私钥转为SEC 1, ASN.1 DER格式字节数组
   231  // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey
   232  //
   233  // marshalECPrivateKey marshals an EC private key into ASN.1, DER format and
   234  // sets the curve ID to the given OID, or omits it if OID is nil.
   235  func marshalECPrivateKeyWithOID(key interface{}, oid asn1.ObjectIdentifier) ([]byte, error) {
   236  	switch priv := key.(type) {
   237  	case *ecdsa.PrivateKey:
   238  		if oid.Equal(oidNamedCurveP256SM2) {
   239  			return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: not ecdsa curves")
   240  		}
   241  		privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8)
   242  		return asn1.Marshal(ecPrivateKey{
   243  			Version:       ecPrivKeyVersion,
   244  			PrivateKey:    priv.D.FillBytes(privateKey),
   245  			NamedCurveOID: oid,
   246  			PublicKey:     asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)},
   247  			PrivType:      "ecdsa",
   248  		})
   249  	case *ecdsa_ext.PrivateKey:
   250  		if oid.Equal(oidNamedCurveP256SM2) {
   251  			return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: not ecdsa curves")
   252  		}
   253  		privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8)
   254  		return asn1.Marshal(ecPrivateKey{
   255  			Version:       ecPrivKeyVersion,
   256  			PrivateKey:    priv.D.FillBytes(privateKey),
   257  			NamedCurveOID: oid,
   258  			PublicKey:     asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)},
   259  			PrivType:      "ecdsa_ext",
   260  		})
   261  	case *sm2.PrivateKey:
   262  		if !oid.Equal(oidNamedCurveP256SM2) {
   263  			return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: not sm2 curve")
   264  		}
   265  		privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8)
   266  		return asn1.Marshal(ecPrivateKey{
   267  			Version:       ecPrivKeyVersion,
   268  			PrivateKey:    priv.D.FillBytes(privateKey),
   269  			NamedCurveOID: oid,
   270  			PublicKey:     asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)},
   271  			PrivType:      "sm2",
   272  		})
   273  		// var ecPriv ecPrivateKey
   274  		// ecPriv.Version = ecPrivKeyVersion
   275  		// ecPriv.NamedCurveOID = oidNamedCurveP256SM2
   276  		// ecPriv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}
   277  		// ecPriv.PrivateKey = priv.D.Bytes()
   278  		// return asn1.Marshal(ecPriv)
   279  	}
   280  	return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: failed to marshalECPrivateKeyWithOID: Unknown PrivateKey")
   281  }