OSDN Git Service

Hulk did something
[bytom/vapor.git] / crypto / sm2 / pkcs8.go
1 package sm2
2
3 import (
4         "crypto/aes"
5         "crypto/cipher"
6         "crypto/elliptic"
7         "crypto/hmac"
8         "crypto/md5"
9         "crypto/rand"
10         "crypto/sha1"
11         "crypto/sha256"
12         "crypto/sha512"
13         "crypto/x509/pkix"
14         "encoding/asn1"
15         "encoding/pem"
16         "errors"
17         "hash"
18         "io/ioutil"
19         "math/big"
20         "os"
21         "reflect"
22 )
23
24 /*
25  * reference to RFC5959 and RFC2898
26  */
27
28 var (
29         oidPBES1  = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 3}  // pbeWithMD5AndDES-CBC(PBES1)
30         oidPBES2  = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 13} // id-PBES2(PBES2)
31         oidPBKDF2 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 12} // id-PBKDF2
32
33         oidKEYMD5    = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 5}
34         oidKEYSHA1   = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 7}
35         oidKEYSHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 9}
36         oidKEYSHA512 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 11}
37
38         oidAES128CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 2}
39         oidAES256CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42}
40
41         oidSM2 = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
42 )
43
44 // reference to https://www.rfc-editor.org/rfc/rfc5958.txt
45 type PrivateKeyInfo struct {
46         Version             int // v1 or v2
47         PrivateKeyAlgorithm []asn1.ObjectIdentifier
48         PrivateKey          []byte
49 }
50
51 // reference to https://www.rfc-editor.org/rfc/rfc5958.txt
52 type EncryptedPrivateKeyInfo struct {
53         EncryptionAlgorithm Pbes2Algorithms
54         EncryptedData       []byte
55 }
56
57 // reference to https://www.ietf.org/rfc/rfc2898.txt
58 type Pbes2Algorithms struct {
59         IdPBES2     asn1.ObjectIdentifier
60         Pbes2Params Pbes2Params
61 }
62
63 // reference to https://www.ietf.org/rfc/rfc2898.txt
64 type Pbes2Params struct {
65         KeyDerivationFunc Pbes2KDfs // PBES2-KDFs
66         EncryptionScheme  Pbes2Encs // PBES2-Encs
67 }
68
69 // reference to https://www.ietf.org/rfc/rfc2898.txt
70 type Pbes2KDfs struct {
71         IdPBKDF2    asn1.ObjectIdentifier
72         Pkdf2Params Pkdf2Params
73 }
74
75 type Pbes2Encs struct {
76         EncryAlgo asn1.ObjectIdentifier
77         IV        []byte
78 }
79
80 // reference to https://www.ietf.org/rfc/rfc2898.txt
81 type Pkdf2Params struct {
82         Salt           []byte
83         IterationCount int
84         Prf            pkix.AlgorithmIdentifier
85 }
86
87 type sm2PrivateKey struct {
88         Version       int
89         PrivateKey    []byte
90         NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
91         PublicKey     asn1.BitString        `asn1:"optional,explicit,tag:1"`
92 }
93
94 type pkcs8 struct {
95         Version    int
96         Algo       pkix.AlgorithmIdentifier
97         PrivateKey []byte
98 }
99
100 // copy from crypto/pbkdf2.go
101 func pbkdf(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
102         prf := hmac.New(h, password)
103         hashLen := prf.Size()
104         numBlocks := (keyLen + hashLen - 1) / hashLen
105
106         var buf [4]byte
107         dk := make([]byte, 0, numBlocks*hashLen)
108         U := make([]byte, hashLen)
109         for block := 1; block <= numBlocks; block++ {
110                 // N.B.: || means concatenation, ^ means XOR
111                 // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
112                 // U_1 = PRF(password, salt || uint(i))
113                 prf.Reset()
114                 prf.Write(salt)
115                 buf[0] = byte(block >> 24)
116                 buf[1] = byte(block >> 16)
117                 buf[2] = byte(block >> 8)
118                 buf[3] = byte(block)
119                 prf.Write(buf[:4])
120                 dk = prf.Sum(dk)
121                 T := dk[len(dk)-hashLen:]
122                 copy(U, T)
123
124                 // U_n = PRF(password, U_(n-1))
125                 for n := 2; n <= iter; n++ {
126                         prf.Reset()
127                         prf.Write(U)
128                         U = U[:0]
129                         U = prf.Sum(U)
130                         for x := range U {
131                                 T[x] ^= U[x]
132                         }
133                 }
134         }
135         return dk[:keyLen]
136 }
137
138 func ParseSm2PublicKey(der []byte) (*PublicKey, error) {
139         var pubkey pkixPublicKey
140
141         if _, err := asn1.Unmarshal(der, &pubkey); err != nil {
142                 return nil, err
143         }
144         if !reflect.DeepEqual(pubkey.Algo.Algorithm, oidSM2) {
145                 return nil, errors.New("x509: not sm2 elliptic curve")
146         }
147         curve := P256Sm2()
148         x, y := elliptic.Unmarshal(curve, pubkey.BitString.Bytes)
149         pub := PublicKey{
150                 Curve: curve,
151                 X:     x,
152                 Y:     y,
153         }
154         return &pub, nil
155 }
156
157 func MarshalSm2PublicKey(key *PublicKey) ([]byte, error) {
158         var r pkixPublicKey
159         var algo pkix.AlgorithmIdentifier
160
161         algo.Algorithm = oidSM2
162         algo.Parameters.Class = 0
163         algo.Parameters.Tag = 6
164         algo.Parameters.IsCompound = false
165         algo.Parameters.FullBytes = []byte{6, 8, 42, 129, 28, 207, 85, 1, 130, 45} // asn1.Marshal(asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301})
166         r.Algo = algo
167         r.BitString = asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}
168         return asn1.Marshal(r)
169 }
170
171 func ParseSm2PrivateKey(der []byte) (*PrivateKey, error) {
172         var privKey sm2PrivateKey
173
174         if _, err := asn1.Unmarshal(der, &privKey); err != nil {
175                 return nil, errors.New("x509: failed to parse SM2 private key: " + err.Error())
176         }
177         curve := P256Sm2()
178         k := new(big.Int).SetBytes(privKey.PrivateKey)
179         curveOrder := curve.Params().N
180         if k.Cmp(curveOrder) >= 0 {
181                 return nil, errors.New("x509: invalid elliptic curve private key value")
182         }
183         priv := new(PrivateKey)
184         priv.Curve = curve
185         priv.D = k
186         privateKey := make([]byte, (curveOrder.BitLen()+7)/8)
187         for len(privKey.PrivateKey) > len(privateKey) {
188                 if privKey.PrivateKey[0] != 0 {
189                         return nil, errors.New("x509: invalid private key length")
190                 }
191                 privKey.PrivateKey = privKey.PrivateKey[1:]
192         }
193         copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
194         priv.X, priv.Y = curve.ScalarBaseMult(privateKey)
195         return priv, nil
196 }
197
198 func ParsePKCS8UnecryptedPrivateKey(der []byte) (*PrivateKey, error) {
199         var privKey pkcs8
200
201         if _, err := asn1.Unmarshal(der, &privKey); err != nil {
202                 return nil, err
203         }
204         if !reflect.DeepEqual(privKey.Algo.Algorithm, oidSM2) {
205                 return nil, errors.New("x509: not sm2 elliptic curve")
206         }
207         return ParseSm2PrivateKey(privKey.PrivateKey)
208 }
209
210 func ParsePKCS8EcryptedPrivateKey(der, pwd []byte) (*PrivateKey, error) {
211         var keyInfo EncryptedPrivateKeyInfo
212
213         _, err := asn1.Unmarshal(der, &keyInfo)
214         if err != nil {
215                 return nil, errors.New("x509: unknown format")
216         }
217         if !reflect.DeepEqual(keyInfo.EncryptionAlgorithm.IdPBES2, oidPBES2) {
218                 return nil, errors.New("x509: only support PBES2")
219         }
220         encryptionScheme := keyInfo.EncryptionAlgorithm.Pbes2Params.EncryptionScheme
221         keyDerivationFunc := keyInfo.EncryptionAlgorithm.Pbes2Params.KeyDerivationFunc
222         if !reflect.DeepEqual(keyDerivationFunc.IdPBKDF2, oidPBKDF2) {
223                 return nil, errors.New("x509: only support PBKDF2")
224         }
225         pkdf2Params := keyDerivationFunc.Pkdf2Params
226         if !reflect.DeepEqual(encryptionScheme.EncryAlgo, oidAES128CBC) &&
227                 !reflect.DeepEqual(encryptionScheme.EncryAlgo, oidAES256CBC) {
228                 return nil, errors.New("x509: unknow encryption algorithm")
229         }
230         iv := encryptionScheme.IV
231         salt := pkdf2Params.Salt
232         iter := pkdf2Params.IterationCount
233         encryptedKey := keyInfo.EncryptedData
234         var key []byte
235         switch {
236         case pkdf2Params.Prf.Algorithm.Equal(oidKEYMD5):
237                 key = pbkdf(pwd, salt, iter, 32, md5.New)
238                 break
239         case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA1):
240                 key = pbkdf(pwd, salt, iter, 32, sha1.New)
241                 break
242         case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA256):
243                 key = pbkdf(pwd, salt, iter, 32, sha256.New)
244                 break
245         case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA512):
246                 key = pbkdf(pwd, salt, iter, 32, sha512.New)
247                 break
248         default:
249                 return nil, errors.New("x509: unknown hash algorithm")
250         }
251         block, err := aes.NewCipher(key)
252         if err != nil {
253                 return nil, err
254         }
255         mode := cipher.NewCBCDecrypter(block, iv)
256         mode.CryptBlocks(encryptedKey, encryptedKey)
257         rKey, err := ParsePKCS8UnecryptedPrivateKey(encryptedKey)
258         if err != nil {
259                 return nil, errors.New("pkcs8: incorrect password")
260         }
261         return rKey, nil
262 }
263
264 func ParsePKCS8PrivateKey(der, pwd []byte) (*PrivateKey, error) {
265         if pwd == nil {
266                 return ParsePKCS8UnecryptedPrivateKey(der)
267         }
268         return ParsePKCS8EcryptedPrivateKey(der, pwd)
269 }
270
271 func MarshalSm2UnecryptedPrivateKey(key *PrivateKey) ([]byte, error) {
272         var r pkcs8
273         var priv sm2PrivateKey
274         var algo pkix.AlgorithmIdentifier
275
276         algo.Algorithm = oidSM2
277         algo.Parameters.Class = 0
278         algo.Parameters.Tag = 6
279         algo.Parameters.IsCompound = false
280         algo.Parameters.FullBytes = []byte{6, 8, 42, 129, 28, 207, 85, 1, 130, 45} // asn1.Marshal(asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301})
281         priv.Version = 1
282         priv.NamedCurveOID = oidNamedCurveP256SM2
283         priv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}
284         priv.PrivateKey = key.D.Bytes()
285         r.Version = 0
286         r.Algo = algo
287         r.PrivateKey, _ = asn1.Marshal(priv)
288         return asn1.Marshal(r)
289 }
290
291 func MarshalSm2EcryptedPrivateKey(PrivKey *PrivateKey, pwd []byte) ([]byte, error) {
292         der, err := MarshalSm2UnecryptedPrivateKey(PrivKey)
293         if err != nil {
294                 return nil, err
295         }
296         iter := 2048
297         salt := make([]byte, 8)
298         iv := make([]byte, 16)
299         rand.Reader.Read(salt)
300         rand.Reader.Read(iv)
301         key := pbkdf(pwd, salt, iter, 32, sha1.New) // 默认是SHA1
302         padding := aes.BlockSize - len(der)%aes.BlockSize
303         if padding > 0 {
304                 n := len(der)
305                 der = append(der, make([]byte, padding)...)
306                 for i := 0; i < padding; i++ {
307                         der[n+i] = byte(padding)
308                 }
309         }
310         encryptedKey := make([]byte, len(der))
311         block, err := aes.NewCipher(key)
312         if err != nil {
313                 return nil, err
314         }
315         mode := cipher.NewCBCEncrypter(block, iv)
316         mode.CryptBlocks(encryptedKey, der)
317         var algorithmIdentifier pkix.AlgorithmIdentifier
318         algorithmIdentifier.Algorithm = oidKEYSHA1
319         algorithmIdentifier.Parameters.Tag = 5
320         algorithmIdentifier.Parameters.IsCompound = false
321         algorithmIdentifier.Parameters.FullBytes = []byte{5, 0}
322         keyDerivationFunc := Pbes2KDfs{
323                 oidPBKDF2,
324                 Pkdf2Params{
325                         salt,
326                         iter,
327                         algorithmIdentifier,
328                 },
329         }
330         encryptionScheme := Pbes2Encs{
331                 oidAES256CBC,
332                 iv,
333         }
334         pbes2Algorithms := Pbes2Algorithms{
335                 oidPBES2,
336                 Pbes2Params{
337                         keyDerivationFunc,
338                         encryptionScheme,
339                 },
340         }
341         encryptedPkey := EncryptedPrivateKeyInfo{
342                 pbes2Algorithms,
343                 encryptedKey,
344         }
345         return asn1.Marshal(encryptedPkey)
346 }
347
348 func MarshalSm2PrivateKey(key *PrivateKey, pwd []byte) ([]byte, error) {
349         if pwd == nil {
350                 return MarshalSm2UnecryptedPrivateKey(key)
351         }
352         return MarshalSm2EcryptedPrivateKey(key, pwd)
353 }
354
355 func ReadPrivateKeyFromMem(data []byte, pwd []byte) (*PrivateKey, error) {
356         var block *pem.Block
357
358         block, _ = pem.Decode(data)
359         if block == nil {
360                 return nil, errors.New("failed to decode private key")
361         }
362         priv, err := ParsePKCS8PrivateKey(block.Bytes, pwd)
363         return priv, err
364 }
365
366 func ReadPrivateKeyFromPem(FileName string, pwd []byte) (*PrivateKey, error) {
367         data, err := ioutil.ReadFile(FileName)
368         if err != nil {
369                 return nil, err
370         }
371         return ReadPrivateKeyFromMem(data, pwd)
372 }
373
374 func WritePrivateKeytoMem(key *PrivateKey, pwd []byte) ([]byte, error) {
375         var block *pem.Block
376
377         der, err := MarshalSm2PrivateKey(key, pwd)
378         if err != nil {
379                 return nil, err
380         }
381         if pwd != nil {
382                 block = &pem.Block{
383                         Type:  "ENCRYPTED PRIVATE KEY",
384                         Bytes: der,
385                 }
386         } else {
387                 block = &pem.Block{
388                         Type:  "PRIVATE KEY",
389                         Bytes: der,
390                 }
391         }
392         return pem.EncodeToMemory(block), nil
393 }
394
395 func WritePrivateKeytoPem(FileName string, key *PrivateKey, pwd []byte) (bool, error) {
396         var block *pem.Block
397
398         der, err := MarshalSm2PrivateKey(key, pwd)
399         if err != nil {
400                 return false, err
401         }
402         if pwd != nil {
403                 block = &pem.Block{
404                         Type:  "ENCRYPTED PRIVATE KEY",
405                         Bytes: der,
406                 }
407         } else {
408                 block = &pem.Block{
409                         Type:  "PRIVATE KEY",
410                         Bytes: der,
411                 }
412         }
413         file, err := os.Create(FileName)
414         if err != nil {
415                 return false, err
416         }
417         defer file.Close()
418         err = pem.Encode(file, block)
419         if err != nil {
420                 return false, err
421         }
422         return true, nil
423 }
424
425 func ReadPublicKeyFromMem(data []byte, _ []byte) (*PublicKey, error) {
426         block, _ := pem.Decode(data)
427         if block == nil || block.Type != "PUBLIC KEY" {
428                 return nil, errors.New("failed to decode public key")
429         }
430         pub, err := ParseSm2PublicKey(block.Bytes)
431         return pub, err
432 }
433
434 func ReadPublicKeyFromPem(FileName string, pwd []byte) (*PublicKey, error) {
435         data, err := ioutil.ReadFile(FileName)
436         if err != nil {
437                 return nil, err
438         }
439         return ReadPublicKeyFromMem(data, pwd)
440 }
441
442 func WritePublicKeytoMem(key *PublicKey, _ []byte) ([]byte, error) {
443         der, err := MarshalSm2PublicKey(key)
444         if err != nil {
445                 return nil, err
446         }
447         block := &pem.Block{
448                 Type:  "PUBLIC KEY",
449                 Bytes: der,
450         }
451         return pem.EncodeToMemory(block), nil
452 }
453
454 func WritePublicKeytoPem(FileName string, key *PublicKey, _ []byte) (bool, error) {
455         der, err := MarshalSm2PublicKey(key)
456         if err != nil {
457                 return false, err
458         }
459         block := &pem.Block{
460                 Type:  "PUBLIC KEY",
461                 Bytes: der,
462         }
463         file, err := os.Create(FileName)
464         defer file.Close()
465         if err != nil {
466                 return false, err
467         }
468         err = pem.Encode(file, block)
469         if err != nil {
470                 return false, err
471         }
472         return true, nil
473 }