Skip to content

Commit 9b84749

Browse files
committed
Added sign/verify functions that takes digest instead of plain text
1 parent c2dcc5c commit 9b84749

File tree

4 files changed

+93
-0
lines changed

4 files changed

+93
-0
lines changed

key.go

+43
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ type PublicKey interface {
6464
// Verifies the data signature using PKCS1.15
6565
VerifyPKCS1v15(method Method, data, sig []byte) error
6666

67+
VerifyHash([]byte, []byte) error
68+
6769
// MarshalPKIXPublicKeyPEM converts the public key to PEM-encoded PKIX
6870
// format
6971
MarshalPKIXPublicKeyPEM() (pem_block []byte, err error)
@@ -101,6 +103,8 @@ type PrivateKey interface {
101103
// MarshalPKCS1PrivateKeyDER converts the private key to DER-encoded PKCS1
102104
// format
103105
MarshalPKCS1PrivateKeyDER() (der_block []byte, err error)
106+
107+
SignHash([]byte) ([]byte, error)
104108
}
105109

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

124+
func (key *pKey) SignHash(digest []byte) ([]byte, error) {
125+
ctx := C.X_EVP_PKEY_CTX_new(key.key, nil)
126+
defer C.X_EVP_PKEY_CTX_free(ctx)
127+
128+
if C.X_EVP_PKEY_sign_init(ctx) <= 0 {
129+
return nil, errors.New("Error initializing context")
130+
}
131+
132+
sig := make([]byte, 72, 72)
133+
var sigblen C.size_t = 72
134+
135+
e := C.X_EVP_PKEY_sign(ctx,
136+
((*C.uchar)(unsafe.Pointer(&sig[0]))),
137+
&sigblen,
138+
(*C.uchar)(unsafe.Pointer(&digest[0])),
139+
C.size_t(len(digest)))
140+
if e <= 0 {
141+
return nil, errors.New("Error signining")
142+
}
143+
return sig[:sigblen], nil
144+
}
145+
120146
func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) {
121147

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

194+
func (key *pKey) VerifyHash(digest, sig []byte) error {
195+
ctx := C.X_EVP_PKEY_CTX_new(key.key, nil)
196+
defer C.X_EVP_PKEY_CTX_free(ctx)
197+
198+
if C.X_EVP_PKEY_verify_init(ctx) <= 0 {
199+
return errors.New("Error initializing context")
200+
}
201+
if 1 != C.X_EVP_PKEY_verify(ctx,
202+
((*C.uchar)(unsafe.Pointer(&sig[0]))),
203+
C.size_t(len(sig)),
204+
(*C.uchar)(unsafe.Pointer(&digest[0])),
205+
C.size_t(len(digest))) {
206+
return errors.New("Signing Failed")
207+
}
208+
return nil
209+
}
210+
168211
func (key *pKey) VerifyPKCS1v15(method Method, data, sig []byte) error {
169212
ctx := C.X_EVP_MD_CTX_new()
170213
defer C.X_EVP_MD_CTX_free(ctx)

key_test.go

+15
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"crypto/x509"
2323
"encoding/hex"
2424
pem_pkg "encoding/pem"
25+
"fmt"
2526
"io/ioutil"
2627
"testing"
2728
)
@@ -254,6 +255,20 @@ func TestSignEC(t *testing.T) {
254255
t.Fatal(err)
255256
}
256257
})
258+
259+
t.Run("sha256WithExternalHash", func(t *testing.T) {
260+
t.Parallel()
261+
h, _ := SHA256(data)
262+
sig, err := key.SignHash(h[:])
263+
if err != nil {
264+
t.Fatal(err)
265+
}
266+
fmt.Println("Signature: ", sig)
267+
err = key.VerifyHash(h[:], sig)
268+
if err != nil {
269+
t.Fatal(err)
270+
}
271+
})
257272
}
258273

259274
func TestSignED25519(t *testing.T) {

shim.c

+28
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ int X_EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret,
5858
return EVP_DigestSign(ctx, sigret, siglen, tbs, tbslen);
5959
}
6060

61+
int X_EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) {
62+
return EVP_PKEY_sign_init(ctx);
63+
}
64+
65+
int X_EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) {
66+
return EVP_PKEY_sign(ctx, sig, siglen, tbs, tbslen);
67+
}
68+
69+
unsigned long X_ERR_get_error(){
70+
return ERR_get_error();
71+
}
6172

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

83+
int X_EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) {
84+
return EVP_PKEY_verify_init(ctx);
85+
}
86+
87+
int X_EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) {
88+
return EVP_PKEY_verify(ctx, sig, siglen, tbs, tbslen);
89+
}
90+
91+
7292
#else
7393

7494
const int X_ED25519_SUPPORT = 0;
@@ -116,10 +136,18 @@ EVP_MD_CTX* X_EVP_MD_CTX_new() {
116136
return EVP_MD_CTX_new();
117137
}
118138

139+
EVP_PKEY_CTX* X_EVP_PKEY_CTX_new(EVP_PKEY *key, ENGINE *e){
140+
return EVP_PKEY_CTX_new(key, e);
141+
}
142+
119143
void X_EVP_MD_CTX_free(EVP_MD_CTX* ctx) {
120144
EVP_MD_CTX_free(ctx);
121145
}
122146

147+
void X_EVP_PKEY_CTX_free(EVP_PKEY_CTX* ctx) {
148+
EVP_PKEY_CTX_free(ctx);
149+
}
150+
123151
static int x_bio_create(BIO *b) {
124152
BIO_set_shutdown(b, 1);
125153
BIO_set_init(b, 1);

shim.h

+7
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ extern const int X_ED25519_SUPPORT;
106106
extern int X_EVP_PKEY_ED25519;
107107
extern const EVP_MD *X_EVP_get_digestbyname(const char *name);
108108
extern EVP_MD_CTX *X_EVP_MD_CTX_new();
109+
extern EVP_PKEY_CTX* X_EVP_PKEY_CTX_new(EVP_PKEY *key, ENGINE *e);
110+
extern void X_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
109111
extern void X_EVP_MD_CTX_free(EVP_MD_CTX *ctx);
110112
extern const EVP_MD *X_EVP_md_null();
111113
extern const EVP_MD *X_EVP_md5();
@@ -135,10 +137,12 @@ extern int X_EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key);
135137
extern int X_EVP_PKEY_assign_charp(EVP_PKEY *pkey, int type, char *key);
136138
extern int X_EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, EVP_PKEY *pkey);
137139
extern int X_EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type);
140+
extern int X_EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
138141
extern int X_EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
139142
extern int X_EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey);
140143
extern int X_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
141144
extern int X_EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen);
145+
extern int X_EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen);
142146
extern int X_EVP_CIPHER_block_size(EVP_CIPHER *c);
143147
extern int X_EVP_CIPHER_key_length(EVP_CIPHER *c);
144148
extern int X_EVP_CIPHER_iv_length(EVP_CIPHER *c);
@@ -150,6 +154,8 @@ extern void X_EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int padding);
150154
extern const EVP_CIPHER *X_EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *ctx);
151155
extern int X_EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx);
152156
extern int X_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid);
157+
extern int X_EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
158+
extern int X_EVP_PKEY_sign(EVP_PKEY_CTX *ctx,unsigned char *sig, size_t *siglen,const unsigned char *tbs, size_t tbslen);
153159

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

171177
/* PEM methods */
172178
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);
179+
unsigned long X_ERR_get_error();

0 commit comments

Comments
 (0)