github.com/Hyperledger-TWGC/tjfoc-gm@v1.4.0/x509/pkcs8.go (about)

     1  /*
     2  Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
     3  Licensed under the Apache License, Version 2.0 (the "License");
     4  you may not use this file except in compliance with the License.
     5  You may obtain a copy of the License at
     6  
     7  	http://www.apache.org/licenses/LICENSE-2.0
     8  
     9  Unless required by applicable law or agreed to in writing, software
    10  distributed under the License is distributed on an "AS IS" BASIS,
    11  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  See the License for the specific language governing permissions and
    13  limitations under the License.
    14  */
    15  
    16  package x509
    17  
    18  import (
    19  	"crypto/aes"
    20  	"crypto/cipher"
    21  	"crypto/elliptic"
    22  	"crypto/hmac"
    23  	"crypto/md5"
    24  	"crypto/rand"
    25  	"crypto/sha1"
    26  	"crypto/sha256"
    27  	"crypto/sha512"
    28  	"crypto/x509/pkix"
    29  	"encoding/asn1"
    30  	"errors"
    31  	"hash"
    32  	"math/big"
    33  	"reflect"
    34  
    35  	"github.com/Hyperledger-TWGC/tjfoc-gm/sm2"
    36  )
    37  
    38  /*
    39   * reference to RFC5959 and RFC2898
    40   */
    41  
    42  var (
    43  	oidPBES1  = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 3}  // pbeWithMD5AndDES-CBC(PBES1)
    44  	oidPBES2  = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 13} // id-PBES2(PBES2)
    45  	oidPBKDF2 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 12} // id-PBKDF2
    46  
    47  	oidKEYMD5    = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 5}
    48  	oidKEYSHA1   = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 7}
    49  	oidKEYSHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 9}
    50  	oidKEYSHA512 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 11}
    51  
    52  	oidAES128CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 2}
    53  	oidAES256CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42}
    54  
    55  	oidSM2 = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
    56  )
    57  
    58  // reference to https://www.rfc-editor.org/rfc/rfc5958.txt
    59  type PrivateKeyInfo struct {
    60  	Version             int // v1 or v2
    61  	PrivateKeyAlgorithm []asn1.ObjectIdentifier
    62  	PrivateKey          []byte
    63  }
    64  
    65  // reference to https://www.rfc-editor.org/rfc/rfc5958.txt
    66  type EncryptedPrivateKeyInfo struct {
    67  	EncryptionAlgorithm Pbes2Algorithms
    68  	EncryptedData       []byte
    69  }
    70  
    71  // reference to https://www.ietf.org/rfc/rfc2898.txt
    72  type Pbes2Algorithms struct {
    73  	IdPBES2     asn1.ObjectIdentifier
    74  	Pbes2Params Pbes2Params
    75  }
    76  
    77  // reference to https://www.ietf.org/rfc/rfc2898.txt
    78  type Pbes2Params struct {
    79  	KeyDerivationFunc Pbes2KDfs // PBES2-KDFs
    80  	EncryptionScheme  Pbes2Encs // PBES2-Encs
    81  }
    82  
    83  // reference to https://www.ietf.org/rfc/rfc2898.txt
    84  type Pbes2KDfs struct {
    85  	IdPBKDF2    asn1.ObjectIdentifier
    86  	Pkdf2Params Pkdf2Params
    87  }
    88  
    89  type Pbes2Encs struct {
    90  	EncryAlgo asn1.ObjectIdentifier
    91  	IV        []byte
    92  }
    93  
    94  // reference to https://www.ietf.org/rfc/rfc2898.txt
    95  type Pkdf2Params struct {
    96  	Salt           []byte
    97  	IterationCount int
    98  	Prf            pkix.AlgorithmIdentifier
    99  }
   100  
   101  type sm2PrivateKey struct {
   102  	Version       int
   103  	PrivateKey    []byte
   104  	NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
   105  	PublicKey     asn1.BitString        `asn1:"optional,explicit,tag:1"`
   106  }
   107  
   108  type pkcs8 struct {
   109  	Version    int
   110  	Algo       pkix.AlgorithmIdentifier
   111  	PrivateKey []byte
   112  }
   113  
   114  // copy from crypto/pbkdf2.go
   115  func pbkdf(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
   116  	prf := hmac.New(h, password)
   117  	hashLen := prf.Size()
   118  	numBlocks := (keyLen + hashLen - 1) / hashLen
   119  
   120  	var buf [4]byte
   121  	dk := make([]byte, 0, numBlocks*hashLen)
   122  	U := make([]byte, hashLen)
   123  	for block := 1; block <= numBlocks; block++ {
   124  		// N.B.: || means concatenation, ^ means XOR
   125  		// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
   126  		// U_1 = PRF(password, salt || uint(i))
   127  		prf.Reset()
   128  		prf.Write(salt)
   129  		buf[0] = byte(block >> 24)
   130  		buf[1] = byte(block >> 16)
   131  		buf[2] = byte(block >> 8)
   132  		buf[3] = byte(block)
   133  		prf.Write(buf[:4])
   134  		dk = prf.Sum(dk)
   135  		T := dk[len(dk)-hashLen:]
   136  		copy(U, T)
   137  
   138  		// U_n = PRF(password, U_(n-1))
   139  		for n := 2; n <= iter; n++ {
   140  			prf.Reset()
   141  			prf.Write(U)
   142  			U = U[:0]
   143  			U = prf.Sum(U)
   144  			for x := range U {
   145  				T[x] ^= U[x]
   146  			}
   147  		}
   148  	}
   149  	return dk[:keyLen]
   150  }
   151  
   152  func ParseSm2PublicKey(der []byte) (*sm2.PublicKey, error) {
   153  	var pubkey pkixPublicKey
   154  
   155  	if _, err := asn1.Unmarshal(der, &pubkey); err != nil {
   156  		return nil, err
   157  	}
   158  	if !reflect.DeepEqual(pubkey.Algo.Algorithm, oidSM2) {
   159  		return nil, errors.New("x509: not sm2 elliptic curve")
   160  	}
   161  	curve := sm2.P256Sm2()
   162  	x, y := elliptic.Unmarshal(curve, pubkey.BitString.Bytes)
   163  	pub := sm2.PublicKey{
   164  		Curve: curve,
   165  		X:     x,
   166  		Y:     y,
   167  	}
   168  	return &pub, nil
   169  }
   170  
   171  func MarshalSm2PublicKey(key *sm2.PublicKey) ([]byte, error) {
   172  	var r pkixPublicKey
   173  	var algo pkix.AlgorithmIdentifier
   174  
   175  	if(key.Curve.Params()!=sm2.P256Sm2().Params()){
   176  		return nil, errors.New("x509: unsupported elliptic curve")
   177  	}
   178  	algo.Algorithm = oidSM2
   179  	algo.Parameters.Class = 0
   180  	algo.Parameters.Tag = 6
   181  	algo.Parameters.IsCompound = false
   182  	algo.Parameters.FullBytes = []byte{6, 8, 42, 129, 28, 207, 85, 1, 130, 45} // asn1.Marshal(asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301})
   183  	r.Algo = algo
   184  	r.BitString = asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}
   185  	return asn1.Marshal(r)
   186  }
   187  
   188  func ParseSm2PrivateKey(der []byte) (*sm2.PrivateKey, error) {
   189  	var privKey sm2PrivateKey
   190  
   191  	if _, err := asn1.Unmarshal(der, &privKey); err != nil {
   192  		return nil, errors.New("x509: failed to parse SM2 private key: " + err.Error())
   193  	}
   194  	curve := sm2.P256Sm2()
   195  	k := new(big.Int).SetBytes(privKey.PrivateKey)
   196  	curveOrder := curve.Params().N
   197  	if k.Cmp(curveOrder) >= 0 {
   198  		return nil, errors.New("x509: invalid elliptic curve private key value")
   199  	}
   200  	priv := new(sm2.PrivateKey)
   201  	priv.Curve = curve
   202  	priv.D = k
   203  	privateKey := make([]byte, (curveOrder.BitLen()+7)/8)
   204  	for len(privKey.PrivateKey) > len(privateKey) {
   205  		if privKey.PrivateKey[0] != 0 {
   206  			return nil, errors.New("x509: invalid private key length")
   207  		}
   208  		privKey.PrivateKey = privKey.PrivateKey[1:]
   209  	}
   210  	copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
   211  	priv.X, priv.Y = curve.ScalarBaseMult(privateKey)
   212  	return priv, nil
   213  }
   214  
   215  func ParsePKCS8UnecryptedPrivateKey(der []byte) (*sm2.PrivateKey, error) {
   216  	var privKey pkcs8
   217  
   218  	if _, err := asn1.Unmarshal(der, &privKey); err != nil {
   219  		return nil, err
   220  	}
   221  	if !reflect.DeepEqual(privKey.Algo.Algorithm, oidSM2) {
   222  		return nil, errors.New("x509: not sm2 elliptic curve")
   223  	}
   224  	return ParseSm2PrivateKey(privKey.PrivateKey)
   225  }
   226  
   227  func ParsePKCS8EcryptedPrivateKey(der, pwd []byte) (*sm2.PrivateKey, error) {
   228  	var keyInfo EncryptedPrivateKeyInfo
   229  
   230  	_, err := asn1.Unmarshal(der, &keyInfo)
   231  	if err != nil {
   232  		return nil, errors.New("x509: unknown format")
   233  	}
   234  	if !reflect.DeepEqual(keyInfo.EncryptionAlgorithm.IdPBES2, oidPBES2) {
   235  		return nil, errors.New("x509: only support PBES2")
   236  	}
   237  	encryptionScheme := keyInfo.EncryptionAlgorithm.Pbes2Params.EncryptionScheme
   238  	keyDerivationFunc := keyInfo.EncryptionAlgorithm.Pbes2Params.KeyDerivationFunc
   239  	if !reflect.DeepEqual(keyDerivationFunc.IdPBKDF2, oidPBKDF2) {
   240  		return nil, errors.New("x509: only support PBKDF2")
   241  	}
   242  	pkdf2Params := keyDerivationFunc.Pkdf2Params
   243  	if !reflect.DeepEqual(encryptionScheme.EncryAlgo, oidAES128CBC) &&
   244  		!reflect.DeepEqual(encryptionScheme.EncryAlgo, oidAES256CBC) {
   245  		return nil, errors.New("x509: unknow encryption algorithm")
   246  	}
   247  	iv := encryptionScheme.IV
   248  	salt := pkdf2Params.Salt
   249  	iter := pkdf2Params.IterationCount
   250  	encryptedKey := keyInfo.EncryptedData
   251  	var key []byte
   252  	switch {
   253  	case pkdf2Params.Prf.Algorithm.Equal(oidKEYMD5):
   254  		key = pbkdf(pwd, salt, iter, 32, md5.New)
   255  		break
   256  	case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA1):
   257  		key = pbkdf(pwd, salt, iter, 32, sha1.New)
   258  		break
   259  	case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA256):
   260  		key = pbkdf(pwd, salt, iter, 32, sha256.New)
   261  		break
   262  	case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA512):
   263  		key = pbkdf(pwd, salt, iter, 32, sha512.New)
   264  		break
   265  	default:
   266  		return nil, errors.New("x509: unknown hash algorithm")
   267  	}
   268  	block, err := aes.NewCipher(key)
   269  	if err != nil {
   270  		return nil, err
   271  	}
   272  	mode := cipher.NewCBCDecrypter(block, iv)
   273  	mode.CryptBlocks(encryptedKey, encryptedKey)
   274  	rKey, err := ParsePKCS8UnecryptedPrivateKey(encryptedKey)
   275  	if err != nil {
   276  		return nil, errors.New("pkcs8: incorrect password")
   277  	}
   278  	return rKey, nil
   279  }
   280  
   281  func ParsePKCS8PrivateKey(der, pwd []byte) (*sm2.PrivateKey, error) {
   282  	if pwd == nil {
   283  		
   284  		return ParsePKCS8UnecryptedPrivateKey(der)
   285  	}
   286  	return ParsePKCS8EcryptedPrivateKey(der, pwd)
   287  }
   288  
   289  func MarshalSm2UnecryptedPrivateKey(key *sm2.PrivateKey) ([]byte, error) {
   290  	var r pkcs8
   291  	var priv sm2PrivateKey
   292  	var algo pkix.AlgorithmIdentifier
   293  
   294  	algo.Algorithm = oidSM2
   295  	algo.Parameters.Class = 0
   296  	algo.Parameters.Tag = 6
   297  	algo.Parameters.IsCompound = false
   298  	algo.Parameters.FullBytes = []byte{6, 8, 42, 129, 28, 207, 85, 1, 130, 45} // asn1.Marshal(asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301})
   299  	priv.Version = 1
   300  	priv.NamedCurveOID = oidNamedCurveP256SM2
   301  	priv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}
   302  	priv.PrivateKey = key.D.Bytes()
   303  	r.Version = 0
   304  	r.Algo = algo
   305  	r.PrivateKey, _ = asn1.Marshal(priv)
   306  	return asn1.Marshal(r)
   307  }
   308  
   309  func MarshalSm2EcryptedPrivateKey(PrivKey *sm2.PrivateKey, pwd []byte) ([]byte, error) {
   310  	der, err := MarshalSm2UnecryptedPrivateKey(PrivKey)
   311  	if err != nil {
   312  		return nil, err
   313  	}
   314  	iter := 2048
   315  	salt := make([]byte, 8)
   316  	iv := make([]byte, 16)
   317  	rand.Reader.Read(salt)
   318  	rand.Reader.Read(iv)
   319  	key := pbkdf(pwd, salt, iter, 32, sha1.New) // 默认是SHA1
   320  	padding := aes.BlockSize - len(der)%aes.BlockSize
   321  	if padding > 0 {
   322  		n := len(der)
   323  		der = append(der, make([]byte, padding)...)
   324  		for i := 0; i < padding; i++ {
   325  			der[n+i] = byte(padding)
   326  		}
   327  	}
   328  	encryptedKey := make([]byte, len(der))
   329  	block, err := aes.NewCipher(key)
   330  	if err != nil {
   331  		return nil, err
   332  	}
   333  	mode := cipher.NewCBCEncrypter(block, iv)
   334  	mode.CryptBlocks(encryptedKey, der)
   335  	var algorithmIdentifier pkix.AlgorithmIdentifier
   336  	algorithmIdentifier.Algorithm = oidKEYSHA1
   337  	algorithmIdentifier.Parameters.Tag = 5
   338  	algorithmIdentifier.Parameters.IsCompound = false
   339  	algorithmIdentifier.Parameters.FullBytes = []byte{5, 0}
   340  	keyDerivationFunc := Pbes2KDfs{
   341  		oidPBKDF2,
   342  		Pkdf2Params{
   343  			salt,
   344  			iter,
   345  			algorithmIdentifier,
   346  		},
   347  	}
   348  	encryptionScheme := Pbes2Encs{
   349  		oidAES256CBC,
   350  		iv,
   351  	}
   352  	pbes2Algorithms := Pbes2Algorithms{
   353  		oidPBES2,
   354  		Pbes2Params{
   355  			keyDerivationFunc,
   356  			encryptionScheme,
   357  		},
   358  	}
   359  	encryptedPkey := EncryptedPrivateKeyInfo{
   360  		pbes2Algorithms,
   361  		encryptedKey,
   362  	}
   363  	return asn1.Marshal(encryptedPkey)
   364  }
   365  
   366  func MarshalSm2PrivateKey(key *sm2.PrivateKey, pwd []byte) ([]byte, error) {
   367  	if pwd == nil {
   368  		return MarshalSm2UnecryptedPrivateKey(key)
   369  	}
   370  	return MarshalSm2EcryptedPrivateKey(key, pwd)
   371  }
   372