Skip to content

Commit 9bd163e

Browse files
committed
Init
0 parents  commit 9bd163e

File tree

12 files changed

+1649
-0
lines changed

12 files changed

+1649
-0
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# GmSSL-Go
2+
3+
## 简介
4+
5+
GmSSL-Go 是GmSSL密码库 https://github.com/guanzhi/GmSSL 的Go语言封装,以`cgo`方式实现,通过Go类和函数提供了如下密码接口:
6+
7+
* 密码随机数生成器
8+
* SM2加密和签名,SM2密钥生成、私钥口令加密保护、密钥PEM文件导入导出
9+
* SM2数字证书的导入、解析和验证
10+
* SM3哈希函数、HMAC-SM3消息认证码、基于SM3的PBKDF2密钥导出函数
11+
* SM4分组加密,以及SM4的CBC、CTR、GCM三种加密模式
12+
* SM9加密和签名,以及SM9密钥生成、密钥口令加密保护、密钥PEM文件导入导出
13+
* ZUC序列密码加密
14+
15+
目前GmSSL-Go功能可以覆盖除SSL/TLS/TLCP之外的国密算法主要应用开发场景。
16+
17+
## 开发入门
18+
19+
GmSSL-Go的库代码位于`gmssl`目录下,示例位于`examples`目录下。在源代码的`examples`目录下执行
20+
21+
```bash
22+
go run .
23+
```
24+
25+
可以执行默认的测试程序,查看`examples/hello.go`了解更多用法。
26+

build.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the License); you may
5+
* not use this file except in compliance with the License.
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*/
9+
/* +build cgo */
10+
11+
package gmssl
12+
13+
/*
14+
#cgo LDFLAGS: -lgmssl
15+
*/
16+
import "C"

