From 1d9843178d6d26df11dbfa37eb657a3c824664ea Mon Sep 17 00:00:00 2001 From: Andrew Harding Date: Tue, 11 Mar 2014 15:46:56 -0600 Subject: [PATCH] space monkey internal commit export [katamari commit: fc133f4e22e0d82053b5978b099a04f1ae5f62d5] --- pem.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/pem.go b/pem.go index 22488e8..a0d04e4 100644 --- a/pem.go +++ b/pem.go @@ -3,10 +3,29 @@ package openssl +// #include // #include // #include // // void OPENSSL_free_not_a_macro(void *ref) { OPENSSL_free(ref); } +// +// int EVP_SignInit_not_a_macro(EVP_MD_CTX *ctx, const EVP_MD *type) { +// return EVP_SignInit(ctx, type); +// } +// +// int EVP_SignUpdate_not_a_macro(EVP_MD_CTX *ctx, const void *d, +// unsigned int cnt) { +// return EVP_SignUpdate(ctx, d, cnt); +// } +// +// int EVP_VerifyInit_not_a_macro(EVP_MD_CTX *ctx, const EVP_MD *type) { +// return EVP_VerifyInit(ctx, type); +// } +// +// int EVP_VerifyUpdate_not_a_macro(EVP_MD_CTX *ctx, const void *d, +// unsigned int cnt) { +// return EVP_VerifyUpdate(ctx, d, cnt); +// } import "C" import ( @@ -16,7 +35,16 @@ import ( "unsafe" ) +type Method *C.EVP_MD + +var ( + SHA256 Method = C.EVP_sha256() +) + type PublicKey interface { + // Verifies the data signature using PKCS1.15 + VerifyPKCS1v15(method Method, data, sig []byte) error + // MarshalPKIXPublicKeyPEM converts the public key to PEM-encoded PKIX // format MarshalPKIXPublicKeyPEM() (pem_block []byte, err error) @@ -31,6 +59,9 @@ type PublicKey interface { type PrivateKey interface { PublicKey + // Signs the data using PKCS1.15 + SignPKCS1v15(Method, []byte) ([]byte, error) + // MarshalPKCS1PrivateKeyPEM converts the private key to PEM-encoded PKCS1 // format MarshalPKCS1PrivateKeyPEM() (pem_block []byte, err error) @@ -46,6 +77,50 @@ type pKey struct { func (key *pKey) evpPKey() *C.EVP_PKEY { return key.key } +func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) { + var ctx C.EVP_MD_CTX + C.EVP_MD_CTX_init(&ctx) + defer C.EVP_MD_CTX_cleanup(&ctx) + + if 1 != C.EVP_SignInit_not_a_macro(&ctx, method) { + return nil, errors.New("signpkcs1v15: failed to init signature") + } + if len(data) > 0 { + if 1 != C.EVP_SignUpdate_not_a_macro( + &ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { + return nil, errors.New("signpkcs1v15: failed to update signature") + } + } + sig := make([]byte, C.EVP_PKEY_size(key.key)) + var sigblen C.uint + if 1 != C.EVP_SignFinal(&ctx, + ((*C.uchar)(unsafe.Pointer(&sig[0]))), &sigblen, key.key) { + return nil, errors.New("signpkcs1v15: failed to finalize signature") + } + return sig[:sigblen], nil +} + +func (key *pKey) VerifyPKCS1v15(method Method, data, sig []byte) error { + var ctx C.EVP_MD_CTX + C.EVP_MD_CTX_init(&ctx) + defer C.EVP_MD_CTX_cleanup(&ctx) + + if 1 != C.EVP_VerifyInit_not_a_macro(&ctx, method) { + return errors.New("verifypkcs1v15: failed to init verify") + } + if len(data) > 0 { + if 1 != C.EVP_VerifyUpdate_not_a_macro( + &ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { + return errors.New("verifypkcs1v15: failed to update verify") + } + } + if 1 != C.EVP_VerifyFinal(&ctx, + ((*C.uchar)(unsafe.Pointer(&sig[0]))), C.uint(len(sig)), key.key) { + return errors.New("verifypkcs1v15: failed to finalize verify") + } + return nil +} + func (key *pKey) MarshalPKCS1PrivateKeyPEM() (pem_block []byte, err error) { bio := C.BIO_new(C.BIO_s_mem())