OSDN Git Service

new repo
[bytom/vapor.git] / crypto / sm2 / pkcs1.go
1 package sm2
2
3 import (
4         "crypto/rsa"
5         "encoding/asn1"
6         "errors"
7         "math/big"
8 )
9
10 // pkcs1PrivateKey is a structure which mirrors the PKCS#1 ASN.1 for an RSA private key.
11 type pkcs1PrivateKey struct {
12         Version int
13         N       *big.Int
14         E       int
15         D       *big.Int
16         P       *big.Int
17         Q       *big.Int
18         // We ignore these values, if present, because rsa will calculate them.
19         Dp   *big.Int `asn1:"optional"`
20         Dq   *big.Int `asn1:"optional"`
21         Qinv *big.Int `asn1:"optional"`
22
23         AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional,omitempty"`
24 }
25
26 type pkcs1AdditionalRSAPrime struct {
27         Prime *big.Int
28
29         // We ignore these values because rsa will calculate them.
30         Exp   *big.Int
31         Coeff *big.Int
32 }
33
34 // ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER encoded form.
35 func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) {
36         var priv pkcs1PrivateKey
37         rest, err := asn1.Unmarshal(der, &priv)
38         if len(rest) > 0 {
39                 return nil, asn1.SyntaxError{Msg: "trailing data"}
40         }
41         if err != nil {
42                 return nil, err
43         }
44
45         if priv.Version > 1 {
46                 return nil, errors.New("x509: unsupported private key version")
47         }
48
49         if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 {
50                 return nil, errors.New("x509: private key contains zero or negative value")
51         }
52
53         key := new(rsa.PrivateKey)
54         key.PublicKey = rsa.PublicKey{
55                 E: priv.E,
56                 N: priv.N,
57         }
58
59         key.D = priv.D
60         key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes))
61         key.Primes[0] = priv.P
62         key.Primes[1] = priv.Q
63         for i, a := range priv.AdditionalPrimes {
64                 if a.Prime.Sign() <= 0 {
65                         return nil, errors.New("x509: private key contains zero or negative prime")
66                 }
67                 key.Primes[i+2] = a.Prime
68                 // We ignore the other two values because rsa will calculate
69                 // them as needed.
70         }
71
72         err = key.Validate()
73         if err != nil {
74                 return nil, err
75         }
76         key.Precompute()
77
78         return key, nil
79 }
80
81 // MarshalPKCS1PrivateKey converts a private key to ASN.1 DER encoded form.
82 func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte {
83         key.Precompute()
84
85         version := 0
86         if len(key.Primes) > 2 {
87                 version = 1
88         }
89
90         priv := pkcs1PrivateKey{
91                 Version: version,
92                 N:       key.N,
93                 E:       key.PublicKey.E,
94                 D:       key.D,
95                 P:       key.Primes[0],
96                 Q:       key.Primes[1],
97                 Dp:      key.Precomputed.Dp,
98                 Dq:      key.Precomputed.Dq,
99                 Qinv:    key.Precomputed.Qinv,
100         }
101
102         priv.AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(key.Precomputed.CRTValues))
103         for i, values := range key.Precomputed.CRTValues {
104                 priv.AdditionalPrimes[i].Prime = key.Primes[2+i]
105                 priv.AdditionalPrimes[i].Exp = values.Exp
106                 priv.AdditionalPrimes[i].Coeff = values.Coeff
107         }
108
109         b, _ := asn1.Marshal(priv)
110         return b
111 }
112
113 // rsaPublicKey reflects the ASN.1 structure of a PKCS#1 public key.
114 type rsaPublicKey struct {
115         N *big.Int
116         E int
117 }