cert.go

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
/*
2+
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the License); you may
5+
* not use this file except in compliance with the License.
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*/
9+
/* +build cgo */
10+
package gmssl
11+
12+
/*
13+
#include <stdio.h>
14+
#include <string.h>
15+
#include <stdlib.h>
16+
#include <gmssl/sm2.h>
17+
#include <gmssl/mem.h>
18+
#include <gmssl/asn1.h>
19+
#include <gmssl/x509.h>
20+
#include <gmssl/error.h>
21+
22+
23+
24+
*/
25+
import "C"
26+
27+
import (
28+
"unsafe"
29+
"errors"
30+
"runtime"
31+
"time"
32+
)
33+
34+
35+
type Sm2Certificate struct {
36+
cert *C.uint8_t
37+
certlen C.size_t
38+
}
39+
40+
func ImportSm2CertificatePem(path string) (*Sm2Certificate, error) {
41+
42+
path_str := C.CString(path)
43+
defer C.free(unsafe.Pointer(path_str))
44+
45+
fp := C.fopen(path_str, C.CString("rb"))
46+
if fp == nil {
47+
return nil, errors.New("fopen failure")
48+
}
49+
defer C.fclose(fp)
50+
51+
var cert *C.uint8_t
52+
var certlen C.size_t
53+
54+
if C.x509_cert_new_from_file(&cert, &certlen, path_str) != 1 {
55+
return nil, errors.New("Libgmssl inner error")
56+
}
57+
58+
ret := &Sm2Certificate{cert, certlen}
59+
runtime.SetFinalizer(ret, func(ret *Sm2Certificate) {
60+
C.free(unsafe.Pointer(ret.cert))
61+
})
62+
return ret, nil
63+
}
64+
65+
func (cert *Sm2Certificate) GetSerialNumber() ([]byte, error) {
66+
var serial *C.uint8_t
67+
var serial_len C.size_t
68+
69+
if C.x509_cert_get_issuer_and_serial_number(cert.cert, cert.certlen, nil, nil, &serial, &serial_len) != 1 {
70+
return nil, errors.New("Libgmssl inner error")
71+
}
72+
73+
outbuf := make([]byte, serial_len)
74+
C.memcpy(unsafe.Pointer(&outbuf[0]), unsafe.Pointer(serial), serial_len)
75+
return outbuf, nil
76+
}
77+
78+
func (cert *Sm2Certificate) GetValidity() (time.Time, time.Time, error) {
79+
80+
var not_before C.time_t
81+
var not_after C.time_t
82+
83+
if C.x509_cert_get_details(cert.cert, cert.certlen,
84+
nil, nil, nil, nil, nil, nil,
85+
&not_before, &not_after,
86+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) != 1 {
87+
return time.Unix(0,0), time.Unix(0,0), errors.New("Libgmssl inner error")
88+
}
89+
90+
return time.Unix(int64(not_before), 0), time.Unix(int64(not_after), 0), nil
91+
}
92+
93+
94+
func gmssl_parse_attr_type_and_value(name map[string]string, d *C.uint8_t, dlen C.size_t) error {
95+
var oid C.int
96+
var tag C.int
97+
var val *C.char
98+
var vlen C.size_t
99+
100+
if C.x509_name_type_from_der(&oid, &d, &dlen) != 1 {
101+
return errors.New("libgmssl inner error")
102+
}
103+
oid_name := C.x509_name_type_name(oid)
104+
105+
if oid == C.OID_email_address {
106+
if C.asn1_ia5_string_from_der_ex(C.ASN1_TAG_IA5String, &val, &vlen, &d, &dlen) != 1 {
107+
return errors.New("libgmssl inner error")
108+
}
109+
name[C.GoString(oid_name)] = C.GoStringN(val, C.int(vlen))
110+
111+
} else {
112+
var uchar_ptr *C.uchar
113+
if C.x509_directory_name_from_der(&tag, &uchar_ptr, &vlen, &d, &dlen) != 1 {
114+
return errors.New("libgmssl inner error")
115+
}
116+
117+
name[C.GoString(oid_name)] = C.GoStringN((*C.char)(unsafe.Pointer(uchar_ptr)), C.int(vlen))
118+
}
119+
120+
if C.asn1_length_is_zero(dlen) != 1 {
121+
return errors.New("libgmssl inner error")
122+
}
123+
124+
return nil;
125+
}
126+
127+
func gmssl_parse_rdn(name map[string]string, d *C.uint8_t, dlen C.size_t) error {
128+
var p *C.uint8_t
129+
var plen C.size_t
130+
131+
for dlen > 0 {
132+
if C.asn1_type_from_der(C.ASN1_TAG_SEQUENCE, &p, &plen, &d, &dlen) != 1 {
133+
return errors.New("libgmssl inner error")
134+
}
135+
if gmssl_parse_attr_type_and_value(name, p, plen) != nil {
136+
return errors.New("Parse RDN error")
137+
}
138+
}
139+
return nil
140+
}
141+
142+
func gmssl_parse_name(name map[string]string, d *C.uint8_t, dlen C.size_t) error {
143+
var p *C.uint8_t
144+
var plen C.size_t
145+
146+
for dlen > 0 {
147+
if C.asn1_nonempty_type_from_der(C.ASN1_TAG_SET, &p, &plen, &d, &dlen) != 1 {
148+
return errors.New("libgmssl inner error")
149+
}
150+
if gmssl_parse_rdn(name, p, plen) != nil {
151+
return errors.New("Parse name error")
152+
}
153+
}
154+
return nil
155+
}
156+
157+
func (cert *Sm2Certificate) GetIssuer() ([]byte, map[string]string, error) {
158+
var issuer *C.uint8_t
159+
var issuer_len C.size_t
160+
161+
if C.x509_cert_get_issuer(cert.cert, cert.certlen, &issuer, &issuer_len) != 1 {
162+
return nil, nil, errors.New("Libgmssl inner error")
163+
}
164+
165+
name := make(map[string]string)
166+
167+
if gmssl_parse_name(name, issuer, issuer_len) != nil {
168+
return nil, nil, errors.New("Libgmssl inner error")
169+
}
170+
171+
raw_data := make([]byte, issuer_len)
172+
C.memcpy(unsafe.Pointer(&raw_data[0]), unsafe.Pointer(issuer), issuer_len)
173+
174+
return raw_data, name, nil
175+
}
176+
177+
func (cert *Sm2Certificate) GetSubject() ([]byte, map[string]string, error) {
178+
var subject *C.uint8_t
179+
var subject_len C.size_t
180+
181+
if C.x509_cert_get_subject(cert.cert, cert.certlen, &subject, &subject_len) != 1 {
182+
return nil, nil, errors.New("Libgmssl inner error")
183+
}
184+
185+
name := make(map[string]string)
186+
187+
if gmssl_parse_name(name, subject, subject_len) != nil {
188+
return nil, nil, errors.New("Libgmssl inner error")
189+
}
190+
191+
raw_data := make([]byte, subject_len)
192+
C.memcpy(unsafe.Pointer(&raw_data[0]), unsafe.Pointer(subject), subject_len)
193+
194+
return raw_data, name, nil
195+
}
196+
197+
func (cert *Sm2Certificate) GetSubjectPublicKey() (*Sm2Key, error) {
198+
199+
ret := new(Sm2Key)
200+
201+
if C.x509_cert_get_subject_public_key(cert.cert, cert.certlen, &ret.sm2_key) != 1 {
202+
return nil, errors.New("Libgmssl inner error")
203+
}
204+
ret.has_private_key = false
205+
206+
return ret, nil
207+
}
208+
209+
func (cert *Sm2Certificate) VerifyByCaCertificate(ca_cert *Sm2Certificate, sm2_id string) bool {
210+
211+
sm2_id_str := C.CString(sm2_id)
212+
defer C.free(unsafe.Pointer(sm2_id_str))
213+
214+
if C.x509_cert_verify_by_ca_cert(cert.cert, cert.certlen, ca_cert.cert, ca_cert.certlen,
215+
sm2_id_str, C.strlen(sm2_id_str)) != 1 {
216+
return false
217+
}
218+
return true
219+
}
220+
221+

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/GmSSL/TestGo
2+
3+
go 1.21.1

rand.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the License); you may
5+
* not use this file except in compliance with the License.
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*/
9+
/* +build cgo */
10+
package gmssl
11+
12+
/*
13+
#include <gmssl/rand.h>
14+
*/
15+
import "C"
16+
17+
import (
18+
"errors"
19+
)
20+
21+
func RandBytes(length int) ([]byte, error) {
22+
outbuf := make([]byte, length)
23+
if C.rand_bytes((*C.uchar)(&outbuf[0]), C.size_t(length)) <= 0 {
24+
return nil, errors.New("Libgmssl inner error")
25+
}
26+
return outbuf[:length], nil
27+
}

0 commit comments

Comments
 (0)