aboutsummaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2024-05-02 16:20:05 +0900
committerKazuki Yamaguchi <k@rhe.jp>2024-05-02 16:20:05 +0900
commit386a73512f9b82238b90fd89d39782e4e1d45490 (patch)
treed51bb3d93876453bf533f22ec099deaf12575d7b /ext
parentabacf2f7e70b6b7b82dbe982e6727b943a7f873b (diff)
parenta8ef53494026057038e763af4f33aa9442249498 (diff)
downloadruby-openssl-386a73512f9b82238b90fd89d39782e4e1d45490.tar.gz
Merge branch 'maint-3.2'
* maint-3.2: Fix modular square root test with LibreSSL >= 3.8 pkcs7: raise PKCS7Error for PKCS7 without content in PKCS7.read_smime pkcs7: raise ArgumentError for PKCS7 with no content in PKCS7.new cipher: fix buffer overflow in Cipher#update ssl: allow failure on test_connect_certificate_verify_failed_exception_message .github/workflows/test.yml: synchronize with master Only CSR version 1 (encoded as 0) is allowed by PKIX standards test_asn1.rb: Remove the assertions of the time string format without second. test/openssl/test_asn1.rb: skip failing tests on LibreSSL 3.6.0 Use EVP_Digest{Sign,Verify} when available Fix performance regression in do_write(s)
Diffstat (limited to 'ext')
-rw-r--r--ext/openssl/ossl_cipher.c18
-rw-r--r--ext/openssl/ossl_pkcs7.c8
2 files changed, 22 insertions, 4 deletions
diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c
index 1910a5cd..6f74c925 100644
--- a/ext/openssl/ossl_cipher.c
+++ b/ext/openssl/ossl_cipher.c
@@ -386,11 +386,23 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self)
in = (unsigned char *)RSTRING_PTR(data);
in_len = RSTRING_LEN(data);
GetCipher(self, ctx);
- out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);
- if (out_len <= 0) {
+
+ /*
+ * As of OpenSSL 3.2, there is no reliable way to determine the required
+ * output buffer size for arbitrary cipher modes.
+ * https://github.com/openssl/openssl/issues/22628
+ *
+ * in_len+block_size is usually sufficient, but AES key wrap with padding
+ * ciphers require in_len+15 even though they have a block size of 8 bytes.
+ *
+ * Using EVP_MAX_BLOCK_LENGTH (32) as a safe upper bound for ciphers
+ * currently implemented in OpenSSL, but this can change in the future.
+ */
+ if (in_len > LONG_MAX - EVP_MAX_BLOCK_LENGTH) {
ossl_raise(rb_eRangeError,
"data too big to make output buffer: %ld bytes", in_len);
}
+ out_len = in_len + EVP_MAX_BLOCK_LENGTH;
if (NIL_P(str)) {
str = rb_str_new(0, out_len);
@@ -401,7 +413,7 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self)
if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len))
ossl_raise(eCipherError, NULL);
- assert(out_len < RSTRING_LEN(str));
+ assert(out_len <= RSTRING_LEN(str));
rb_str_set_len(str, out_len);
return str;
diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c
index 78dcbd66..aeeb4bf5 100644
--- a/ext/openssl/ossl_pkcs7.c
+++ b/ext/openssl/ossl_pkcs7.c
@@ -165,7 +165,11 @@ ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg)
out = NULL;
pkcs7 = SMIME_read_PKCS7(in, &out);
BIO_free(in);
- if(!pkcs7) ossl_raise(ePKCS7Error, NULL);
+ if (!pkcs7)
+ ossl_raise(ePKCS7Error, "Could not parse the PKCS7");
+ if (!pkcs7->d.ptr)
+ ossl_raise(ePKCS7Error, "No content in PKCS7");
+
data = out ? ossl_membio2str(out) : Qnil;
SetPKCS7(ret, pkcs7);
ossl_pkcs7_set_data(ret, data);
@@ -346,6 +350,8 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
BIO_free(in);
if (!p7)
ossl_raise(rb_eArgError, "Could not parse the PKCS7");
+ if (!p7->d.ptr)
+ ossl_raise(rb_eArgError, "No content in PKCS7");
RTYPEDDATA_DATA(self) = p7;
PKCS7_free(p7_orig);