...
1
15
16 package x509
17
18 import (
19 "crypto/rsa"
20 "encoding/asn1"
21 "errors"
22 "math/big"
23 )
24
25
26 type pkcs1PrivateKey struct {
27 Version int
28 N *big.Int
29 E int
30 D *big.Int
31 P *big.Int
32 Q *big.Int
33
34 Dp *big.Int `asn1:"optional"`
35 Dq *big.Int `asn1:"optional"`
36 Qinv *big.Int `asn1:"optional"`
37
38 AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional,omitempty"`
39 }
40
41 type pkcs1AdditionalRSAPrime struct {
42 Prime *big.Int
43
44
45 Exp *big.Int
46 Coeff *big.Int
47 }
48
49
50 func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) {
51 var priv pkcs1PrivateKey
52 rest, err := asn1.Unmarshal(der, &priv)
53 if len(rest) > 0 {
54 return nil, asn1.SyntaxError{Msg: "trailing data"}
55 }
56 if err != nil {
57 return nil, err
58 }
59
60 if priv.Version > 1 {
61 return nil, errors.New("x509: unsupported private key version")
62 }
63
64 if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 {
65 return nil, errors.New("x509: private key contains zero or negative value")
66 }
67
68 key := new(rsa.PrivateKey)
69 key.PublicKey = rsa.PublicKey{
70 E: priv.E,
71 N: priv.N,
72 }
73
74 key.D = priv.D
75 key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes))
76 key.Primes[0] = priv.P
77 key.Primes[1] = priv.Q
78 for i, a := range priv.AdditionalPrimes {
79 if a.Prime.Sign() <= 0 {
80 return nil, errors.New("x509: private key contains zero or negative prime")
81 }
82 key.Primes[i+2] = a.Prime
83
84
85 }
86
87 err = key.Validate()
88 if err != nil {
89 return nil, err
90 }
91 key.Precompute()
92
93 return key, nil
94 }
95
96
97 func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte {
98 key.Precompute()
99
100 version := 0
101 if len(key.Primes) > 2 {
102 version = 1
103 }
104
105 priv := pkcs1PrivateKey{
106 Version: version,
107 N: key.N,
108 E: key.PublicKey.E,
109 D: key.D,
110 P: key.Primes[0],
111 Q: key.Primes[1],
112 Dp: key.Precomputed.Dp,
113 Dq: key.Precomputed.Dq,
114 Qinv: key.Precomputed.Qinv,
115 }
116
117 priv.AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(key.Precomputed.CRTValues))
118 for i, values := range key.Precomputed.CRTValues {
119 priv.AdditionalPrimes[i].Prime = key.Primes[2+i]
120 priv.AdditionalPrimes[i].Exp = values.Exp
121 priv.AdditionalPrimes[i].Coeff = values.Coeff
122 }
123
124 b, _ := asn1.Marshal(priv)
125 return b
126 }
127
128
129 type rsaPublicKey struct {
130 N *big.Int
131 E int
132 }
133
View as plain text