1
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/tjfoc/gmsm/sm2"
36 )
37
38
41
42 var (
43 oidPBES1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 3}
44 oidPBES2 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 13}
45 oidPBKDF2 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 12}
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
59 type PrivateKeyInfo struct {
60 Version int
61 PrivateKeyAlgorithm []asn1.ObjectIdentifier
62 PrivateKey []byte
63 }
64
65
66 type EncryptedPrivateKeyInfo struct {
67 EncryptionAlgorithm Pbes2Algorithms
68 EncryptedData []byte
69 }
70
71
72 type Pbes2Algorithms struct {
73 IdPBES2 asn1.ObjectIdentifier
74 Pbes2Params Pbes2Params
75 }
76
77
78 type Pbes2Params struct {
79 KeyDerivationFunc Pbes2KDfs
80 EncryptionScheme Pbes2Encs
81 }
82
83
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
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
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
125
126
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
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}
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}
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)
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
View as plain text