From e3bebf32d46f0320b24a8ce279e3e5d4a5c89fca Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Fri, 8 Sep 2023 21:44:25 +0200 Subject: [PATCH] crypto: return clear errors when loading invalid PFX data --- src/crypto/crypto_context.cc | 57 ++++++++++++++---------- test/fixtures/keys/cert-without-key.pfx | Bin 0 -> 1483 bytes test/parallel/test-tls-invalid-pfx.js | 23 ++++++++++ 3 files changed, 57 insertions(+), 23 deletions(-) create mode 100644 test/fixtures/keys/cert-without-key.pfx create mode 100644 test/parallel/test-tls-invalid-pfx.js diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index 3876adf7d72211..4c906914b75e02 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -1053,31 +1053,42 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { X509* cert_ptr = nullptr; STACK_OF(X509)* extra_certs_ptr = nullptr; if (d2i_PKCS12_bio(in.get(), &p12_ptr) && - (p12.reset(p12_ptr), true) && // Move ownership to the smart pointer. - PKCS12_parse(p12.get(), pass.data(), - &pkey_ptr, - &cert_ptr, - &extra_certs_ptr) && - (pkey.reset(pkey_ptr), cert.reset(cert_ptr), - extra_certs.reset(extra_certs_ptr), true) && // Move ownership. - SSL_CTX_use_certificate_chain(sc->ctx_.get(), - std::move(cert), - extra_certs.get(), - &sc->cert_, - &sc->issuer_) && - SSL_CTX_use_PrivateKey(sc->ctx_.get(), pkey.get())) { - // Add CA certs too - for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) { - X509* ca = sk_X509_value(extra_certs.get(), i); - - if (cert_store == GetOrCreateRootCertStore()) { - cert_store = NewRootCertStore(); - SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store); + (p12.reset(p12_ptr), true) && // Move ownership to the smart pointer. + PKCS12_parse(p12.get(), pass.data(), + &pkey_ptr, + &cert_ptr, + &extra_certs_ptr) && + (pkey.reset(pkey_ptr), cert.reset(cert_ptr), // Move ownership. + extra_certs.reset(extra_certs_ptr), true)) { + if (pkey.get() == nullptr) { + return THROW_ERR_CRYPTO_OPERATION_FAILED(env, + "Unable to load private key from PFX data"); + } + + if (cert.get() == nullptr) { + return THROW_ERR_CRYPTO_OPERATION_FAILED(env, + "Unable to load certificate from PFX data"); + } + + if (SSL_CTX_use_certificate_chain(sc->ctx_.get(), + std::move(cert), + extra_certs.get(), + &sc->cert_, + &sc->issuer_) && + SSL_CTX_use_PrivateKey(sc->ctx_.get(), pkey.get())) { + // Add CA certs too + for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) { + X509* ca = sk_X509_value(extra_certs.get(), i); + + if (cert_store == GetOrCreateRootCertStore()) { + cert_store = NewRootCertStore(); + SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store); + } + X509_STORE_add_cert(cert_store, ca); + SSL_CTX_add_client_CA(sc->ctx_.get(), ca); } - X509_STORE_add_cert(cert_store, ca); - SSL_CTX_add_client_CA(sc->ctx_.get(), ca); + ret = true; } - ret = true; } if (!ret) { diff --git a/test/fixtures/keys/cert-without-key.pfx b/test/fixtures/keys/cert-without-key.pfx new file mode 100644 index 0000000000000000000000000000000000000000..6d3dfca11fe98446931033e13becbac383c4ffe0 GIT binary patch literal 1483 zcmV;+1vL6Ff(6F{0Ru3C1$_nyDuzgg_YDCD0ic2fZUlk_YA}KYW-x*UVg?B+hDe6@ z4FLxRpn?TcFoFe70s#Opf(1wh2`Yw2hW8Bt2LUiw1_>&LNQU{y72y2mmk)1_&yKNQU#O#UHS2`M*uHl*Y}gTW4Q|oITZZb;6sl8 z(4$~E$;+L?JrMzk8(BxR;3u%tVo07nMt4gkG}qqa&eGuX8Jmo0gyfwfC#ZZv7#Od> zf7Ms*50>9X^O`|_z%csxE%??5SQ`}<3H|n^MevmqNw||p0`xmubT1pdlzs~~0zM)p z1@-J>32N$x3_xU<)7aAWlH0acz*gg(3PyHh=0ZQj=dD$qXfsfPxV^wS=`Pif&Pi?E zvXX+YyS%WMbm?6JA4Bn$Y(!(vOQNi{tj+`B*4X_K$6&6UVxv6N?k>{B#WU#1YC-bm zxK=>q`{1xwwx^F`t0DN>0z-T+A-W9ho+f4=^kUF$McklhPYxMM7+q~lrO z$l@`7JSoQS)bY5nyqGtLipeawJbqhxYX1Ro90l&dUG*OCZ8I5dxg003PcVVJv?pNG zynCut%73q?{bv5~Ojsm};it&!X=wOgB1RL?v&%*yf!V}7<6tQ}-f`6fZ}nj?&ZmR0MPr4{Y`66nsSo6FrFtZHsE!}%3^IzQ|FLg5t_dSYR(W` zCQBF-bw|o=c41Sw{xV@QRZtl|Fy_elo%iw@O$d(Zxiw)dQ5OP+)V?^)B{78g<>`m; z?`0GJcLvrYR{!a#H7;7wn3qcNJSjUPvezmA3_jH$Kpg7WT?r3pXjPQ(~l|vF1!kwnm=ZE_FKb}?L%KJ5`%fSKnRIjZnrfBbTuY|g$l~k z)`xjW;3Xl`Gm5HcICGd3Bd$ggIk$Pu2yQ8Ap;p zi#xF3uFLq=^EZfVMTuX~Zg>2^14sU<7{ZP@a!kD+x=J0tz<^OaOcor%%YI>!O~A-V zUrp-(Fm?m4RFZRa!gxNTwB;8tK`=2e4F(BdhDZTr0|WvA1povfbA{bAVR(y9g{P(W l8fsA}>cmtx`2HsZuA { + assert.strictEqual(e.message, 'Unable to load private key from PFX data'); + cleanup(); +}));