mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00:00
[ruby/openssl] Revert "pkey: stop retrying after non-retryable error from OSSL_DECODER"
This reverts commit https://github.com/ruby/openssl/commit/5347880c6eb0 and https://github.com/ruby/openssl/commit/985ba27d6339. These commits attempted to stop processing after the first relevant PEM block, whether it is successful or not, when the input contains multiple keys. It turned out that it cannot be reliably determined using the OSSL_DECODER API. There is an edge case where OSSL_DECODER_from_bio() reports "unsupported" even though the input actually contains an error: https://redirect.github.com/ruby/openssl/pull/931#discussion_r2347813807 Revert the changes for now and keep the existing behavior, as partial support does not seem worth the added complexity. https://github.com/ruby/openssl/commit/319cd4952a
This commit is contained in:
parent
9c85a94f5f
commit
08e7b5f2bd
@ -83,15 +83,13 @@ ossl_pkey_wrap(EVP_PKEY *pkey)
|
||||
# include <openssl/decoder.h>
|
||||
|
||||
static EVP_PKEY *
|
||||
ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass,
|
||||
int *retryable)
|
||||
ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass)
|
||||
{
|
||||
void *ppass = (void *)pass;
|
||||
OSSL_DECODER_CTX *dctx;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
int pos = 0, pos2;
|
||||
|
||||
*retryable = 0;
|
||||
dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, input_type, NULL, NULL,
|
||||
selection, NULL, NULL);
|
||||
if (!dctx)
|
||||
@ -102,25 +100,17 @@ ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass,
|
||||
goto out;
|
||||
while (1) {
|
||||
if (OSSL_DECODER_from_bio(dctx, bio) == 1)
|
||||
goto out;
|
||||
if (BIO_eof(bio))
|
||||
break;
|
||||
// Error queue may not be populated in OpenSSL < 3.0.11 and < 3.1.3
|
||||
// https://github.com/openssl/openssl/pull/21603
|
||||
unsigned long err = ERR_peek_error();
|
||||
if (err && ERR_GET_REASON(err) != ERR_R_UNSUPPORTED)
|
||||
break;
|
||||
if (BIO_eof(bio) == 1) {
|
||||
*retryable = 1;
|
||||
break;
|
||||
}
|
||||
pos2 = BIO_tell(bio);
|
||||
if (pos2 < 0 || pos2 <= pos) {
|
||||
*retryable = 1;
|
||||
if (pos2 < 0 || pos2 <= pos)
|
||||
break;
|
||||
}
|
||||
ossl_clear_error();
|
||||
pos = pos2;
|
||||
}
|
||||
out:
|
||||
OSSL_BIO_reset(bio);
|
||||
OSSL_DECODER_CTX_free(dctx);
|
||||
return pkey;
|
||||
}
|
||||
@ -128,6 +118,7 @@ ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass,
|
||||
EVP_PKEY *
|
||||
ossl_pkey_read_generic(BIO *bio, VALUE pass)
|
||||
{
|
||||
EVP_PKEY *pkey = NULL;
|
||||
/* First check DER, then check PEM. */
|
||||
const char *input_types[] = {"DER", "PEM"};
|
||||
int input_type_num = (int)(sizeof(input_types) / sizeof(char *));
|
||||
@ -176,22 +167,18 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
|
||||
EVP_PKEY_PUBLIC_KEY
|
||||
};
|
||||
int selection_num = (int)(sizeof(selections) / sizeof(int));
|
||||
int i, j;
|
||||
|
||||
for (int i = 0; i < input_type_num; i++) {
|
||||
for (int j = 0; j < selection_num; j++) {
|
||||
if (i || j) {
|
||||
ossl_clear_error();
|
||||
BIO_reset(bio);
|
||||
for (i = 0; i < input_type_num; i++) {
|
||||
for (j = 0; j < selection_num; j++) {
|
||||
pkey = ossl_pkey_read(bio, input_types[i], selections[j], pass);
|
||||
if (pkey) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
int retryable;
|
||||
EVP_PKEY *pkey = ossl_pkey_read(bio, input_types[i], selections[j],
|
||||
pass, &retryable);
|
||||
if (pkey || !retryable)
|
||||
return pkey;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
out:
|
||||
return pkey;
|
||||
}
|
||||
#else
|
||||
EVP_PKEY *
|
||||
|
||||
@ -124,17 +124,6 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
|
||||
}
|
||||
}
|
||||
assert_equal(1, called)
|
||||
|
||||
# Incorrect passphrase returned by the block. The input contains two PEM
|
||||
# blocks.
|
||||
called = 0
|
||||
assert_raise(OpenSSL::PKey::PKeyError) {
|
||||
OpenSSL::PKey.read(encrypted_pem + encrypted_pem) {
|
||||
called += 1
|
||||
"incorrect_passphrase"
|
||||
}
|
||||
}
|
||||
assert_equal(1, called)
|
||||
end
|
||||
|
||||
def test_s_read_passphrase_tty
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user