aboutsummaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2017-05-15 23:47:47 +0900
committerKazuki Yamaguchi <k@rhe.jp>2021-03-16 19:16:11 +0900
commitb2dc4880f5d000c3e0117ecf9c57a273cbd713f9 (patch)
tree8ef5ded37d543a01087790c319577180d8a18e76 /ext
parent5cae289682c6b8fea6324ae8f26dbcc90ebaaa2f (diff)
downloadruby-b2dc4880f5d000c3e0117ecf9c57a273cbd713f9.tar.gz
[ruby/openssl] 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. https://github.com/ruby/openssl/commit/ae19454592
Diffstat (limited to 'ext')
-rw-r--r--ext/openssl/ossl_pkey.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index a0d73f5821..19544ec7f0 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -771,6 +771,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");
@@ -791,6 +811,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;
@@ -839,6 +860,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");
@@ -848,6 +877,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 {