diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2017-05-15 23:47:47 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2020-05-13 17:47:45 +0900 |
commit | ae1945459295e4a08a243aa331551b588291c542 (patch) | |
tree | 874dae2ebafca5d3dfa34f958fa953b7b328cd4c /ext | |
parent | 9ff6e5143b51ac7fd1947ceb680d8944451d1ab4 (diff) | |
download | ruby-openssl-ae1945459295e4a08a243aa331551b588291c542.tar.gz |
pkey: support 'one-shot' signing and verification
OpenSSL 1.1.1 added EVP_DigestSign() and EVP_DigestVerify() functions
to the interface. Some EVP_PKEY methods such as PureEdDSA algorithms
do not support the streaming mechanism and require us to use them.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/openssl/ossl_pkey.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 5c646366..adcc5b6a 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -719,6 +719,26 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) EVP_MD_CTX_free(ctx); ossl_raise(ePKeyError, "EVP_DigestSignInit"); } +#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER) + if (EVP_DigestSign(ctx, NULL, &siglen, (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)) < 1) { + EVP_MD_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_DigestSign"); + } + if (siglen > LONG_MAX) + rb_raise(ePKeyError, "signature would be too large"); + sig = ossl_str_new(NULL, (long)siglen, &state); + if (state) { + EVP_MD_CTX_free(ctx); + rb_jump_tag(state); + } + if (EVP_DigestSign(ctx, (unsigned char *)RSTRING_PTR(sig), &siglen, + (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)) < 1) { + EVP_MD_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_DigestSign"); + } +#else if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) { EVP_MD_CTX_free(ctx); ossl_raise(ePKeyError, "EVP_DigestSignUpdate"); @@ -739,6 +759,7 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) EVP_MD_CTX_free(ctx); ossl_raise(ePKeyError, "EVP_DigestSignFinal"); } +#endif EVP_MD_CTX_free(ctx); rb_str_set_len(sig, siglen); return sig; @@ -787,6 +808,14 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) EVP_MD_CTX_free(ctx); ossl_raise(ePKeyError, "EVP_DigestVerifyInit"); } +#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER) + ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig), + RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)); + EVP_MD_CTX_free(ctx); + if (ret < 0) + ossl_raise(ePKeyError, "EVP_DigestVerify"); +#else if (EVP_DigestVerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) { EVP_MD_CTX_free(ctx); ossl_raise(ePKeyError, "EVP_DigestVerifyUpdate"); @@ -796,6 +825,7 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) EVP_MD_CTX_free(ctx); if (ret < 0) ossl_raise(ePKeyError, "EVP_DigestVerifyFinal"); +#endif if (ret) return Qtrue; else { |