Skip to content

Commit

Permalink
Set mark and pop error in d2i_PrivateKey_ex
Browse files Browse the repository at this point in the history
This commit sets the error mark before calling old_priv_decode and if
old_priv_decode returns false, and if EVP_PKCS82PKEY is successful, the
errors are popped to the previously set mark.

The motivation for this is an issue we found when linking Node.js
against OpenSSL 3.0. Details can be found in the link below and the
test case provided in this commit attempts cover this.

Refs: https://github.com/danbev/learning-libcrypto#asn1-wrong-tag-issue
Refs: nodejs/node#29817
  • Loading branch information
danbev committed Oct 5, 2020
1 parent 6514dee commit a39ca55
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
2 changes: 2 additions & 0 deletions crypto/asn1/d2i_pr.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ EVP_PKEY *d2i_PrivateKey_ex(int type, EVP_PKEY **a, const unsigned char **pp,
goto err;
}

ERR_set_mark();
if (!ret->ameth->old_priv_decode ||
!ret->ameth->old_priv_decode(ret, &p, length)) {
if (ret->ameth->priv_decode != NULL
Expand All @@ -60,6 +61,7 @@ EVP_PKEY *d2i_PrivateKey_ex(int type, EVP_PKEY **a, const unsigned char **pp,
goto err;
EVP_PKEY_free(ret);
ret = tmp;
ERR_pop_to_mark();
if (EVP_PKEY_type(type) != EVP_PKEY_base_id(ret))
goto err;
} else {
Expand Down
23 changes: 23 additions & 0 deletions test/evp_extra_test2.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/provider.h>
#include "testutil.h"
#include "internal/nelem.h"
Expand Down Expand Up @@ -248,6 +249,27 @@ static int test_alternative_default(void)
return ok;
}

static int test_d2i_PrivateKey_ex(void) {
int ok;
OSSL_PROVIDER *provider;
BIO *key_bio;
EVP_PKEY* pkey;
ok = 0;

provider = OSSL_PROVIDER_load(NULL, "default");
key_bio = BIO_new_mem_buf((&keydata[0])->kder, (&keydata)[0]->size);

ok = TEST_ptr(pkey = PEM_read_bio_PrivateKey(key_bio, NULL, NULL, NULL));
TEST_int_eq(ERR_peek_error(), 0);
test_openssl_errors();

EVP_PKEY_free(pkey);
BIO_free(key_bio);
OSSL_PROVIDER_unload(provider);

return ok;
}

int setup_tests(void)
{
mainctx = OPENSSL_CTX_new();
Expand All @@ -264,6 +286,7 @@ int setup_tests(void)

ADD_TEST(test_alternative_default);
ADD_ALL_TESTS(test_d2i_AutoPrivateKey_ex, OSSL_NELEM(keydata));
ADD_TEST(test_d2i_PrivateKey_ex);

return 1;
}
Expand Down

0 comments on commit a39ca55

Please sign in to comment.