Skip to content

Commit 301c84d

Browse files
author
czdsdo
committed
公私钥证书统一使用Pem文件格式存储
1 parent 7caf961 commit 301c84d

File tree

2 files changed

+167
-220
lines changed

2 files changed

+167
-220
lines changed

x509/utils.go

Lines changed: 167 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
package x509
22

33
import (
4+
"bytes"
5+
"crypto"
6+
"crypto/rand"
7+
"crypto/rsa"
8+
"encoding/asn1"
49
"encoding/pem"
510
"errors"
611
"github.com/Hyperledger-TWGC/tjfoc-gm/sm2"
712
"io/ioutil"
813
"os"
914
)
1015

11-
func ReadPrivateKeyFromMem(data []byte, pwd []byte) (*sm2.PrivateKey, error) {
16+
func ReadPrivateKeyFromPem(FileName string, pwd []byte) (*sm2.PrivateKey, error) {
17+
data, err := ioutil.ReadFile(FileName)
18+
if err != nil {
19+
return nil, err
20+
}
1221
var block *pem.Block
13-
1422
block, _ = pem.Decode(data)
1523
if block == nil {
1624
return nil, errors.New("failed to decode private key")
@@ -19,20 +27,11 @@ func ReadPrivateKeyFromMem(data []byte, pwd []byte) (*sm2.PrivateKey, error) {
1927
return priv, err
2028
}
2129

22-
func ReadPrivateKeyFromPem(FileName string, pwd []byte) (*sm2.PrivateKey, error) {
23-
data, err := ioutil.ReadFile(FileName)
24-
if err != nil {
25-
return nil, err
26-
}
27-
return ReadPrivateKeyFromMem(data, pwd)
28-
}
29-
30-
func WritePrivateKeytoMem(key *sm2.PrivateKey, pwd []byte) ([]byte, error) {
30+
func WritePrivateKeytoPem(FileName string, key *sm2.PrivateKey, pwd []byte) (err error) {
3131
var block *pem.Block
32-
3332
der, err := MarshalSm2PrivateKey(key, pwd)
3433
if err != nil {
35-
return nil, err
34+
return err
3635
}
3736
if pwd != nil {
3837
block = &pem.Block{
@@ -45,15 +44,7 @@ func WritePrivateKeytoMem(key *sm2.PrivateKey, pwd []byte) ([]byte, error) {
4544
Bytes: der,
4645
}
4746
}
48-
return pem.EncodeToMemory(block), nil
49-
}
50-
51-
func WritePrivateKeytoPem(FileName string, key *sm2.PrivateKey, pwd []byte) (err error) {
52-
certPem, err := WritePrivateKeytoMem(key, pwd)
53-
if err != nil {
54-
return err
55-
}
56-
47+
certPem := pem.EncodeToMemory(block)
5748
file, err := os.Create(FileName)
5849
if err != nil {
5950
return err
@@ -68,48 +59,187 @@ func WritePrivateKeytoPem(FileName string, key *sm2.PrivateKey, pwd []byte) (err
6859
return nil
6960
}
7061

71-
func ReadPublicKeyFromMem(data []byte) (*sm2.PublicKey, error) {
62+
func ReadPublicKeyFromPem(FileName string) (*sm2.PublicKey, error) {
63+
data, err := ioutil.ReadFile(FileName)
64+
if err != nil {
65+
return nil, err
66+
}
7267
block, _ := pem.Decode(data)
7368
if block == nil || block.Type != "PUBLIC KEY" {
7469
return nil, errors.New("failed to decode public key")
7570
}
76-
pub, err := ParseSm2PublicKey(block.Bytes)
77-
return pub, err
71+
return ParseSm2PublicKey(block.Bytes)
7872
}
7973

80-
func ReadPublicKeyFromPem(FileName string) (*sm2.PublicKey, error) {
74+
func WritePublicKeytoPem(FileName string, key *sm2.PublicKey) (err error) {
75+
der, err := MarshalSm2PublicKey(key)
76+
if err != nil {
77+
return err
78+
}
79+
block := &pem.Block{
80+
Type: "PUBLIC KEY",
81+
Bytes: der,
82+
}
83+
certPem := pem.EncodeToMemory(block)
84+
file, err := os.Create(FileName)
85+
defer func() {
86+
err = file.Close()
87+
}()
88+
if err != nil {
89+
return err
90+
}
91+
_, err = file.Write(certPem)
92+
if err != nil {
93+
return err
94+
}
95+
return nil
96+
}
97+
98+
func ReadCertificateRequestFromPem(FileName string) (*CertificateRequest, error) {
8199
data, err := ioutil.ReadFile(FileName)
82100
if err != nil {
83101
return nil, err
84102
}
85-
return ReadPublicKeyFromMem(data)
103+
block, _ := pem.Decode(data)
104+
if block == nil {
105+
return nil, errors.New("failed to decode certificate request")
106+
}
107+
return ParseCertificateRequest(block.Bytes)
86108
}
87109

88-
func WritePublicKeytoMem(key *sm2.PublicKey) ([]byte, error) {
89-
der, err := MarshalSm2PublicKey(key)
110+
func CreateCertificateRequestToPem(FileName string, template *CertificateRequest, privKey *sm2.PrivateKey) error {
111+
der, err := CreateCertificateRequest(rand.Reader, template, privKey)
90112
if err != nil {
91-
return nil, err
113+
return err
92114
}
93115
block := &pem.Block{
94-
Type: "PUBLIC KEY",
116+
Type: "CERTIFICATE REQUEST",
95117
Bytes: der,
96118
}
97-
return pem.EncodeToMemory(block), nil
119+
file, err := os.Create(FileName)
120+
if err != nil {
121+
return err
122+
}
123+
defer func() {
124+
err = file.Close()
125+
}()
126+
err = pem.Encode(file, block)
127+
if err != nil {
128+
return err
129+
}
130+
return nil
98131
}
99132

100-
func WritePublicKeytoPem(FileName string, key *sm2.PublicKey) (err error) {
101-
certPem, err := WritePublicKeytoMem(key)
133+
func ReadCertificateFromPem(FileName string) (*Certificate, error) {
134+
data, err := ioutil.ReadFile(FileName)
135+
if err != nil {
136+
return nil, err
137+
}
138+
block, _ := pem.Decode(data)
139+
if block == nil {
140+
return nil, errors.New("failed to decode certificate request")
141+
}
142+
return ParseCertificate(block.Bytes)
143+
}
144+
145+
func CreateCertificateToPem(FileName string, template, parent *Certificate, pubKey *sm2.PublicKey, privKey *sm2.PrivateKey) error {
146+
if template.SerialNumber == nil {
147+
return errors.New("x509: no SerialNumber given")
148+
}
149+
150+
hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(privKey.Public(), template.SignatureAlgorithm)
151+
if err != nil {
152+
return err
153+
}
154+
155+
publicKeyBytes, publicKeyAlgorithm, err := marshalPublicKey(pubKey)
156+
if err != nil {
157+
return err
158+
}
159+
160+
asn1Issuer, err := subjectBytes(parent)
161+
if err != nil {
162+
return err
163+
}
164+
165+
asn1Subject, err := subjectBytes(template)
166+
if err != nil {
167+
return err
168+
}
169+
170+
if !bytes.Equal(asn1Issuer, asn1Subject) && len(parent.SubjectKeyId) > 0 {
171+
template.AuthorityKeyId = parent.SubjectKeyId
172+
}
173+
174+
extensions, err := buildExtensions(template)
175+
if err != nil {
176+
return err
177+
}
178+
encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
179+
c := tbsCertificate{
180+
Version: 2,
181+
SerialNumber: template.SerialNumber,
182+
SignatureAlgorithm: signatureAlgorithm,
183+
Issuer: asn1.RawValue{FullBytes: asn1Issuer},
184+
Validity: validity{template.NotBefore.UTC(), template.NotAfter.UTC()},
185+
Subject: asn1.RawValue{FullBytes: asn1Subject},
186+
PublicKey: publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey},
187+
Extensions: extensions,
188+
}
189+
190+
tbsCertContents, err := asn1.Marshal(c)
191+
if err != nil {
192+
return err
193+
}
194+
195+
c.Raw = tbsCertContents
196+
197+
digest := tbsCertContents
198+
switch template.SignatureAlgorithm {
199+
case SM2WithSM3, SM2WithSHA1, SM2WithSHA256:
200+
break
201+
default:
202+
h := hashFunc.New()
203+
h.Write(tbsCertContents)
204+
digest = h.Sum(nil)
205+
}
206+
207+
var signerOpts crypto.SignerOpts
208+
signerOpts = hashFunc
209+
if template.SignatureAlgorithm != 0 && template.SignatureAlgorithm.isRSAPSS() {
210+
signerOpts = &rsa.PSSOptions{
211+
SaltLength: rsa.PSSSaltLengthEqualsHash,
212+
Hash: crypto.Hash(hashFunc),
213+
}
214+
}
215+
216+
var signature []byte
217+
signature, err = privKey.Sign(rand.Reader, digest, signerOpts)
102218
if err != nil {
103219
return err
104220
}
221+
der, err := asn1.Marshal(certificate{
222+
nil,
223+
c,
224+
signatureAlgorithm,
225+
asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
226+
})
105227

228+
if err != nil {
229+
return err
230+
}
231+
block := &pem.Block{
232+
Type: "CERTIFICATE",
233+
Bytes: der,
234+
}
235+
certPem := pem.EncodeToMemory(block)
106236
file, err := os.Create(FileName)
107-
defer func() {
108-
err = file.Close()
109-
}()
110237
if err != nil {
111238
return err
112239
}
240+
defer func() {
241+
err = file.Close()
242+
}()
113243
_, err = file.Write(certPem)
114244
if err != nil {
115245
return err

0 commit comments

Comments
 (0)