Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added sign/verify functions that takes digest instead of plain text #143

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions key.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ type PublicKey interface {
// Verifies the data signature using PKCS1.15
VerifyPKCS1v15(method Method, data, sig []byte) error

VerifyHash([]byte, []byte) error

// MarshalPKIXPublicKeyPEM converts the public key to PEM-encoded PKIX
// format
MarshalPKIXPublicKeyPEM() (pem_block []byte, err error)
Expand Down Expand Up @@ -101,6 +103,8 @@ type PrivateKey interface {
// MarshalPKCS1PrivateKeyDER converts the private key to DER-encoded PKCS1
// format
MarshalPKCS1PrivateKeyDER() (der_block []byte, err error)

SignHash([]byte) ([]byte, error)
}

type pKey struct {
Expand All @@ -117,6 +121,28 @@ func (key *pKey) BaseType() NID {
return NID(C.EVP_PKEY_base_id(key.key))
}

func (key *pKey) SignHash(digest []byte) ([]byte, error) {
ctx := C.X_EVP_PKEY_CTX_new(key.key, nil)
defer C.X_EVP_PKEY_CTX_free(ctx)

if C.X_EVP_PKEY_sign_init(ctx) <= 0 {
return nil, errors.New("Error initializing context")
}

sig := make([]byte, 72, 72)
var sigblen C.size_t = 72

e := C.X_EVP_PKEY_sign(ctx,
((*C.uchar)(unsafe.Pointer(&sig[0]))),
&sigblen,
(*C.uchar)(unsafe.Pointer(&digest[0])),
C.size_t(len(digest)))
if e <= 0 {
return nil, errors.New("Error signining")
}
return sig[:sigblen], nil
}

func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) {

ctx := C.X_EVP_MD_CTX_new()
Expand Down Expand Up @@ -165,6 +191,23 @@ func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) {
}
}

func (key *pKey) VerifyHash(digest, sig []byte) error {
ctx := C.X_EVP_PKEY_CTX_new(key.key, nil)
defer C.X_EVP_PKEY_CTX_free(ctx)

if C.X_EVP_PKEY_verify_init(ctx) <= 0 {
return errors.New("Error initializing context")
}
if 1 != C.X_EVP_PKEY_verify(ctx,
((*C.uchar)(unsafe.Pointer(&sig[0]))),
C.size_t(len(sig)),
(*C.uchar)(unsafe.Pointer(&digest[0])),
C.size_t(len(digest))) {
return errors.New("Signing Failed")
}
return nil
}

func (key *pKey) VerifyPKCS1v15(method Method, data, sig []byte) error {
ctx := C.X_EVP_MD_CTX_new()
defer C.X_EVP_MD_CTX_free(ctx)
Expand Down
15 changes: 15 additions & 0 deletions key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"crypto/x509"
"encoding/hex"
pem_pkg "encoding/pem"
"fmt"
"io/ioutil"
"testing"
)
Expand Down Expand Up @@ -254,6 +255,20 @@ func TestSignEC(t *testing.T) {
t.Fatal(err)
}
})

t.Run("sha256WithExternalHash", func(t *testing.T) {
t.Parallel()
h, _ := SHA256(data)
sig, err := key.SignHash(h[:])
if err != nil {
t.Fatal(err)
}
fmt.Println("Signature: ", sig)
err = key.VerifyHash(h[:], sig)
if err != nil {
t.Fatal(err)
}
})
}

func TestSignED25519(t *testing.T) {
Expand Down
28 changes: 28 additions & 0 deletions shim.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ int X_EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret,
return EVP_DigestSign(ctx, sigret, siglen, tbs, tbslen);
}

int X_EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) {
return EVP_PKEY_sign_init(ctx);
}

int X_EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) {
return EVP_PKEY_sign(ctx, sig, siglen, tbs, tbslen);
}

unsigned long X_ERR_get_error(){
return ERR_get_error();
}

int X_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey){
Expand All @@ -69,6 +80,15 @@ int X_EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
return EVP_DigestVerify(ctx, sigret, siglen, tbs, tbslen);
}

int X_EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) {
return EVP_PKEY_verify_init(ctx);
}

int X_EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) {
return EVP_PKEY_verify(ctx, sig, siglen, tbs, tbslen);
}


#else

const int X_ED25519_SUPPORT = 0;
Expand Down Expand Up @@ -116,10 +136,18 @@ EVP_MD_CTX* X_EVP_MD_CTX_new() {
return EVP_MD_CTX_new();
}

EVP_PKEY_CTX* X_EVP_PKEY_CTX_new(EVP_PKEY *key, ENGINE *e){
return EVP_PKEY_CTX_new(key, e);
}

void X_EVP_MD_CTX_free(EVP_MD_CTX* ctx) {
EVP_MD_CTX_free(ctx);
}

void X_EVP_PKEY_CTX_free(EVP_PKEY_CTX* ctx) {
EVP_PKEY_CTX_free(ctx);
}

static int x_bio_create(BIO *b) {
BIO_set_shutdown(b, 1);
BIO_set_init(b, 1);
Expand Down
7 changes: 7 additions & 0 deletions shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ extern const int X_ED25519_SUPPORT;
extern int X_EVP_PKEY_ED25519;
extern const EVP_MD *X_EVP_get_digestbyname(const char *name);
extern EVP_MD_CTX *X_EVP_MD_CTX_new();
extern EVP_PKEY_CTX* X_EVP_PKEY_CTX_new(EVP_PKEY *key, ENGINE *e);
extern void X_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
extern void X_EVP_MD_CTX_free(EVP_MD_CTX *ctx);
extern const EVP_MD *X_EVP_md_null();
extern const EVP_MD *X_EVP_md5();
Expand Down Expand Up @@ -135,10 +137,12 @@ extern int X_EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key);
extern int X_EVP_PKEY_assign_charp(EVP_PKEY *pkey, int type, char *key);
extern int X_EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, EVP_PKEY *pkey);
extern int X_EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type);
extern int X_EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
extern int X_EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
extern int X_EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey);
extern int X_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
extern int X_EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen);
extern int X_EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen);
extern int X_EVP_CIPHER_block_size(EVP_CIPHER *c);
extern int X_EVP_CIPHER_key_length(EVP_CIPHER *c);
extern int X_EVP_CIPHER_iv_length(EVP_CIPHER *c);
Expand All @@ -150,6 +154,8 @@ extern void X_EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int padding);
extern const EVP_CIPHER *X_EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *ctx);
extern int X_EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx);
extern int X_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid);
extern int X_EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
extern int X_EVP_PKEY_sign(EVP_PKEY_CTX *ctx,unsigned char *sig, size_t *siglen,const unsigned char *tbs, size_t tbslen);

/* HMAC methods */
extern size_t X_HMAC_size(const HMAC_CTX *e);
Expand All @@ -170,3 +176,4 @@ extern int X_X509_set_version(X509 *x, long version);

/* PEM methods */
extern int X_PEM_write_bio_PrivateKey_traditional(BIO *bio, EVP_PKEY *key, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
unsigned long X_ERR_get_error();