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

add func to verify rsa signature #8

Merged
merged 3 commits into from
Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
79 changes: 79 additions & 0 deletions rsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package openssl
import "C"
import (
"errors"
"strings"
"unsafe"
)

Expand Down Expand Up @@ -75,3 +76,81 @@ func VerifyRecoverRSASignature(publicKey, signature []byte) ([]byte, error) {
recoveredBytes := C.GoBytes(unsafe.Pointer(rout), C.int(routlen))
return recoveredBytes, nil
}

// VerifyRSASignature verifies that a signature is valid for some data and a Public Key
// - Parameter publicKey: The OpenSSL EVP_PKEY public key in DER format
// - Parameter signature: The signature to verify in DER format
// - Parameter data: The data used to generate the signature
// - Parameter digest: The name of the digest to use. The currently supported values are: sha1, sha224, sha256, sha384, sha512, ripemd160, rsassapss
// - Returns: True if the signature was verified
func VerifyRSASignature(publicKey, signature, data []byte, digest string) (bool, error) {
digest = strings.ToLower(digest)
digestName := "sha256"
switch {
case strings.Contains(digest, "sha1"):
digestName = "sha1"
case strings.Contains(digest, "sha224"):
digestName = "sha224"
case strings.Contains(digest, "sha256"), strings.Contains(digest, "rsassapss"):
digestName = "sha256"
case strings.Contains(digest, "sha384"):
digestName= "sha384"
case strings.Contains(digest, "sha512"):
digestName = "sha512"
case strings.Contains(digest, "ripemd160"):
digestName = "ripemd160"
}
md, err := GetDigestByName(digestName)
if err != nil {
return false, err
}

inf := C.BIO_new(C.BIO_s_mem())
if inf == nil {
return false, errors.New("failed allocating input buffer")
}
defer C.BIO_free(inf)
_, err = asAnyBio(inf).Write(publicKey)
if err != nil {
return false, err
}
pubKey := C.d2i_PUBKEY_bio(inf, nil)
if pubKey == nil {
return false, errors.New("failed to load public key")
}
defer C.EVP_PKEY_free(pubKey)
ctx := C.EVP_PKEY_CTX_new(pubKey, nil)
if ctx == nil {
return false, errors.New("failed to setup context")
}
defer C.EVP_PKEY_CTX_free(ctx)

mdctx := C.EVP_MD_CTX_new()
defer C.EVP_MD_CTX_free(mdctx)

nRes := C.EVP_DigestVerifyInit(mdctx, &ctx, md.ptr, nil, pubKey)
if nRes != 1 {
return false, errors.New("unable to init digest verify")
}

if strings.Contains(digestName, "rsassapss") {
if C.X_EVP_PKEY_CTX_ctrl_str(ctx, C.CString("rsa_padding_mode"), C.CString("pss") ) <= 0 {
return false, errors.New("failed to set rsa padding mode")
}
if C.X_EVP_PKEY_CTX_ctrl_str(ctx, C.CString("rsa_pss_saltlen"), C.CString("auto")) <= 0 {
return false, errors.New("failed to set rsa pss saltlen")
}
}

nRes = C.EVP_DigestUpdate(mdctx, unsafe.Pointer((*C.uchar)(&data[0])), C.size_t(len(data)))
if nRes != 1 {
return false, errors.New("unable to update digest")
}

nRes = C.EVP_DigestVerifyFinal(mdctx, (*C.uchar)(&signature[0]), C.size_t(len(signature)))
if nRes != 1 {
return false, nil
}

return true, nil
}
4 changes: 4 additions & 0 deletions shim.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,10 @@ int X_EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad) {
return EVP_PKEY_CTX_set_rsa_padding(ctx, pad);
}

int X_EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) {
return EVP_PKEY_CTX_ctrl_str(ctx, type, value);
}

size_t X_HMAC_size(const HMAC_CTX *e) {
return HMAC_size(e);
}
Expand Down
1 change: 1 addition & 0 deletions shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ 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_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad);
extern int X_EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value);

/* HMAC methods */
extern size_t X_HMAC_size(const HMAC_CTX *e);
Expand Down