Skip to content

Commit 29d89c9

Browse files
danbevaddaleax
authored andcommitted
src: split CryptoPemCallback into two functions
Currently the function CryptoPemCallback is used for two things: 1. As a passphrase callback. 2. To avoid the default OpenSSL passphrase routine. The default OpenSSL passphase routine would apply if both the callback and the passphrase are null pointers and the typical behaviour is to prompt for the passphase which is not appropriate in node. This commit suggests that the PasswordCallback function only handle passphrases, and that an additional function named NoPasswordCallback used for the second case to avoid OpenSSL's passphase routine. PR-URL: #12827 Reviewed-By: Sam Roberts <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent 7e5ed8b commit 29d89c9

File tree

1 file changed

+22
-11
lines changed

1 file changed

+22
-11
lines changed

src/node_crypto.cc

+22-11
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,6 @@ static void crypto_lock_cb(int mode, int n, const char* file, int line) {
229229
}
230230

231231

232-
// This callback is used by OpenSSL when it needs to query for the passphrase
233-
// which may be used for encrypted PEM structures.
234232
static int PasswordCallback(char *buf, int size, int rwflag, void *u) {
235233
if (u) {
236234
size_t buflen = static_cast<size_t>(size);
@@ -244,6 +242,16 @@ static int PasswordCallback(char *buf, int size, int rwflag, void *u) {
244242
}
245243

246244

245+
// This callback is used to avoid the default passphrase callback in OpenSSL
246+
// which will typically prompt for the passphrase. The prompting is designed
247+
// for the OpenSSL CLI, but works poorly for Node.js because it involves
248+
// synchronous interaction with the controlling terminal, something we never
249+
// want, and use this function to avoid it.
250+
static int NoPasswordCallback(char *buf, int size, int rwflag, void *u) {
251+
return 0;
252+
}
253+
254+
247255
void ThrowCryptoError(Environment* env,
248256
unsigned long err, // NOLINT(runtime/int)
249257
const char* default_message = nullptr) {
@@ -613,7 +621,7 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
613621
// that we are interested in
614622
ERR_clear_error();
615623

616-
x = PEM_read_bio_X509_AUX(in, nullptr, PasswordCallback, nullptr);
624+
x = PEM_read_bio_X509_AUX(in, nullptr, NoPasswordCallback, nullptr);
617625

618626
if (x == nullptr) {
619627
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
@@ -631,7 +639,10 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
631639
goto done;
632640
}
633641

634-
while ((extra = PEM_read_bio_X509(in, nullptr, PasswordCallback, nullptr))) {
642+
while ((extra = PEM_read_bio_X509(in,
643+
nullptr,
644+
NoPasswordCallback,
645+
nullptr))) {
635646
if (sk_X509_push(extra_certs, extra))
636647
continue;
637648

@@ -728,7 +739,7 @@ static X509_STORE* NewRootCertStore() {
728739
if (root_certs_vector.empty()) {
729740
for (size_t i = 0; i < arraysize(root_certs); i++) {
730741
BIO* bp = NodeBIO::NewFixed(root_certs[i], strlen(root_certs[i]));
731-
X509 *x509 = PEM_read_bio_X509(bp, nullptr, PasswordCallback, nullptr);
742+
X509 *x509 = PEM_read_bio_X509(bp, nullptr, NoPasswordCallback, nullptr);
732743
BIO_free(bp);
733744

734745
// Parse errors from the built-in roots are fatal.
@@ -771,7 +782,7 @@ void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
771782

772783
X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_);
773784
while (X509* x509 =
774-
PEM_read_bio_X509(bio, nullptr, PasswordCallback, nullptr)) {
785+
PEM_read_bio_X509(bio, nullptr, NoPasswordCallback, nullptr)) {
775786
if (cert_store == root_cert_store) {
776787
cert_store = NewRootCertStore();
777788
SSL_CTX_set_cert_store(sc->ctx_, cert_store);
@@ -803,7 +814,7 @@ void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
803814
return;
804815

805816
X509_CRL* crl =
806-
PEM_read_bio_X509_CRL(bio, nullptr, PasswordCallback, nullptr);
817+
PEM_read_bio_X509_CRL(bio, nullptr, NoPasswordCallback, nullptr);
807818

808819
if (crl == nullptr) {
809820
BIO_free_all(bio);
@@ -842,7 +853,7 @@ static unsigned long AddCertsFromFile( // NOLINT(runtime/int)
842853
}
843854

844855
while (X509* x509 =
845-
PEM_read_bio_X509(bio, nullptr, PasswordCallback, nullptr)) {
856+
PEM_read_bio_X509(bio, nullptr, NoPasswordCallback, nullptr)) {
846857
X509_STORE_add_cert(store, x509);
847858
X509_free(x509);
848859
}
@@ -4387,7 +4398,7 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
43874398
// Split this out into a separate function once we have more than one
43884399
// consumer of public keys.
43894400
if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
4390-
pkey = PEM_read_bio_PUBKEY(bp, nullptr, PasswordCallback, nullptr);
4401+
pkey = PEM_read_bio_PUBKEY(bp, nullptr, NoPasswordCallback, nullptr);
43914402
if (pkey == nullptr)
43924403
goto exit;
43934404
} else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
@@ -4403,7 +4414,7 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
44034414
goto exit;
44044415
} else {
44054416
// X.509 fallback
4406-
x509 = PEM_read_bio_X509(bp, nullptr, PasswordCallback, nullptr);
4417+
x509 = PEM_read_bio_X509(bp, nullptr, NoPasswordCallback, nullptr);
44074418
if (x509 == nullptr)
44084419
goto exit;
44094420

@@ -4530,7 +4541,7 @@ bool PublicKeyCipher::Cipher(const char* key_pem,
45304541
goto exit;
45314542
} else if (operation == kPublic &&
45324543
strncmp(key_pem, CERTIFICATE_PFX, CERTIFICATE_PFX_LEN) == 0) {
4533-
x509 = PEM_read_bio_X509(bp, nullptr, PasswordCallback, nullptr);
4544+
x509 = PEM_read_bio_X509(bp, nullptr, NoPasswordCallback, nullptr);
45344545
if (x509 == nullptr)
45354546
goto exit;
45364547

0 commit comments

Comments
 (0)