11package x509
22
33import (
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