Update GmSSL-Go

This commit is contained in:
Zhi Guan
2018-08-06 20:51:29 +08:00
parent 962f7fbe3e
commit ebd186d01d
12 changed files with 390 additions and 238 deletions

View File

@@ -5,5 +5,16 @@ package gmssl
/*
#cgo darwin CFLAGS: -I/usr/local/include
#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"

View File

@@ -14,14 +14,8 @@ package gmssl
#include <openssl/objects.h>
#include <openssl/opensslconf.h>
static void _OPENSSL_free(void *p) {
OPENSSL_free(p);
}
static long _BIO_get_mem_data(BIO *b, char **pp) {
return BIO_get_mem_data(b, pp);
}
extern long _BIO_get_mem_data(BIO *b, char **pp);
extern void _OPENSSL_free(void *addr);
*/
import "C"
@@ -35,7 +29,7 @@ type Certificate struct {
x509 *C.X509
}
func ReadCertificateFromPEM(pem string, pass string) (*Certificate, error) {
func NewCertificateFromPEM(pem string, pass string) (*Certificate, error) {
cpem := C.CString(pem)
defer C.free(unsafe.Pointer(cpem))
cpass := C.CString(pass)
@@ -114,6 +108,11 @@ func (cert *Certificate) GetPublicKey() (*PublicKey, error) {
})
return ret, nil
}
func (cert *Certificate) GetText() (string, error) {
return "", nil
}
func (cert *Certificate) CheckPrivateKey(skey *PrivateKey) error {
if 1 != C.X509_check_private_key(cert.x509, skey.pkey) {
err := GetErrors()
@@ -124,4 +123,3 @@ func (cert *Certificate) CheckPrivateKey(skey *PrivateKey) error {
}
return nil
}

View File

@@ -34,9 +34,7 @@ static char *get_cipher_names(void) {
return ret;
}
static void _OPENSSL_free(void *addr) {
OPENSSL_free(addr);
}
extern void _OPENSSL_free(void *addr);
*/
import "C"
@@ -87,7 +85,7 @@ type CipherContext struct {
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) {
cname := C.CString(name)

View File

@@ -5,6 +5,7 @@ package gmssl
/*
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/crypto.h>
static void cb_digest_names_len(const EVP_MD *md, const char *from,
@@ -36,9 +37,7 @@ static char *get_digest_names() {
return ret;
}
static void _OPENSSL_free(void *addr) {
OPENSSL_free(addr);
}
extern void _OPENSSL_free(void *addr);
*/
import "C"
@@ -64,32 +63,38 @@ func GetDigestLength(name string) (int, error) {
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 {
ctx *C.EVP_MD_CTX
}
func NewDigestContext(name string, eng *Engine) (*DigestContext, error) {
func NewDigestContext(name string) (*DigestContext, 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.EVP_MD_CTX_new()
if ctx == nil {
return nil, GetErrors()
}
ret := &DigestContext{ctx}
runtime.SetFinalizer(ret, func(ret *DigestContext) {
C.EVP_MD_CTX_free(ret.ctx)
})
if 1 != C.EVP_DigestInit(ctx, md) {
if 1 != C.EVP_DigestInit_ex(ctx, md, nil) {
return nil, GetErrors()
}
return ret, nil
}
@@ -106,8 +111,19 @@ func (ctx *DigestContext) Update(data []byte) error {
func (ctx *DigestContext) Final() ([]byte, error) {
outbuf := make([]byte, 64)
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 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
}

View File

@@ -9,30 +9,6 @@ package gmssl
#include <openssl/err.h>
#include <openssl/evp.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"
@@ -61,7 +37,7 @@ type Engine struct {
engine *C.ENGINE;
}
func GetEngineByName(name string) (*Engine, error) {
func NewEngineByName(name string) (*Engine, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
eng := C.ENGINE_by_id(cname)
@@ -79,6 +55,10 @@ func GetEngineByName(name string) (*Engine, error) {
return ret, nil
}
func (e *Engine) GetCommands() ([]string, error) {
return []string{"SO_PATH"}, nil
}
func (e *Engine) RunCommand(name, arg string) error {
cname := C.CString(name)
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))
cpass := C.CString(pass)
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 {
return nil, GetErrors()
}
@@ -111,7 +92,9 @@ func (e *Engine) GetPublicKey(id string, pass string) (*PublicKey, error) {
defer C.free(unsafe.Pointer(cid))
cpass := C.CString(pass)
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 {
return nil, GetErrors()
}

View File

@@ -5,10 +5,8 @@ package gmssl
#include <openssl/err.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"
@@ -24,7 +22,7 @@ func GetErrors() error {
defer C.BIO_free(bio)
C.ERR_print_errors(bio)
var p *C.char
len := C.bio_get_mem_data(bio, &p)
len := C._BIO_get_mem_data(bio, &p)
if len <= 0 {
return errors.New("GetErrors function failure 2")
}

79
go/gmssl/hmac.go Normal file
View 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
}

View File

@@ -10,11 +10,12 @@ package gmssl
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/engine.h>
#include <openssl/objects.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 *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;
break;
case NID_dhSinglePass_cofactorDH_sha512kdf_scheme:
pkey_type = EVP_PKEY_EC;
ec_scheme = NID_secg_scheme;
ecdh_cofactor_mode = 1;
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)))) {
goto end;
}
*siglen = EVP_PKEY_size(sk);
if (EVP_PKEY_sign(ctx, sig, siglen, dgst, dgstlen) <= 0) {
goto end;
}
@@ -478,11 +479,14 @@ int pk_verify(EVP_PKEY *pk, const char *alg, const unsigned char *dgst,
EVP_PKEY_CTX *ctx = NULL;
if (!(ctx = EVP_PKEY_CTX_new(pk, e))) {
printf("%s %d: error\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_verify_init(ctx)) {
printf("%s %d: error\n", __FILE__, __LINE__);
goto end;
}
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) {
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) {
printf("ret = %d\n", ret);
ERR_print_errors_fp(stderr);
goto end;
}
end:
@@ -507,6 +513,7 @@ import "C"
import (
"unsafe"
"errors"
"runtime"
)
@@ -521,63 +528,87 @@ func GetPublicKeyAlgorithmNames() []string {
}
func GetSignAlgorithmNames(pkey string) ([]string, error) {
return []string{
"sm2sign",
"ecdsa-with-Recommended",
"ecdsa-with-SHA1",
"ecdsa-with-SHA256",
"ecdsa-with-SHA512",
"RSA-SHA1",
"RSA-SHA256",
"RSA-SHA512",
"DSA-SHA1",
}, nil
if pkey == "EC" {
return []string{
"sm2sign",
"ecdsa-with-Recommended",
"ecdsa-with-SHA1",
"ecdsa-with-SHA256",
"ecdsa-with-SHA512",
}, nil
} else if pkey == "RSA" {
return []string{
"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) {
return []string{
"RSAES-OAEP",
"ecies-recommendedParameters",
"ecies-specifiedParameters",
"ecies-with-x9-63-sha1-xor-hmac",
"ecies-with-x9-63-sha256-xor-hmac",
"ecies-with-x9-63-sha512-xor-hmac",
"ecies-with-x9-63-sha1-aes128-cbc-hmac",
"ecies-with-x9-63-sha256-aes128-cbc-hmac",
"ecies-with-x9-63-sha512-aes256-cbc-hmac",
"ecies-with-x9-63-sha256-aes128-ctr-hmac",
"ecies-with-x9-63-sha512-aes256-ctr-hmac",
"ecies-with-x9-63-sha256-aes128-cbc-hmac-half",
"ecies-with-x9-63-sha512-aes256-cbc-hmac-half",
"ecies-with-x9-63-sha256-aes128-ctr-hmac-half",
"ecies-with-x9-63-sha512-aes256-ctr-hmac-half",
"ecies-with-x9-63-sha1-aes128-cbc-cmac",
"ecies-with-x9-63-sha256-aes128-cbc-cmac",
"ecies-with-x9-63-sha512-aes256-cbc-cmac",
"ecies-with-x9-63-sha256-aes128-ctr-cmac",
"ecies-with-x9-63-sha512-aes256-ctr-cmac",
"sm2encrypt-with-sm3",
"sm2encrypt-with-sha1",
"sm2encrypt-with-sha256",
"sm2encrypt-with-sha512",
}, nil
if pkey == "RSA" {
return []string{
"RSAES-OAEP",
}, nil
} else if pkey == "EC" {
return []string {
"ecies-recommendedParameters",
"ecies-specifiedParameters",
"ecies-with-x9-63-sha1-xor-hmac",
"ecies-with-x9-63-sha256-xor-hmac",
"ecies-with-x9-63-sha512-xor-hmac",
"ecies-with-x9-63-sha1-aes128-cbc-hmac",
"ecies-with-x9-63-sha256-aes128-cbc-hmac",
"ecies-with-x9-63-sha512-aes256-cbc-hmac",
"ecies-with-x9-63-sha256-aes128-ctr-hmac",
"ecies-with-x9-63-sha512-aes256-ctr-hmac",
"ecies-with-x9-63-sha256-aes128-cbc-hmac-half",
"ecies-with-x9-63-sha512-aes256-cbc-hmac-half",
"ecies-with-x9-63-sha256-aes128-ctr-hmac-half",
"ecies-with-x9-63-sha512-aes256-ctr-hmac-half",
"ecies-with-x9-63-sha1-aes128-cbc-cmac",
"ecies-with-x9-63-sha256-aes128-cbc-cmac",
"ecies-with-x9-63-sha512-aes256-cbc-cmac",
"ecies-with-x9-63-sha256-aes128-ctr-cmac",
"ecies-with-x9-63-sha512-aes256-ctr-cmac",
"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) {
return []string{
"sm2exchange",
"dhSinglePass-stdDH-sha1kdf-scheme",
"dhSinglePass-stdDH-sha224kdf-scheme",
"dhSinglePass-stdDH-sha256kdf-scheme",
"dhSinglePass-stdDH-sha384kdf-scheme",
"dhSinglePass-stdDH-sha512kdf-scheme",
"dhSinglePass-cofactorDH-sha1kdf-scheme",
"dhSinglePass-cofactorDH-sha224kdf-scheme",
"dhSinglePass-cofactorDH-sha256kdf-scheme",
"dhSinglePass-cofactorDH-sha384kdf-scheme",
"dhSinglePass-cofactorDH-sha512kdf-scheme",
"dhKeyAgreement",
}, nil
if pkey == "EC" {
return []string{
"sm2exchange",
}, nil
} else if pkey == "DH" {
return []string{
"dhSinglePass-stdDH-sha1kdf-scheme",
"dhSinglePass-stdDH-sha224kdf-scheme",
"dhSinglePass-stdDH-sha256kdf-scheme",
"dhSinglePass-stdDH-sha384kdf-scheme",
"dhSinglePass-stdDH-sha512kdf-scheme",
"dhSinglePass-cofactorDH-sha1kdf-scheme",
"dhSinglePass-cofactorDH-sha224kdf-scheme",
"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 {
@@ -588,10 +619,17 @@ type PrivateKey struct {
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)
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 {
return nil, GetErrors()
}
@@ -687,18 +725,20 @@ func (sk *PrivateKey) GetPEM(cipher string, pass string) (string, error) {
return "", GetErrors()
}
/* FIXME: PKCS #5 can not use SM4 */
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()
}
var p *C.char
len := C.bio_get_mem_data(bio, &p)
len := C._BIO_get_mem_data(bio, &p)
if len <= 0 {
return "", GetErrors()
}
return C.GoString(p), nil
return C.GoString(p)[:len], nil
}
func (sk *PrivateKey) GetPublicKeyPEM() (string, error) {
@@ -711,11 +751,11 @@ func (sk *PrivateKey) GetPublicKeyPEM() (string, error) {
return "", GetErrors()
}
var p *C.char
len := C.bio_get_mem_data(bio, &p)
len := C._BIO_get_mem_data(bio, &p)
if len <= 0 {
return "", GetErrors()
}
return C.GoString(p), nil
return C.GoString(p)[:len], nil
}
func (sk *PrivateKey) GetText() (string, error) {
@@ -724,15 +764,15 @@ func (sk *PrivateKey) GetText() (string, error) {
return "", GetErrors()
}
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()
}
var p *C.char
len := C.bio_get_mem_data(bio, &p)
len := C._BIO_get_mem_data(bio, &p)
if len <= 0 {
return "", GetErrors()
}
return C.GoString(p), nil
return C.GoString(p)[:len], nil
}
func NewPublicKeyFromPEM(pem string)(*PublicKey, error) {
@@ -764,11 +804,11 @@ func (pk *PublicKey) GetPEM() (string, error) {
return "", GetErrors()
}
var p *C.char
len := C.bio_get_mem_data(bio, &p)
len := C._BIO_get_mem_data(bio, &p)
if len <= 0 {
return "", GetErrors()
}
return C.GoString(p), nil
return C.GoString(p)[:len], nil
}
func (pk *PublicKey) GetText() (string, error) {
@@ -781,59 +821,63 @@ func (pk *PublicKey) GetText() (string, error) {
return "", GetErrors()
}
var p *C.char
len := C.bio_get_mem_data(bio, &p)
len := C._BIO_get_mem_data(bio, &p)
if len <= 0 {
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)
defer C.free(unsafe.Pointer(calg))
var outlen C.size_t
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 {
return nil, GetErrors()
}
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)
defer C.free(unsafe.Pointer(calg))
var outlen C.size_t
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 {
return nil, GetErrors()
}
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)
defer C.free(unsafe.Pointer(calg))
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 {
C.ERR_print_errors_fp(C.stderr)
return nil, GetErrors()
}
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)
defer C.free(unsafe.Pointer(calg))
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 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)
defer C.free(unsafe.Pointer(calg))
var keylen C.size_t

View File

@@ -20,6 +20,5 @@ func GenerateRandom(length int) ([]byte, error) {
if C.RAND_bytes((*C.uchar)(&outbuf[0]), C.int(length)) <= 0 {
return nil, GetErrors()
}
return outbuf[:length], nil
}

View File

@@ -11,7 +11,7 @@ type digest struct {
func New() hash.Hash {
d := new(digest)
ctx, err := gmssl.NewDigestContext("SM3", nil)
ctx, err := gmssl.NewDigestContext("SM3")
if err != nil {
return nil
}
@@ -36,10 +36,7 @@ func (d *digest) Size() int {
}
func (d *digest) Reset() {
err := d.ctx.Reset()
if err != nil {
// do something?
}
_ = d.ctx.Reset()
}
func (d *digest) Write(p []byte) (int, error) {

View File

@@ -8,7 +8,7 @@ import "C"
func GetVersions() []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_BUILT_ON)),
C.GoString(C.OpenSSL_version(C.OPENSSL_CFLAGS)),

View File

@@ -11,135 +11,164 @@ func main() {
versions := gmssl.GetVersions()
fmt.Println("GmSSL 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()
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()
for _, cipher := range ciphers {
fmt.Println(" " + cipher)
fmt.Print(" " + cipher)
}
fmt.Println("");
fmt.Println("\n")
/* sm3 digest */
sm3ctx, err := gmssl.NewDigestContext("SM3", nil)
if err != nil {
fmt.Println(err)
return
fmt.Println("Public Key Algorithms:")
pkey_algs := gmssl.GetPublicKeyAlgorithmNames()
for _, pkey_alg := range pkey_algs {
fmt.Print(" " + pkey_alg + ":")
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(err)
return
}
if err := sm3ctx.Update([]byte("bc")); err != nil {
fmt.Println(err)
return
}
sm3digest, err := sm3ctx.Final()
if err != nil {
fmt.Println(err)
return
fmt.Println("")
/* Engines */
fmt.Print("Engines:")
engines := gmssl.GetEngineNames()
for _, engine := range engines {
fmt.Print(" " + engine)
}
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)
/* SM3 digest with Go hash.Hash API */
sm3hash := sm3.New()
sm3hash.Write([]byte("abc"))
fmt.Printf("sm3(\"abc\") = %x\n", sm3hash.Sum(nil))
/* hmac-sm3 */
hmac_sm3, err := gmssl.NewHMACContext("SM3", nil, []byte("this is the key"))
if err != nil {
fmt.Println(err)
return
}
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
}
/* HMAC-SM3 */
hmac_sm3, _ := gmssl.NewHMACContext("SM3", []byte("this is the key"))
hmac_sm3.Update([]byte("ab"))
hmac_sm3.Update([]byte("c"))
mactag, _ := hmac_sm3.Final()
fmt.Printf("hmac-sm3(\"abc\") = %x\n", mactag)
/* generate random key */
keylen, err := gmssl.GetCipherKeyLength("SMS4")
if err != nil {
fmt.Println(err)
return
}
key, err := gmssl.GenerateRandom(keylen)
if err != nil {
fmt.Println(err)
return
}
/* Generate random key and IV */
keylen, _ := gmssl.GetCipherKeyLength("SMS4")
key, _ := gmssl.GenerateRandom(keylen)
ivlen, _ := gmssl.GetCipherIVLength("SMS4")
iv, _ := gmssl.GenerateRandom(ivlen)
/* generate random iv */
ivlen, err := gmssl.GetCipherIVLength("SMS4")
if err != nil {
fmt.Println(err)
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
}
/* SMS4-CBC Encrypt/Decrypt */
encryptor, _ := gmssl.NewCipherContext("SMS4", key, iv, true)
ciphertext1, _ := encryptor.Update([]byte("hello"))
ciphertext2, _ := encryptor.Final()
ciphertext := make([]byte, 0, len(ciphertext1) + len(ciphertext2))
ciphertext = append(ciphertext, ciphertext1...)
ciphertext = append(ciphertext, ciphertext2...)
/* decrypt */
decryptor, err := gmssl.NewCipherContext("SMS4", nil, key, iv, false)
if err != nil {
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
}
decryptor, _ := gmssl.NewCipherContext("SMS4", key, iv, false)
plaintext1, _ := decryptor.Update(ciphertext)
plaintext2, _ := decryptor.Final()
plaintext := make([]byte, 0, len(plaintext1) + len(plaintext2))
plaintext = append(plaintext, plaintext1...)
plaintext = append(plaintext, plaintext2...)
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")
}
}