Skip to content

Commit 55485ff

Browse files
pimterrytargos
authored andcommitted
crypto: return clear errors when loading invalid PFX data
PR-URL: #49566 Reviewed-By: Ben Noordhuis <[email protected]>
1 parent c48cd84 commit 55485ff

File tree

3 files changed

+74
-25
lines changed

3 files changed

+74
-25
lines changed

src/crypto/crypto_context.cc

+51-25
Original file line numberDiff line numberDiff line change
@@ -1052,34 +1052,60 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
10521052
EVP_PKEY* pkey_ptr = nullptr;
10531053
X509* cert_ptr = nullptr;
10541054
STACK_OF(X509)* extra_certs_ptr = nullptr;
1055-
if (d2i_PKCS12_bio(in.get(), &p12_ptr) &&
1056-
(p12.reset(p12_ptr), true) && // Move ownership to the smart pointer.
1057-
PKCS12_parse(p12.get(), pass.data(),
1058-
&pkey_ptr,
1059-
&cert_ptr,
1060-
&extra_certs_ptr) &&
1061-
(pkey.reset(pkey_ptr), cert.reset(cert_ptr),
1062-
extra_certs.reset(extra_certs_ptr), true) && // Move ownership.
1063-
SSL_CTX_use_certificate_chain(sc->ctx_.get(),
1064-
std::move(cert),
1065-
extra_certs.get(),
1066-
&sc->cert_,
1067-
&sc->issuer_) &&
1068-
SSL_CTX_use_PrivateKey(sc->ctx_.get(), pkey.get())) {
1069-
// Add CA certs too
1070-
for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) {
1071-
X509* ca = sk_X509_value(extra_certs.get(), i);
1072-
1073-
if (cert_store == GetOrCreateRootCertStore()) {
1074-
cert_store = NewRootCertStore();
1075-
SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
1076-
}
1077-
X509_STORE_add_cert(cert_store, ca);
1078-
SSL_CTX_add_client_CA(sc->ctx_.get(), ca);
1055+
1056+
if (!d2i_PKCS12_bio(in.get(), &p12_ptr)) {
1057+
goto done;
1058+
}
1059+
1060+
// Move ownership to the smart pointer:
1061+
p12.reset(p12_ptr);
1062+
1063+
if (!PKCS12_parse(
1064+
p12.get(), pass.data(), &pkey_ptr, &cert_ptr, &extra_certs_ptr)) {
1065+
goto done;
1066+
}
1067+
1068+
// Move ownership of the parsed data:
1069+
pkey.reset(pkey_ptr);
1070+
cert.reset(cert_ptr);
1071+
extra_certs.reset(extra_certs_ptr);
1072+
1073+
if (!pkey) {
1074+
return THROW_ERR_CRYPTO_OPERATION_FAILED(
1075+
env, "Unable to load private key from PFX data");
1076+
}
1077+
1078+
if (!cert) {
1079+
return THROW_ERR_CRYPTO_OPERATION_FAILED(
1080+
env, "Unable to load certificate from PFX data");
1081+
}
1082+
1083+
if (!SSL_CTX_use_certificate_chain(sc->ctx_.get(),
1084+
std::move(cert),
1085+
extra_certs.get(),
1086+
&sc->cert_,
1087+
&sc->issuer_)) {
1088+
goto done;
1089+
}
1090+
1091+
if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), pkey.get())) {
1092+
goto done;
1093+
}
1094+
1095+
// Add CA certs too
1096+
for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) {
1097+
X509* ca = sk_X509_value(extra_certs.get(), i);
1098+
1099+
if (cert_store == GetOrCreateRootCertStore()) {
1100+
cert_store = NewRootCertStore();
1101+
SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
10791102
}
1080-
ret = true;
1103+
X509_STORE_add_cert(cert_store, ca);
1104+
SSL_CTX_add_client_CA(sc->ctx_.get(), ca);
10811105
}
1106+
ret = true;
10821107

1108+
done:
10831109
if (!ret) {
10841110
// TODO(@jasnell): Should this use ThrowCryptoError?
10851111
unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
1.45 KB
Binary file not shown.

test/parallel/test-tls-invalid-pfx.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
const common = require('../common');
3+
if (!common.hasCrypto)
4+
common.skip('missing crypto');
5+
const fixtures = require('../common/fixtures');
6+
7+
const {
8+
assert, connect, keys
9+
} = require(fixtures.path('tls-connect'));
10+
11+
const invalidPfx = fixtures.readKey('cert-without-key.pfx');
12+
13+
connect({
14+
client: {
15+
pfx: invalidPfx,
16+
passphrase: 'test',
17+
rejectUnauthorized: false
18+
},
19+
server: keys.agent1
20+
}, common.mustCall((e, pair, cleanup) => {
21+
assert.strictEqual(e.message, 'Unable to load private key from PFX data');
22+
cleanup();
23+
}));

0 commit comments

Comments
 (0)