Skip to content

Commit 319cd49

Browse files
committed
Revert "pkey: stop retrying after non-retryable error from OSSL_DECODER"
This reverts commit 5347880 and 985ba27. 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.
1 parent 8b184a3 commit 319cd49

File tree

2 files changed

+14
-38
lines changed

2 files changed

+14
-38
lines changed

ext/openssl/ossl_pkey.c

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,13 @@ ossl_pkey_wrap(EVP_PKEY *pkey)
8383
# include <openssl/decoder.h>
8484

8585
static EVP_PKEY *
86-
ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass,
87-
int *retryable)
86+
ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass)
8887
{
8988
void *ppass = (void *)pass;
9089
OSSL_DECODER_CTX *dctx;
9190
EVP_PKEY *pkey = NULL;
9291
int pos = 0, pos2;
9392

94-
*retryable = 0;
9593
dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, input_type, NULL, NULL,
9694
selection, NULL, NULL);
9795
if (!dctx)
@@ -102,32 +100,25 @@ ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass,
102100
goto out;
103101
while (1) {
104102
if (OSSL_DECODER_from_bio(dctx, bio) == 1)
103+
goto out;
104+
if (BIO_eof(bio))
105105
break;
106-
// Error queue may not be populated in OpenSSL < 3.0.11 and < 3.1.3
107-
// https://github.com/openssl/openssl/pull/21603
108-
unsigned long err = ERR_peek_error();
109-
if (err && ERR_GET_REASON(err) != ERR_R_UNSUPPORTED)
110-
break;
111-
if (BIO_eof(bio) == 1) {
112-
*retryable = 1;
113-
break;
114-
}
115106
pos2 = BIO_tell(bio);
116-
if (pos2 < 0 || pos2 <= pos) {
117-
*retryable = 1;
107+
if (pos2 < 0 || pos2 <= pos)
118108
break;
119-
}
120109
ossl_clear_error();
121110
pos = pos2;
122111
}
123112
out:
113+
OSSL_BIO_reset(bio);
124114
OSSL_DECODER_CTX_free(dctx);
125115
return pkey;
126116
}
127117

128118
EVP_PKEY *
129119
ossl_pkey_read_generic(BIO *bio, VALUE pass)
130120
{
121+
EVP_PKEY *pkey = NULL;
131122
/* First check DER, then check PEM. */
132123
const char *input_types[] = {"DER", "PEM"};
133124
int input_type_num = (int)(sizeof(input_types) / sizeof(char *));
@@ -176,22 +167,18 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
176167
EVP_PKEY_PUBLIC_KEY
177168
};
178169
int selection_num = (int)(sizeof(selections) / sizeof(int));
170+
int i, j;
179171

180-
for (int i = 0; i < input_type_num; i++) {
181-
for (int j = 0; j < selection_num; j++) {
182-
if (i || j) {
183-
ossl_clear_error();
184-
BIO_reset(bio);
172+
for (i = 0; i < input_type_num; i++) {
173+
for (j = 0; j < selection_num; j++) {
174+
pkey = ossl_pkey_read(bio, input_types[i], selections[j], pass);
175+
if (pkey) {
176+
goto out;
185177
}
186-
187-
int retryable;
188-
EVP_PKEY *pkey = ossl_pkey_read(bio, input_types[i], selections[j],
189-
pass, &retryable);
190-
if (pkey || !retryable)
191-
return pkey;
192178
}
193179
}
194-
return NULL;
180+
out:
181+
return pkey;
195182
}
196183
#else
197184
EVP_PKEY *

test/openssl/test_pkey.rb

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,6 @@ def test_s_read_passphrase
124124
}
125125
}
126126
assert_equal(1, called)
127-
128-
# Incorrect passphrase returned by the block. The input contains two PEM
129-
# blocks.
130-
called = 0
131-
assert_raise(OpenSSL::PKey::PKeyError) {
132-
OpenSSL::PKey.read(encrypted_pem + encrypted_pem) {
133-
called += 1
134-
"incorrect_passphrase"
135-
}
136-
}
137-
assert_equal(1, called)
138127
end
139128

140129
def test_s_read_passphrase_tty

0 commit comments

Comments
 (0)