@@ -7,13 +7,18 @@ import (
77 "crypto/rand"
88 "crypto/rsa"
99 "crypto/x509"
10+ "crypto/x509/pkix"
1011 "encoding/asn1"
1112 "encoding/pem"
1213 "math/big"
1314 "time"
1415
1516 "github.com/xtls/xray-core/common"
17+ "github.com/xtls/xray-core/common/crypto/gost"
18+ sm2crypto "github.com/xtls/xray-core/common/crypto/sm2"
1619 "github.com/xtls/xray-core/common/errors"
20+ "github.com/tjfoc/gmsm/sm2"
21+ sm2x509 "github.com/tjfoc/gmsm/x509"
1722)
1823
1924type Certificate struct {
@@ -45,54 +50,292 @@ func (c *Certificate) ToPEM() ([]byte, []byte) {
4550
4651type Option func (* x509.Certificate )
4752
53+ // SM2-specific option types
54+ type SM2Option func (* sm2x509.Certificate )
55+
4856func Authority (isCA bool ) Option {
4957 return func (cert * x509.Certificate ) {
5058 cert .IsCA = isCA
5159 }
5260}
5361
62+ func SM2Authority (isCA bool ) SM2Option {
63+ return func (cert * sm2x509.Certificate ) {
64+ cert .IsCA = isCA
65+ }
66+ }
67+
5468func NotBefore (t time.Time ) Option {
5569 return func (c * x509.Certificate ) {
5670 c .NotBefore = t
5771 }
5872}
5973
74+ func SM2NotBefore (t time.Time ) SM2Option {
75+ return func (c * sm2x509.Certificate ) {
76+ c .NotBefore = t
77+ }
78+ }
79+
6080func NotAfter (t time.Time ) Option {
6181 return func (c * x509.Certificate ) {
6282 c .NotAfter = t
6383 }
6484}
6585
86+ func SM2NotAfter (t time.Time ) SM2Option {
87+ return func (c * sm2x509.Certificate ) {
88+ c .NotAfter = t
89+ }
90+ }
91+
6692func DNSNames (names ... string ) Option {
6793 return func (c * x509.Certificate ) {
6894 c .DNSNames = names
6995 }
7096}
7197
98+ func SM2DNSNames (names ... string ) SM2Option {
99+ return func (c * sm2x509.Certificate ) {
100+ c .DNSNames = names
101+ }
102+ }
103+
72104func CommonName (name string ) Option {
73105 return func (c * x509.Certificate ) {
74106 c .Subject .CommonName = name
75107 }
76108}
77109
110+ func SM2CommonName (name string ) SM2Option {
111+ return func (c * sm2x509.Certificate ) {
112+ c .Subject .CommonName = name
113+ }
114+ }
115+
78116func KeyUsage (usage x509.KeyUsage ) Option {
79117 return func (c * x509.Certificate ) {
80118 c .KeyUsage = usage
81119 }
82120}
83121
122+ func SM2KeyUsage (usage sm2x509.KeyUsage ) SM2Option {
123+ return func (c * sm2x509.Certificate ) {
124+ c .KeyUsage = usage
125+ }
126+ }
127+
84128func Organization (org string ) Option {
85129 return func (c * x509.Certificate ) {
86130 c .Subject .Organization = []string {org }
87131 }
88132}
89133
134+ func SM2Organization (org string ) SM2Option {
135+ return func (c * sm2x509.Certificate ) {
136+ c .Subject .Organization = []string {org }
137+ }
138+ }
139+
90140func MustGenerate (parent * Certificate , opts ... Option ) * Certificate {
91141 cert , err := Generate (parent , opts ... )
92142 common .Must (err )
93143 return cert
94144}
95145
146+ // MustGenerateGOST2012_256 generates a certificate using GOST 2012-256 algorithm
147+ func MustGenerateGOST2012_256 (parent * Certificate , opts ... SM2Option ) * Certificate {
148+ cert , err := GenerateGOST2012_256 (parent , opts ... )
149+ common .Must (err )
150+ return cert
151+ }
152+
153+ // MustGenerateGOST2012_512 generates a certificate using GOST 2012-512 algorithm
154+ func MustGenerateGOST2012_512 (parent * Certificate , opts ... SM2Option ) * Certificate {
155+ cert , err := GenerateGOST2012_512 (parent , opts ... )
156+ common .Must (err )
157+ return cert
158+ }
159+
160+ // MustGenerateSM2 generates a certificate using SM2 algorithm
161+ func MustGenerateSM2 (parent * Certificate , opts ... SM2Option ) * Certificate {
162+ cert , err := GenerateSM2 (parent , opts ... )
163+ common .Must (err )
164+ return cert
165+ }
166+
167+ // GenerateGOST2012_256 generates a certificate using GOST 2012-256 algorithm
168+ func GenerateGOST2012_256 (parent * Certificate , opts ... SM2Option ) (* Certificate , error ) {
169+ var (
170+ err error
171+ )
172+ selfKey , err := gost .GenerateKeyPair (gost .GOST2012_256 )
173+ if err != nil {
174+ return nil , errors .New ("failed to generate GOST 2012-256 private key" ).Base (err )
175+ }
176+
177+ serialNumberLimit := new (big.Int ).Lsh (big .NewInt (1 ), 128 )
178+ serialNumber , err := rand .Int (rand .Reader , serialNumberLimit )
179+ if err != nil {
180+ return nil , errors .New ("failed to generate serial number" ).Base (err )
181+ }
182+ template := & sm2x509.Certificate {
183+ SerialNumber : serialNumber ,
184+ Subject : pkix.Name {
185+ Organization : []string {"Xray GOST 2012-256 Certificate" },
186+ CommonName : "" ,
187+ },
188+ NotBefore : time .Now ().Add (time .Hour * - 1 ),
189+ NotAfter : time .Now ().Add (time .Hour ),
190+ KeyUsage : sm2x509 .KeyUsageKeyEncipherment | sm2x509 .KeyUsageDigitalSignature ,
191+ ExtKeyUsage : []sm2x509.ExtKeyUsage {sm2x509 .ExtKeyUsageServerAuth },
192+ BasicConstraintsValid : true ,
193+ }
194+ parentCert := template
195+ if parent != nil {
196+ pCert , err := sm2x509 .ParseCertificate (parent .Certificate )
197+ if err != nil {
198+ return nil , errors .New ("failed to parse parent certificate" ).Base (err )
199+ }
200+ parentCert = pCert
201+ }
202+ if parentCert .NotAfter .Before (template .NotAfter ) {
203+ template .NotAfter = parentCert .NotAfter
204+ }
205+ if parentCert .NotBefore .After (template .NotBefore ) {
206+ template .NotBefore = parentCert .NotBefore
207+ }
208+ for _ , opt := range opts {
209+ opt (template )
210+ }
211+ certDER , err := sm2x509 .CreateCertificate (template , parentCert , & selfKey .PublicKey , selfKey )
212+ if err != nil {
213+ return nil , errors .New ("failed to create GOST 2012-256 certificate" ).Base (err )
214+ }
215+ privateKey , err := sm2x509 .MarshalSm2UnecryptedPrivateKey (selfKey )
216+ if err != nil {
217+ return nil , errors .New ("Unable to marshal GOST 2012-256 private key" ).Base (err )
218+ }
219+ return & Certificate {
220+ Certificate : certDER ,
221+ PrivateKey : privateKey ,
222+ }, nil
223+ }
224+
225+ // GenerateGOST2012_512 generates a certificate using GOST 2012-512 algorithm
226+ func GenerateGOST2012_512 (parent * Certificate , opts ... SM2Option ) (* Certificate , error ) {
227+ var (
228+ err error
229+ )
230+ selfKey , err := gost .GenerateKeyPair (gost .GOST2012_512 )
231+ if err != nil {
232+ return nil , errors .New ("failed to generate GOST 2012-512 private key" ).Base (err )
233+ }
234+ serialNumberLimit := new (big.Int ).Lsh (big .NewInt (1 ), 128 )
235+ serialNumber , err := rand .Int (rand .Reader , serialNumberLimit )
236+ if err != nil {
237+ return nil , errors .New ("failed to generate serial number" ).Base (err )
238+ }
239+ template := & sm2x509.Certificate {
240+ SerialNumber : serialNumber ,
241+ Subject : pkix.Name {
242+ Organization : []string {"Xray GOST 2012-512 Certificate" },
243+ CommonName : "" ,
244+ },
245+ NotBefore : time .Now ().Add (time .Hour * - 1 ),
246+ NotAfter : time .Now ().Add (time .Hour ),
247+ KeyUsage : sm2x509 .KeyUsageKeyEncipherment | sm2x509 .KeyUsageDigitalSignature ,
248+ ExtKeyUsage : []sm2x509.ExtKeyUsage {sm2x509 .ExtKeyUsageServerAuth },
249+ BasicConstraintsValid : true ,
250+ }
251+ parentCert := template
252+ if parent != nil {
253+ pCert , err := sm2x509 .ParseCertificate (parent .Certificate )
254+ if err != nil {
255+ return nil , errors .New ("failed to parse parent certificate" ).Base (err )
256+ }
257+ parentCert = pCert
258+ }
259+ if parentCert .NotAfter .Before (template .NotAfter ) {
260+ template .NotAfter = parentCert .NotAfter
261+ }
262+ if parentCert .NotBefore .After (template .NotBefore ) {
263+ template .NotBefore = parentCert .NotBefore
264+ }
265+ for _ , opt := range opts {
266+ opt (template )
267+ }
268+ certDER , err := sm2x509 .CreateCertificate (template , parentCert , & selfKey .PublicKey , selfKey )
269+ if err != nil {
270+ return nil , errors .New ("failed to create GOST 2012-512 certificate" ).Base (err )
271+ }
272+ privateKey , err := sm2x509 .MarshalSm2UnecryptedPrivateKey (selfKey )
273+ if err != nil {
274+ return nil , errors .New ("Unable to marshal GOST 2012-512 private key" ).Base (err )
275+ }
276+ return & Certificate {
277+ Certificate : certDER ,
278+ PrivateKey : privateKey ,
279+ }, nil
280+ }
281+
282+ // GenerateSM2 generates a certificate using SM2 algorithm
283+ func GenerateSM2 (parent * Certificate , opts ... SM2Option ) (* Certificate , error ) {
284+ var (
285+ err error
286+ )
287+ selfKey , err := sm2crypto .GenerateKeyPair ()
288+ if err != nil {
289+ return nil , errors .New ("failed to generate SM2 private key" ).Base (err )
290+ }
291+ serialNumberLimit := new (big.Int ).Lsh (big .NewInt (1 ), 128 )
292+ serialNumber , err := rand .Int (rand .Reader , serialNumberLimit )
293+ if err != nil {
294+ return nil , errors .New ("failed to generate serial number" ).Base (err )
295+ }
296+ template := & sm2x509.Certificate {
297+ SerialNumber : serialNumber ,
298+ Subject : pkix.Name {
299+ Organization : []string {"Xray SM2 Certificate" },
300+ CommonName : "" ,
301+ },
302+ NotBefore : time .Now ().Add (time .Hour * - 1 ),
303+ NotAfter : time .Now ().Add (time .Hour ),
304+ KeyUsage : sm2x509 .KeyUsageKeyEncipherment | sm2x509 .KeyUsageDigitalSignature ,
305+ ExtKeyUsage : []sm2x509.ExtKeyUsage {sm2x509 .ExtKeyUsageServerAuth },
306+ BasicConstraintsValid : true ,
307+ }
308+ parentCert := template
309+ if parent != nil {
310+ pCert , err := sm2x509 .ParseCertificate (parent .Certificate )
311+ if err != nil {
312+ return nil , errors .New ("failed to parse parent certificate" ).Base (err )
313+ }
314+ parentCert = pCert
315+ }
316+ if parentCert .NotAfter .Before (template .NotAfter ) {
317+ template .NotAfter = parentCert .NotAfter
318+ }
319+ if parentCert .NotBefore .After (template .NotBefore ) {
320+ template .NotBefore = parentCert .NotBefore
321+ }
322+ for _ , opt := range opts {
323+ opt (template )
324+ }
325+ certDER , err := sm2x509 .CreateCertificate (template , parentCert , & selfKey .PublicKey , selfKey )
326+ if err != nil {
327+ return nil , errors .New ("failed to create SM2 certificate" ).Base (err )
328+ }
329+ privateKey , err := sm2x509 .MarshalSm2UnecryptedPrivateKey (selfKey )
330+ if err != nil {
331+ return nil , errors .New ("Unable to marshal SM2 private key" ).Base (err )
332+ }
333+ return & Certificate {
334+ Certificate : certDER ,
335+ PrivateKey : privateKey ,
336+ }, nil
337+ }
338+
96339func publicKey (priv interface {}) interface {} {
97340 switch k := priv .(type ) {
98341 case * rsa.PrivateKey :
@@ -101,6 +344,8 @@ func publicKey(priv interface{}) interface{} {
101344 return & k .PublicKey
102345 case ed25519.PrivateKey :
103346 return k .Public ().(ed25519.PublicKey )
347+ case * sm2.PrivateKey :
348+ return & k .PublicKey
104349 default :
105350 return nil
106351 }
0 commit comments