mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-08 23:13:38 +08:00
Update GmSSL-Go
This commit is contained in:
@@ -5,5 +5,16 @@ package gmssl
|
|||||||
/*
|
/*
|
||||||
#cgo darwin CFLAGS: -I/usr/local/include
|
#cgo darwin CFLAGS: -I/usr/local/include
|
||||||
#cgo darwin LDFLAGS: -L/usr/local/lib -lcrypto
|
#cgo darwin LDFLAGS: -L/usr/local/lib -lcrypto
|
||||||
|
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
|
||||||
|
long _BIO_get_mem_data(BIO *b, char **pp) {
|
||||||
|
return BIO_get_mem_data(b, pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _OPENSSL_free(void *addr) {
|
||||||
|
OPENSSL_free(addr);
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|||||||
@@ -14,14 +14,8 @@ package gmssl
|
|||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
#include <openssl/opensslconf.h>
|
#include <openssl/opensslconf.h>
|
||||||
|
|
||||||
static void _OPENSSL_free(void *p) {
|
extern long _BIO_get_mem_data(BIO *b, char **pp);
|
||||||
OPENSSL_free(p);
|
extern void _OPENSSL_free(void *addr);
|
||||||
}
|
|
||||||
|
|
||||||
static long _BIO_get_mem_data(BIO *b, char **pp) {
|
|
||||||
return BIO_get_mem_data(b, pp);
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
@@ -35,7 +29,7 @@ type Certificate struct {
|
|||||||
x509 *C.X509
|
x509 *C.X509
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadCertificateFromPEM(pem string, pass string) (*Certificate, error) {
|
func NewCertificateFromPEM(pem string, pass string) (*Certificate, error) {
|
||||||
cpem := C.CString(pem)
|
cpem := C.CString(pem)
|
||||||
defer C.free(unsafe.Pointer(cpem))
|
defer C.free(unsafe.Pointer(cpem))
|
||||||
cpass := C.CString(pass)
|
cpass := C.CString(pass)
|
||||||
@@ -114,6 +108,11 @@ func (cert *Certificate) GetPublicKey() (*PublicKey, error) {
|
|||||||
})
|
})
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cert *Certificate) GetText() (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
func (cert *Certificate) CheckPrivateKey(skey *PrivateKey) error {
|
func (cert *Certificate) CheckPrivateKey(skey *PrivateKey) error {
|
||||||
if 1 != C.X509_check_private_key(cert.x509, skey.pkey) {
|
if 1 != C.X509_check_private_key(cert.x509, skey.pkey) {
|
||||||
err := GetErrors()
|
err := GetErrors()
|
||||||
@@ -124,4 +123,3 @@ func (cert *Certificate) CheckPrivateKey(skey *PrivateKey) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,9 +34,7 @@ static char *get_cipher_names(void) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _OPENSSL_free(void *addr) {
|
extern void _OPENSSL_free(void *addr);
|
||||||
OPENSSL_free(addr);
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
@@ -87,7 +85,7 @@ type CipherContext struct {
|
|||||||
ctx *C.EVP_CIPHER_CTX
|
ctx *C.EVP_CIPHER_CTX
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCipherContext(name string, eng *Engine, key, iv []byte, encrypt bool) (
|
func NewCipherContext(name string, key, iv []byte, encrypt bool) (
|
||||||
*CipherContext, error) {
|
*CipherContext, error) {
|
||||||
|
|
||||||
cname := C.CString(name)
|
cname := C.CString(name)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package gmssl
|
|||||||
/*
|
/*
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
|
|
||||||
static void cb_digest_names_len(const EVP_MD *md, const char *from,
|
static void cb_digest_names_len(const EVP_MD *md, const char *from,
|
||||||
@@ -36,9 +37,7 @@ static char *get_digest_names() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _OPENSSL_free(void *addr) {
|
extern void _OPENSSL_free(void *addr);
|
||||||
OPENSSL_free(addr);
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
@@ -64,32 +63,38 @@ func GetDigestLength(name string) (int, error) {
|
|||||||
return int(C.EVP_MD_size(md)), nil
|
return int(C.EVP_MD_size(md)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetDigestBlockSize(name string) (int, error) {
|
||||||
|
cname := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
md := C.EVP_get_digestbyname(cname)
|
||||||
|
if md == nil {
|
||||||
|
return 0, GetErrors()
|
||||||
|
}
|
||||||
|
return int(C.EVP_MD_block_size(md)), nil
|
||||||
|
}
|
||||||
|
|
||||||
type DigestContext struct {
|
type DigestContext struct {
|
||||||
ctx *C.EVP_MD_CTX
|
ctx *C.EVP_MD_CTX
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDigestContext(name string, eng *Engine) (*DigestContext, error) {
|
func NewDigestContext(name string) (*DigestContext, error) {
|
||||||
cname := C.CString(name)
|
cname := C.CString(name)
|
||||||
defer C.free(unsafe.Pointer(cname))
|
defer C.free(unsafe.Pointer(cname))
|
||||||
md := C.EVP_get_digestbyname(cname)
|
md := C.EVP_get_digestbyname(cname)
|
||||||
if md == nil {
|
if md == nil {
|
||||||
return nil, GetErrors()
|
return nil, GetErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := C.EVP_MD_CTX_new()
|
ctx := C.EVP_MD_CTX_new()
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
return nil, GetErrors()
|
return nil, GetErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
ret := &DigestContext{ctx}
|
ret := &DigestContext{ctx}
|
||||||
runtime.SetFinalizer(ret, func(ret *DigestContext) {
|
runtime.SetFinalizer(ret, func(ret *DigestContext) {
|
||||||
C.EVP_MD_CTX_free(ret.ctx)
|
C.EVP_MD_CTX_free(ret.ctx)
|
||||||
})
|
})
|
||||||
|
if 1 != C.EVP_DigestInit_ex(ctx, md, nil) {
|
||||||
if 1 != C.EVP_DigestInit(ctx, md) {
|
|
||||||
return nil, GetErrors()
|
return nil, GetErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,8 +111,19 @@ func (ctx *DigestContext) Update(data []byte) error {
|
|||||||
func (ctx *DigestContext) Final() ([]byte, error) {
|
func (ctx *DigestContext) Final() ([]byte, error) {
|
||||||
outbuf := make([]byte, 64)
|
outbuf := make([]byte, 64)
|
||||||
outlen := C.uint(len(outbuf))
|
outlen := C.uint(len(outbuf))
|
||||||
if 1 != C.EVP_DigestFinal(ctx.ctx, (*C.uchar)(unsafe.Pointer(&outbuf[0])), &outlen) {
|
if 1 != C.EVP_DigestFinal_ex(ctx.ctx, (*C.uchar)(unsafe.Pointer(&outbuf[0])), &outlen) {
|
||||||
return nil, GetErrors()
|
return nil, GetErrors()
|
||||||
}
|
}
|
||||||
return outbuf[:outlen], nil
|
return outbuf[:outlen], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctx *DigestContext) Reset() error {
|
||||||
|
md := C.EVP_MD_CTX_md(ctx.ctx)
|
||||||
|
if md == nil {
|
||||||
|
return GetErrors()
|
||||||
|
}
|
||||||
|
if 1 != C.EVP_DigestInit_ex(ctx.ctx, md, nil) {
|
||||||
|
return GetErrors()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,30 +9,6 @@ package gmssl
|
|||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
|
|
||||||
static char *get_errors() {
|
|
||||||
char *ret;
|
|
||||||
BIO *bio;
|
|
||||||
char *data;
|
|
||||||
long len;
|
|
||||||
if (!(bio = BIO_new(BIO_s_mem()))) {
|
|
||||||
return (char *)NULL;
|
|
||||||
}
|
|
||||||
ERR_print_errors(bio);
|
|
||||||
len = BIO_get_mem_data(bio, &data);
|
|
||||||
ret = OPENSSL_strdup(data);
|
|
||||||
BIO_free(bio);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static EVP_PKEY *load_public_key(ENGINE *e, const char *id, char *pass) {
|
|
||||||
return ENGINE_load_public_key(e, id, NULL, pass);
|
|
||||||
}
|
|
||||||
|
|
||||||
static EVP_PKEY *load_private_key(ENGINE *e, const char *id, char *pass) {
|
|
||||||
return ENGINE_load_private_key(e, id, NULL, pass);
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
@@ -61,7 +37,7 @@ type Engine struct {
|
|||||||
engine *C.ENGINE;
|
engine *C.ENGINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetEngineByName(name string) (*Engine, error) {
|
func NewEngineByName(name string) (*Engine, error) {
|
||||||
cname := C.CString(name)
|
cname := C.CString(name)
|
||||||
defer C.free(unsafe.Pointer(cname))
|
defer C.free(unsafe.Pointer(cname))
|
||||||
eng := C.ENGINE_by_id(cname)
|
eng := C.ENGINE_by_id(cname)
|
||||||
@@ -79,6 +55,10 @@ func GetEngineByName(name string) (*Engine, error) {
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Engine) GetCommands() ([]string, error) {
|
||||||
|
return []string{"SO_PATH"}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Engine) RunCommand(name, arg string) error {
|
func (e *Engine) RunCommand(name, arg string) error {
|
||||||
cname := C.CString(name)
|
cname := C.CString(name)
|
||||||
defer C.free(unsafe.Pointer(cname))
|
defer C.free(unsafe.Pointer(cname))
|
||||||
@@ -99,7 +79,8 @@ func (e *Engine) GetPrivateKey(id string, pass string) (*PrivateKey, error) {
|
|||||||
defer C.free(unsafe.Pointer(cid))
|
defer C.free(unsafe.Pointer(cid))
|
||||||
cpass := C.CString(pass)
|
cpass := C.CString(pass)
|
||||||
defer C.free(unsafe.Pointer(cpass))
|
defer C.free(unsafe.Pointer(cpass))
|
||||||
sk := C.load_private_key(e.engine, cid, cpass)
|
sk := C.ENGINE_load_private_key(e.engine, cid, nil,
|
||||||
|
unsafe.Pointer(cpass))
|
||||||
if sk == nil {
|
if sk == nil {
|
||||||
return nil, GetErrors()
|
return nil, GetErrors()
|
||||||
}
|
}
|
||||||
@@ -111,7 +92,9 @@ func (e *Engine) GetPublicKey(id string, pass string) (*PublicKey, error) {
|
|||||||
defer C.free(unsafe.Pointer(cid))
|
defer C.free(unsafe.Pointer(cid))
|
||||||
cpass := C.CString(pass)
|
cpass := C.CString(pass)
|
||||||
defer C.free(unsafe.Pointer(cpass))
|
defer C.free(unsafe.Pointer(cpass))
|
||||||
pk := C.load_public_key(e.engine, cid, cpass)
|
|
||||||
|
pk := C.ENGINE_load_public_key(e.engine, cid, nil,
|
||||||
|
unsafe.Pointer(cpass))
|
||||||
if pk == nil {
|
if pk == nil {
|
||||||
return nil, GetErrors()
|
return nil, GetErrors()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ package gmssl
|
|||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
|
|
||||||
long bio_get_mem_data(BIO *bio, char **pp) {
|
|
||||||
return BIO_get_mem_data(bio, pp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
extern long _BIO_get_mem_data(BIO *b, char **pp);
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
@@ -24,7 +22,7 @@ func GetErrors() error {
|
|||||||
defer C.BIO_free(bio)
|
defer C.BIO_free(bio)
|
||||||
C.ERR_print_errors(bio)
|
C.ERR_print_errors(bio)
|
||||||
var p *C.char
|
var p *C.char
|
||||||
len := C.bio_get_mem_data(bio, &p)
|
len := C._BIO_get_mem_data(bio, &p)
|
||||||
if len <= 0 {
|
if len <= 0 {
|
||||||
return errors.New("GetErrors function failure 2")
|
return errors.New("GetErrors function failure 2")
|
||||||
}
|
}
|
||||||
|
|||||||
79
go/gmssl/hmac.go
Normal file
79
go/gmssl/hmac.go
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/* +build cgo */
|
||||||
|
|
||||||
|
package gmssl
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#include <openssl/cmac.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetMacLength(name string) (int, error) {
|
||||||
|
cname := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
md := C.EVP_get_digestbyname(cname)
|
||||||
|
if md == nil {
|
||||||
|
return 0, GetErrors()
|
||||||
|
}
|
||||||
|
return int(C.EVP_MD_size(md)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type HMACContext struct {
|
||||||
|
hctx *C.HMAC_CTX
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHMACContext(name string, key []byte) (
|
||||||
|
*HMACContext, error) {
|
||||||
|
cname := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
md := C.EVP_get_digestbyname(cname)
|
||||||
|
if md == nil {
|
||||||
|
return nil, GetErrors()
|
||||||
|
}
|
||||||
|
ctx := C.HMAC_CTX_new()
|
||||||
|
if ctx == nil {
|
||||||
|
return nil, GetErrors()
|
||||||
|
}
|
||||||
|
ret := &HMACContext{ctx}
|
||||||
|
runtime.SetFinalizer(ret, func(ret *HMACContext) {
|
||||||
|
C.HMAC_CTX_free(ret.hctx)
|
||||||
|
})
|
||||||
|
if 1 != C.HMAC_Init_ex(ctx,
|
||||||
|
unsafe.Pointer(&key[0]), C.int(len(key)), md, nil) {
|
||||||
|
return nil, GetErrors()
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *HMACContext) Update(data []byte) error {
|
||||||
|
if len(data) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if 1 != C.HMAC_Update(ctx.hctx,
|
||||||
|
(*C.uchar)(unsafe.Pointer(&data[0])), C.size_t(len(data))) {
|
||||||
|
return GetErrors()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *HMACContext) Final() ([]byte, error) {
|
||||||
|
outbuf := make([]byte, 64)
|
||||||
|
outlen := C.uint(len(outbuf))
|
||||||
|
if 1 != C.HMAC_Final(ctx.hctx,
|
||||||
|
(*C.uchar)(unsafe.Pointer(&outbuf[0])), &outlen) {
|
||||||
|
return nil, GetErrors()
|
||||||
|
}
|
||||||
|
return outbuf[:outlen], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *HMACContext) Reset() error {
|
||||||
|
if 1 != C.HMAC_Init_ex(ctx.hctx, nil, 0, nil, nil) {
|
||||||
|
return GetErrors()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
196
go/gmssl/pkey.go
196
go/gmssl/pkey.go
@@ -10,11 +10,12 @@ package gmssl
|
|||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
#include <openssl/opensslconf.h>
|
#include <openssl/opensslconf.h>
|
||||||
|
|
||||||
extern long bio_get_mem_data(BIO *bio, char **pp);
|
extern long _BIO_get_mem_data(BIO *bio, char **pp);
|
||||||
|
|
||||||
EVP_PKEY_CTX *new_pkey_keygen_ctx(const char *alg, ENGINE *e) {
|
EVP_PKEY_CTX *new_pkey_keygen_ctx(const char *alg, ENGINE *e) {
|
||||||
EVP_PKEY_CTX *ret = NULL;
|
EVP_PKEY_CTX *ret = NULL;
|
||||||
@@ -326,7 +327,6 @@ static int get_exch_info(const char *alg, int *ppkey_type, int *pec_scheme,
|
|||||||
ecdh_kdf_type = NID_sha384;
|
ecdh_kdf_type = NID_sha384;
|
||||||
break;
|
break;
|
||||||
case NID_dhSinglePass_cofactorDH_sha512kdf_scheme:
|
case NID_dhSinglePass_cofactorDH_sha512kdf_scheme:
|
||||||
pkey_type = EVP_PKEY_EC;
|
|
||||||
ec_scheme = NID_secg_scheme;
|
ec_scheme = NID_secg_scheme;
|
||||||
ecdh_cofactor_mode = 1;
|
ecdh_cofactor_mode = 1;
|
||||||
ecdh_kdf_type = NID_sha512;
|
ecdh_kdf_type = NID_sha512;
|
||||||
@@ -461,6 +461,7 @@ unsigned char *sk_sign(EVP_PKEY *sk, const char *alg, const unsigned char *dgst,
|
|||||||
if (!(sig = OPENSSL_zalloc(EVP_PKEY_size(sk)))) {
|
if (!(sig = OPENSSL_zalloc(EVP_PKEY_size(sk)))) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
*siglen = EVP_PKEY_size(sk);
|
||||||
if (EVP_PKEY_sign(ctx, sig, siglen, dgst, dgstlen) <= 0) {
|
if (EVP_PKEY_sign(ctx, sig, siglen, dgst, dgstlen) <= 0) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -478,11 +479,14 @@ int pk_verify(EVP_PKEY *pk, const char *alg, const unsigned char *dgst,
|
|||||||
EVP_PKEY_CTX *ctx = NULL;
|
EVP_PKEY_CTX *ctx = NULL;
|
||||||
|
|
||||||
if (!(ctx = EVP_PKEY_CTX_new(pk, e))) {
|
if (!(ctx = EVP_PKEY_CTX_new(pk, e))) {
|
||||||
|
printf("%s %d: error\n", __FILE__, __LINE__);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (!EVP_PKEY_verify_init(ctx)) {
|
if (!EVP_PKEY_verify_init(ctx)) {
|
||||||
|
printf("%s %d: error\n", __FILE__, __LINE__);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EVP_PKEY_id(pk) == EVP_PKEY_EC && EC_GROUP_get_curve_name(
|
if (EVP_PKEY_id(pk) == EVP_PKEY_EC && EC_GROUP_get_curve_name(
|
||||||
EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pk))) == NID_sm2p256v1) {
|
EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pk))) == NID_sm2p256v1) {
|
||||||
if (EVP_PKEY_CTX_set_ec_scheme(ctx, NID_sm_scheme) <= 0) {
|
if (EVP_PKEY_CTX_set_ec_scheme(ctx, NID_sm_scheme) <= 0) {
|
||||||
@@ -490,6 +494,8 @@ int pk_verify(EVP_PKEY *pk, const char *alg, const unsigned char *dgst,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ret = EVP_PKEY_verify(ctx, sig, siglen, dgst, dgstlen)) <= 0) {
|
if ((ret = EVP_PKEY_verify(ctx, sig, siglen, dgst, dgstlen)) <= 0) {
|
||||||
|
printf("ret = %d\n", ret);
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
@@ -507,6 +513,7 @@ import "C"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"errors"
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -521,63 +528,87 @@ func GetPublicKeyAlgorithmNames() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetSignAlgorithmNames(pkey string) ([]string, error) {
|
func GetSignAlgorithmNames(pkey string) ([]string, error) {
|
||||||
return []string{
|
if pkey == "EC" {
|
||||||
"sm2sign",
|
return []string{
|
||||||
"ecdsa-with-Recommended",
|
"sm2sign",
|
||||||
"ecdsa-with-SHA1",
|
"ecdsa-with-Recommended",
|
||||||
"ecdsa-with-SHA256",
|
"ecdsa-with-SHA1",
|
||||||
"ecdsa-with-SHA512",
|
"ecdsa-with-SHA256",
|
||||||
"RSA-SHA1",
|
"ecdsa-with-SHA512",
|
||||||
"RSA-SHA256",
|
}, nil
|
||||||
"RSA-SHA512",
|
} else if pkey == "RSA" {
|
||||||
"DSA-SHA1",
|
return []string{
|
||||||
}, nil
|
"RSA-SHA1",
|
||||||
|
"RSA-SHA256",
|
||||||
|
"RSA-SHA512",
|
||||||
|
}, nil
|
||||||
|
} else if pkey == "DSA" {
|
||||||
|
return []string{
|
||||||
|
"DSA-SHA1",
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("Invalid public key algorithm")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPublicKeyEncryptionNames(pkey string) ([]string, error) {
|
func GetPublicKeyEncryptionNames(pkey string) ([]string, error) {
|
||||||
return []string{
|
if pkey == "RSA" {
|
||||||
"RSAES-OAEP",
|
return []string{
|
||||||
"ecies-recommendedParameters",
|
"RSAES-OAEP",
|
||||||
"ecies-specifiedParameters",
|
}, nil
|
||||||
"ecies-with-x9-63-sha1-xor-hmac",
|
} else if pkey == "EC" {
|
||||||
"ecies-with-x9-63-sha256-xor-hmac",
|
return []string {
|
||||||
"ecies-with-x9-63-sha512-xor-hmac",
|
"ecies-recommendedParameters",
|
||||||
"ecies-with-x9-63-sha1-aes128-cbc-hmac",
|
"ecies-specifiedParameters",
|
||||||
"ecies-with-x9-63-sha256-aes128-cbc-hmac",
|
"ecies-with-x9-63-sha1-xor-hmac",
|
||||||
"ecies-with-x9-63-sha512-aes256-cbc-hmac",
|
"ecies-with-x9-63-sha256-xor-hmac",
|
||||||
"ecies-with-x9-63-sha256-aes128-ctr-hmac",
|
"ecies-with-x9-63-sha512-xor-hmac",
|
||||||
"ecies-with-x9-63-sha512-aes256-ctr-hmac",
|
"ecies-with-x9-63-sha1-aes128-cbc-hmac",
|
||||||
"ecies-with-x9-63-sha256-aes128-cbc-hmac-half",
|
"ecies-with-x9-63-sha256-aes128-cbc-hmac",
|
||||||
"ecies-with-x9-63-sha512-aes256-cbc-hmac-half",
|
"ecies-with-x9-63-sha512-aes256-cbc-hmac",
|
||||||
"ecies-with-x9-63-sha256-aes128-ctr-hmac-half",
|
"ecies-with-x9-63-sha256-aes128-ctr-hmac",
|
||||||
"ecies-with-x9-63-sha512-aes256-ctr-hmac-half",
|
"ecies-with-x9-63-sha512-aes256-ctr-hmac",
|
||||||
"ecies-with-x9-63-sha1-aes128-cbc-cmac",
|
"ecies-with-x9-63-sha256-aes128-cbc-hmac-half",
|
||||||
"ecies-with-x9-63-sha256-aes128-cbc-cmac",
|
"ecies-with-x9-63-sha512-aes256-cbc-hmac-half",
|
||||||
"ecies-with-x9-63-sha512-aes256-cbc-cmac",
|
"ecies-with-x9-63-sha256-aes128-ctr-hmac-half",
|
||||||
"ecies-with-x9-63-sha256-aes128-ctr-cmac",
|
"ecies-with-x9-63-sha512-aes256-ctr-hmac-half",
|
||||||
"ecies-with-x9-63-sha512-aes256-ctr-cmac",
|
"ecies-with-x9-63-sha1-aes128-cbc-cmac",
|
||||||
"sm2encrypt-with-sm3",
|
"ecies-with-x9-63-sha256-aes128-cbc-cmac",
|
||||||
"sm2encrypt-with-sha1",
|
"ecies-with-x9-63-sha512-aes256-cbc-cmac",
|
||||||
"sm2encrypt-with-sha256",
|
"ecies-with-x9-63-sha256-aes128-ctr-cmac",
|
||||||
"sm2encrypt-with-sha512",
|
"ecies-with-x9-63-sha512-aes256-ctr-cmac",
|
||||||
}, nil
|
"sm2encrypt-with-sm3",
|
||||||
|
"sm2encrypt-with-sha1",
|
||||||
|
"sm2encrypt-with-sha256",
|
||||||
|
"sm2encrypt-with-sha512",
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("Invalid public key algorithm")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDeriveKeyAlgorithmNames(pkey string) ([]string, error) {
|
func GetDeriveKeyAlgorithmNames(pkey string) ([]string, error) {
|
||||||
return []string{
|
if pkey == "EC" {
|
||||||
"sm2exchange",
|
return []string{
|
||||||
"dhSinglePass-stdDH-sha1kdf-scheme",
|
"sm2exchange",
|
||||||
"dhSinglePass-stdDH-sha224kdf-scheme",
|
}, nil
|
||||||
"dhSinglePass-stdDH-sha256kdf-scheme",
|
} else if pkey == "DH" {
|
||||||
"dhSinglePass-stdDH-sha384kdf-scheme",
|
return []string{
|
||||||
"dhSinglePass-stdDH-sha512kdf-scheme",
|
"dhSinglePass-stdDH-sha1kdf-scheme",
|
||||||
"dhSinglePass-cofactorDH-sha1kdf-scheme",
|
"dhSinglePass-stdDH-sha224kdf-scheme",
|
||||||
"dhSinglePass-cofactorDH-sha224kdf-scheme",
|
"dhSinglePass-stdDH-sha256kdf-scheme",
|
||||||
"dhSinglePass-cofactorDH-sha256kdf-scheme",
|
"dhSinglePass-stdDH-sha384kdf-scheme",
|
||||||
"dhSinglePass-cofactorDH-sha384kdf-scheme",
|
"dhSinglePass-stdDH-sha512kdf-scheme",
|
||||||
"dhSinglePass-cofactorDH-sha512kdf-scheme",
|
"dhSinglePass-cofactorDH-sha1kdf-scheme",
|
||||||
"dhKeyAgreement",
|
"dhSinglePass-cofactorDH-sha224kdf-scheme",
|
||||||
}, nil
|
"dhSinglePass-cofactorDH-sha256kdf-scheme",
|
||||||
|
"dhSinglePass-cofactorDH-sha384kdf-scheme",
|
||||||
|
"dhSinglePass-cofactorDH-sha512kdf-scheme",
|
||||||
|
"dhKeyAgreement",
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("No algorithm supported")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublicKey struct {
|
type PublicKey struct {
|
||||||
@@ -588,10 +619,17 @@ type PrivateKey struct {
|
|||||||
pkey *C.EVP_PKEY
|
pkey *C.EVP_PKEY
|
||||||
}
|
}
|
||||||
|
|
||||||
func GeneratePrivateKey(alg string, args map[string]string, eng Engine) (*PrivateKey, error) {
|
func GeneratePrivateKey(alg string, args map[string]string, eng *Engine) (*PrivateKey, error) {
|
||||||
calg := C.CString(alg)
|
calg := C.CString(alg)
|
||||||
defer C.free(unsafe.Pointer(calg))
|
defer C.free(unsafe.Pointer(calg))
|
||||||
ctx := C.new_pkey_keygen_ctx(calg, eng.engine)
|
|
||||||
|
ctx := C.new_pkey_keygen_ctx(calg, nil)
|
||||||
|
/*
|
||||||
|
if eng != nil {
|
||||||
|
ctx := C.new_pkey_keygen_ctx(calg, eng.engine)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
return nil, GetErrors()
|
return nil, GetErrors()
|
||||||
}
|
}
|
||||||
@@ -687,18 +725,20 @@ func (sk *PrivateKey) GetPEM(cipher string, pass string) (string, error) {
|
|||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: PKCS #5 can not use SM4 */
|
||||||
if 1 != C.PEM_write_bio_PrivateKey(bio, sk.pkey,
|
if 1 != C.PEM_write_bio_PrivateKey(bio, sk.pkey,
|
||||||
C.EVP_sms4_cbc(), nil, C.int(0), nil, unsafe.Pointer(cpass)) {
|
C.EVP_des_ede3_cbc(), nil, C.int(0), nil, unsafe.Pointer(cpass)) {
|
||||||
|
C.ERR_print_errors_fp(C.stderr)
|
||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
var p *C.char
|
var p *C.char
|
||||||
len := C.bio_get_mem_data(bio, &p)
|
len := C._BIO_get_mem_data(bio, &p)
|
||||||
if len <= 0 {
|
if len <= 0 {
|
||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
return C.GoString(p), nil
|
return C.GoString(p)[:len], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sk *PrivateKey) GetPublicKeyPEM() (string, error) {
|
func (sk *PrivateKey) GetPublicKeyPEM() (string, error) {
|
||||||
@@ -711,11 +751,11 @@ func (sk *PrivateKey) GetPublicKeyPEM() (string, error) {
|
|||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
var p *C.char
|
var p *C.char
|
||||||
len := C.bio_get_mem_data(bio, &p)
|
len := C._BIO_get_mem_data(bio, &p)
|
||||||
if len <= 0 {
|
if len <= 0 {
|
||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
return C.GoString(p), nil
|
return C.GoString(p)[:len], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sk *PrivateKey) GetText() (string, error) {
|
func (sk *PrivateKey) GetText() (string, error) {
|
||||||
@@ -724,15 +764,15 @@ func (sk *PrivateKey) GetText() (string, error) {
|
|||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
defer C.BIO_free(bio)
|
defer C.BIO_free(bio)
|
||||||
if 1 != C.EVP_PKEY_print_private(bio, sk.pkey, 4, nil) {
|
if 1 != C.EVP_PKEY_print_private(bio, sk.pkey, 0, nil) {
|
||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
var p *C.char
|
var p *C.char
|
||||||
len := C.bio_get_mem_data(bio, &p)
|
len := C._BIO_get_mem_data(bio, &p)
|
||||||
if len <= 0 {
|
if len <= 0 {
|
||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
return C.GoString(p), nil
|
return C.GoString(p)[:len], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPublicKeyFromPEM(pem string)(*PublicKey, error) {
|
func NewPublicKeyFromPEM(pem string)(*PublicKey, error) {
|
||||||
@@ -764,11 +804,11 @@ func (pk *PublicKey) GetPEM() (string, error) {
|
|||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
var p *C.char
|
var p *C.char
|
||||||
len := C.bio_get_mem_data(bio, &p)
|
len := C._BIO_get_mem_data(bio, &p)
|
||||||
if len <= 0 {
|
if len <= 0 {
|
||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
return C.GoString(p), nil
|
return C.GoString(p)[:len], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pk *PublicKey) GetText() (string, error) {
|
func (pk *PublicKey) GetText() (string, error) {
|
||||||
@@ -781,59 +821,63 @@ func (pk *PublicKey) GetText() (string, error) {
|
|||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
var p *C.char
|
var p *C.char
|
||||||
len := C.bio_get_mem_data(bio, &p)
|
len := C._BIO_get_mem_data(bio, &p)
|
||||||
if len <= 0 {
|
if len <= 0 {
|
||||||
return "", GetErrors()
|
return "", GetErrors()
|
||||||
}
|
}
|
||||||
return C.GoString(p), nil
|
return C.GoString(p)[:len], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pk *PublicKey) Encrypt(alg string, in []byte, eng Engine) ([]byte, error) {
|
func (pk *PublicKey) Encrypt(alg string, in []byte, eng *Engine) ([]byte, error) {
|
||||||
calg := C.CString(alg)
|
calg := C.CString(alg)
|
||||||
defer C.free(unsafe.Pointer(calg))
|
defer C.free(unsafe.Pointer(calg))
|
||||||
var outlen C.size_t
|
var outlen C.size_t
|
||||||
out := C.pk_encrypt(pk.pkey, calg, (*C.uchar)(&in[0]),
|
out := C.pk_encrypt(pk.pkey, calg, (*C.uchar)(&in[0]),
|
||||||
C.size_t(len(in)), &outlen, eng.engine)
|
C.size_t(len(in)), &outlen, nil)
|
||||||
if out == nil {
|
if out == nil {
|
||||||
return nil, GetErrors()
|
return nil, GetErrors()
|
||||||
}
|
}
|
||||||
return C.GoBytes(unsafe.Pointer(out), C.int(outlen)), nil
|
return C.GoBytes(unsafe.Pointer(out), C.int(outlen)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sk *PrivateKey) Decrypt(alg string, in []byte, eng Engine) ([]byte, error) {
|
func (sk *PrivateKey) Decrypt(alg string, in []byte, eng *Engine) ([]byte, error) {
|
||||||
calg := C.CString(alg)
|
calg := C.CString(alg)
|
||||||
defer C.free(unsafe.Pointer(calg))
|
defer C.free(unsafe.Pointer(calg))
|
||||||
var outlen C.size_t
|
var outlen C.size_t
|
||||||
out := C.sk_decrypt(sk.pkey, calg, (*C.uchar)(&in[0]),
|
out := C.sk_decrypt(sk.pkey, calg, (*C.uchar)(&in[0]),
|
||||||
C.size_t(len(in)), &outlen, eng.engine)
|
C.size_t(len(in)), &outlen, nil)
|
||||||
if out == nil {
|
if out == nil {
|
||||||
return nil, GetErrors()
|
return nil, GetErrors()
|
||||||
}
|
}
|
||||||
return C.GoBytes(unsafe.Pointer(out), C.int(outlen)), nil
|
return C.GoBytes(unsafe.Pointer(out), C.int(outlen)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sk *PrivateKey) Sign(alg string, dgst []byte, eng Engine) ([]byte, error) {
|
func (sk *PrivateKey) Sign(alg string, dgst []byte, eng *Engine) ([]byte, error) {
|
||||||
calg := C.CString(alg)
|
calg := C.CString(alg)
|
||||||
defer C.free(unsafe.Pointer(calg))
|
defer C.free(unsafe.Pointer(calg))
|
||||||
var siglen C.size_t
|
var siglen C.size_t
|
||||||
sig := C.sk_sign(sk.pkey, calg, (*C.uchar)(&dgst[0]), C.size_t(len(dgst)), &siglen, eng.engine)
|
sig := C.sk_sign(sk.pkey, calg, (*C.uchar)(&dgst[0]),
|
||||||
|
C.size_t(len(dgst)), &siglen, nil)
|
||||||
if sig == nil {
|
if sig == nil {
|
||||||
|
C.ERR_print_errors_fp(C.stderr)
|
||||||
return nil, GetErrors()
|
return nil, GetErrors()
|
||||||
}
|
}
|
||||||
return C.GoBytes(unsafe.Pointer(sig), C.int(siglen)), nil
|
return C.GoBytes(unsafe.Pointer(sig), C.int(siglen)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pk *PublicKey) Verify(alg string, dgst, sig []byte, eng Engine) error {
|
func (pk *PublicKey) Verify(alg string, dgst, sig []byte, eng *Engine) error {
|
||||||
calg := C.CString(alg)
|
calg := C.CString(alg)
|
||||||
defer C.free(unsafe.Pointer(calg))
|
defer C.free(unsafe.Pointer(calg))
|
||||||
|
|
||||||
if 1 != C.pk_verify(pk.pkey, calg, (*C.uchar)(&dgst[0]), C.size_t(len(dgst)),
|
if 1 != C.pk_verify(pk.pkey, calg, (*C.uchar)(&dgst[0]), C.size_t(len(dgst)),
|
||||||
(*C.uchar)(&sig[0]), C.size_t(len(sig)), eng.engine) {
|
(*C.uchar)(&sig[0]), C.size_t(len(sig)), nil) {
|
||||||
|
C.ERR_print_errors_fp(C.stderr)
|
||||||
return GetErrors()
|
return GetErrors()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sk *PrivateKey) DeriveKey(alg string, peer PublicKey, eng Engine) ([]byte, error) {
|
func (sk *PrivateKey) DeriveKey(alg string, peer PublicKey, eng *Engine) ([]byte, error) {
|
||||||
calg := C.CString(alg)
|
calg := C.CString(alg)
|
||||||
defer C.free(unsafe.Pointer(calg))
|
defer C.free(unsafe.Pointer(calg))
|
||||||
var keylen C.size_t
|
var keylen C.size_t
|
||||||
|
|||||||
@@ -20,6 +20,5 @@ func GenerateRandom(length int) ([]byte, error) {
|
|||||||
if C.RAND_bytes((*C.uchar)(&outbuf[0]), C.int(length)) <= 0 {
|
if C.RAND_bytes((*C.uchar)(&outbuf[0]), C.int(length)) <= 0 {
|
||||||
return nil, GetErrors()
|
return nil, GetErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
return outbuf[:length], nil
|
return outbuf[:length], nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ type digest struct {
|
|||||||
|
|
||||||
func New() hash.Hash {
|
func New() hash.Hash {
|
||||||
d := new(digest)
|
d := new(digest)
|
||||||
ctx, err := gmssl.NewDigestContext("SM3", nil)
|
ctx, err := gmssl.NewDigestContext("SM3")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -36,10 +36,7 @@ func (d *digest) Size() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *digest) Reset() {
|
func (d *digest) Reset() {
|
||||||
err := d.ctx.Reset()
|
_ = d.ctx.Reset()
|
||||||
if err != nil {
|
|
||||||
// do something?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *digest) Write(p []byte) (int, error) {
|
func (d *digest) Write(p []byte) (int, error) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import "C"
|
|||||||
|
|
||||||
func GetVersions() []string {
|
func GetVersions() []string {
|
||||||
versions := []string {
|
versions := []string {
|
||||||
"GmSSL Go API 1.2 Aug 4 2018",
|
"GmSSL Go API 1.3 Aug 6 2018",
|
||||||
C.GoString(C.OpenSSL_version(C.OPENSSL_VERSION)),
|
C.GoString(C.OpenSSL_version(C.OPENSSL_VERSION)),
|
||||||
C.GoString(C.OpenSSL_version(C.OPENSSL_BUILT_ON)),
|
C.GoString(C.OpenSSL_version(C.OPENSSL_BUILT_ON)),
|
||||||
C.GoString(C.OpenSSL_version(C.OPENSSL_CFLAGS)),
|
C.GoString(C.OpenSSL_version(C.OPENSSL_CFLAGS)),
|
||||||
|
|||||||
@@ -11,135 +11,164 @@ func main() {
|
|||||||
versions := gmssl.GetVersions()
|
versions := gmssl.GetVersions()
|
||||||
fmt.Println("GmSSL Versions:")
|
fmt.Println("GmSSL Versions:")
|
||||||
for _, version := range versions {
|
for _, version := range versions {
|
||||||
fmt.Println(" " + version)
|
fmt.Println(" " + version)
|
||||||
}
|
}
|
||||||
fmt.Println("");
|
fmt.Println("")
|
||||||
|
|
||||||
fmt.Println("Supported Digest Algorithms:")
|
fmt.Print("Digest Algorithms:")
|
||||||
digests := gmssl.GetDigestNames()
|
digests := gmssl.GetDigestNames()
|
||||||
for _, digest := range digests {
|
for _, digest := range digests {
|
||||||
fmt.Println(" " + digest)
|
fmt.Print(" " + digest)
|
||||||
}
|
}
|
||||||
fmt.Println("");
|
fmt.Println("\n")
|
||||||
|
|
||||||
fmt.Println("Supported Ciphers:")
|
fmt.Print("Ciphers:")
|
||||||
ciphers := gmssl.GetCipherNames()
|
ciphers := gmssl.GetCipherNames()
|
||||||
for _, cipher := range ciphers {
|
for _, cipher := range ciphers {
|
||||||
fmt.Println(" " + cipher)
|
fmt.Print(" " + cipher)
|
||||||
}
|
}
|
||||||
fmt.Println("");
|
fmt.Println("\n")
|
||||||
|
|
||||||
/* sm3 digest */
|
fmt.Println("Public Key Algorithms:")
|
||||||
sm3ctx, err := gmssl.NewDigestContext("SM3", nil)
|
pkey_algs := gmssl.GetPublicKeyAlgorithmNames()
|
||||||
if err != nil {
|
for _, pkey_alg := range pkey_algs {
|
||||||
fmt.Println(err)
|
fmt.Print(" " + pkey_alg + ":")
|
||||||
return
|
sign_algs, _ := gmssl.GetSignAlgorithmNames(pkey_alg)
|
||||||
|
for _, sign_alg := range sign_algs {
|
||||||
|
fmt.Print(" " + sign_alg)
|
||||||
|
}
|
||||||
|
pkey_encs, _ := gmssl.GetPublicKeyEncryptionNames(pkey_alg)
|
||||||
|
for _, pkey_enc := range pkey_encs {
|
||||||
|
fmt.Print(" " + pkey_enc)
|
||||||
|
}
|
||||||
|
derive_algs, _ := gmssl.GetDeriveKeyAlgorithmNames(pkey_alg)
|
||||||
|
for _, derive_alg := range derive_algs {
|
||||||
|
fmt.Print(" " + derive_alg)
|
||||||
|
}
|
||||||
|
fmt.Println("")
|
||||||
}
|
}
|
||||||
if err := sm3ctx.Update([]byte("a")); err != nil {
|
fmt.Println("")
|
||||||
fmt.Println(err)
|
|
||||||
return
|
/* Engines */
|
||||||
}
|
fmt.Print("Engines:")
|
||||||
if err := sm3ctx.Update([]byte("bc")); err != nil {
|
engines := gmssl.GetEngineNames()
|
||||||
fmt.Println(err)
|
for _, engine := range engines {
|
||||||
return
|
fmt.Print(" " + engine)
|
||||||
}
|
|
||||||
sm3digest, err := sm3ctx.Final()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
fmt.Println("\n");
|
||||||
|
|
||||||
|
/* SM3 digest with GmSSL-Go API */
|
||||||
|
sm3ctx, _ := gmssl.NewDigestContext("SM3")
|
||||||
|
sm3ctx.Update([]byte("a"))
|
||||||
|
sm3ctx.Update([]byte("bc"))
|
||||||
|
sm3digest, _ := sm3ctx.Final()
|
||||||
fmt.Printf("sm3(\"abc\") = %x\n", sm3digest)
|
fmt.Printf("sm3(\"abc\") = %x\n", sm3digest)
|
||||||
|
|
||||||
|
/* SM3 digest with Go hash.Hash API */
|
||||||
sm3hash := sm3.New()
|
sm3hash := sm3.New()
|
||||||
sm3hash.Write([]byte("abc"))
|
sm3hash.Write([]byte("abc"))
|
||||||
fmt.Printf("sm3(\"abc\") = %x\n", sm3hash.Sum(nil))
|
fmt.Printf("sm3(\"abc\") = %x\n", sm3hash.Sum(nil))
|
||||||
|
|
||||||
/* hmac-sm3 */
|
/* HMAC-SM3 */
|
||||||
hmac_sm3, err := gmssl.NewHMACContext("SM3", nil, []byte("this is the key"))
|
hmac_sm3, _ := gmssl.NewHMACContext("SM3", []byte("this is the key"))
|
||||||
if err != nil {
|
hmac_sm3.Update([]byte("ab"))
|
||||||
fmt.Println(err)
|
hmac_sm3.Update([]byte("c"))
|
||||||
return
|
mactag, _ := hmac_sm3.Final()
|
||||||
}
|
|
||||||
if err := hmac_sm3.Update([]byte("ab")); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := hmac_sm3.Update([]byte("c")); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mactag, err := hmac_sm3.Final()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Printf("hmac-sm3(\"abc\") = %x\n", mactag)
|
fmt.Printf("hmac-sm3(\"abc\") = %x\n", mactag)
|
||||||
|
|
||||||
/* generate random key */
|
/* Generate random key and IV */
|
||||||
keylen, err := gmssl.GetCipherKeyLength("SMS4")
|
keylen, _ := gmssl.GetCipherKeyLength("SMS4")
|
||||||
if err != nil {
|
key, _ := gmssl.GenerateRandom(keylen)
|
||||||
fmt.Println(err)
|
ivlen, _ := gmssl.GetCipherIVLength("SMS4")
|
||||||
return
|
iv, _ := gmssl.GenerateRandom(ivlen)
|
||||||
}
|
|
||||||
key, err := gmssl.GenerateRandom(keylen)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/* generate random iv */
|
/* SMS4-CBC Encrypt/Decrypt */
|
||||||
ivlen, err := gmssl.GetCipherIVLength("SMS4")
|
encryptor, _ := gmssl.NewCipherContext("SMS4", key, iv, true)
|
||||||
if err != nil {
|
ciphertext1, _ := encryptor.Update([]byte("hello"))
|
||||||
fmt.Println(err)
|
ciphertext2, _ := encryptor.Final()
|
||||||
return
|
|
||||||
}
|
|
||||||
iv, err := gmssl.GenerateRandom(ivlen)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/* encrypt */
|
|
||||||
encryptor, err := gmssl.NewCipherContext("SMS4", nil, key, iv, true)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ciphertext1, err := encryptor.Update([]byte("hello"))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ciphertext2, err := encryptor.Final()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ciphertext := make([]byte, 0, len(ciphertext1) + len(ciphertext2))
|
ciphertext := make([]byte, 0, len(ciphertext1) + len(ciphertext2))
|
||||||
ciphertext = append(ciphertext, ciphertext1...)
|
ciphertext = append(ciphertext, ciphertext1...)
|
||||||
ciphertext = append(ciphertext, ciphertext2...)
|
ciphertext = append(ciphertext, ciphertext2...)
|
||||||
|
|
||||||
/* decrypt */
|
decryptor, _ := gmssl.NewCipherContext("SMS4", key, iv, false)
|
||||||
decryptor, err := gmssl.NewCipherContext("SMS4", nil, key, iv, false)
|
plaintext1, _ := decryptor.Update(ciphertext)
|
||||||
if err != nil {
|
plaintext2, _ := decryptor.Final()
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
plaintext1, err := decryptor.Update(ciphertext)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
plaintext2, err := decryptor.Final()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
plaintext := make([]byte, 0, len(plaintext1) + len(plaintext2))
|
plaintext := make([]byte, 0, len(plaintext1) + len(plaintext2))
|
||||||
plaintext = append(plaintext, plaintext1...)
|
plaintext = append(plaintext, plaintext1...)
|
||||||
plaintext = append(plaintext, plaintext2...)
|
plaintext = append(plaintext, plaintext2...)
|
||||||
|
|
||||||
fmt.Printf("sms4(\"%s\") = %x\n", plaintext, ciphertext)
|
fmt.Printf("sms4(\"%s\") = %x\n", plaintext, ciphertext)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
/* private key */
|
||||||
|
rsa_args := map[string]string {
|
||||||
|
"rsa_keygen_bits": "2048",
|
||||||
|
"rsa_keygen_pubexp" : "65537",
|
||||||
|
}
|
||||||
|
|
||||||
|
rsa, err := gmssl.GeneratePrivateKey("RSA", rsa_args, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rsa_pem, err := rsa.GetPublicKeyPEM()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(rsa_pem)
|
||||||
|
|
||||||
|
/* Engine */
|
||||||
|
eng, _ := gmssl.NewEngineByName(engines[1])
|
||||||
|
cmds, _ := eng.GetCommands()
|
||||||
|
for _, cmd := range cmds {
|
||||||
|
fmt.Print(" " + cmd)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
/* SM2 key pair operations */
|
||||||
|
sm2keygenargs := map[string]string {
|
||||||
|
"ec_paramgen_curve": "sm2p256v1",
|
||||||
|
"ec_param_enc": "named_curve",
|
||||||
|
}
|
||||||
|
sm2sk, _ := gmssl.GeneratePrivateKey("EC", sm2keygenargs, nil)
|
||||||
|
sm2sktxt, _ := sm2sk.GetText()
|
||||||
|
sm2skpem, _ := sm2sk.GetPEM("SMS4", "password")
|
||||||
|
sm2pkpem, _ := sm2sk.GetPublicKeyPEM()
|
||||||
|
|
||||||
|
fmt.Println(sm2sktxt)
|
||||||
|
fmt.Println(sm2skpem)
|
||||||
|
fmt.Println(sm2pkpem)
|
||||||
|
|
||||||
|
sm2pk, _ := gmssl.NewPublicKeyFromPEM(sm2pkpem)
|
||||||
|
sm2pktxt, _ := sm2pk.GetText()
|
||||||
|
sm2pkpem_, _ := sm2pk.GetPEM()
|
||||||
|
|
||||||
|
fmt.Println(sm2pktxt)
|
||||||
|
fmt.Println(sm2pkpem_)
|
||||||
|
|
||||||
|
/* SM2 sign/verification */
|
||||||
|
sm3ctx.Reset()
|
||||||
|
sm3ctx.Update([]byte("message"))
|
||||||
|
tbs, _ := sm3ctx.Final()
|
||||||
|
|
||||||
|
sig, _ := sm2sk.Sign("sm2sign", tbs, nil)
|
||||||
|
fmt.Printf("sm2sign(sm3(\"message\")) = %x\n", sig)
|
||||||
|
|
||||||
|
if ret := sm2pk.Verify("sm2sign", tbs, sig, nil); ret != nil {
|
||||||
|
fmt.Printf("sm2 verify failure\n")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("sm2 verify success\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SM2 encrypt */
|
||||||
|
sm2msg := "01234567891123456789212345678931234567894123456789512345678961234567897123"
|
||||||
|
sm2encalg := "sm2encrypt-with-sm3"
|
||||||
|
sm2ciphertext, _ := sm2pk.Encrypt(sm2encalg, []byte(sm2msg), nil)
|
||||||
|
sm2plaintext, _ := sm2sk.Decrypt(sm2encalg, sm2ciphertext, nil)
|
||||||
|
fmt.Printf("sm2enc(\"%s\") = %x\n", sm2plaintext, sm2ciphertext)
|
||||||
|
if sm2msg != string(sm2plaintext) {
|
||||||
|
fmt.Println("SM2 encryption/decryption failure")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user