Skip to content

Commit

Permalink
Added sign/verify functions that takes digest instead of plain text
Browse files Browse the repository at this point in the history
  • Loading branch information
pcsx22 committed Sep 6, 2020
1 parent c2dcc5c commit 9b84749
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 0 deletions.
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();

0 comments on commit 9b84749

Please sign in to comment.