Skip to content

Commit 5a92ea7

Browse files
tniessenRafaelGSS
authored andcommittedJun 19, 2023
crypto: handle cert with invalid SPKI gracefully
When attempting to convert the SPKI of a X509Certificate to a KeyObject, throw an error if the subjectPublicKey cannot be parsed instead of aborting the process. Fixes: https://hackerone.com/bugs?report_id=1884159 PR-URL: nodejs-private/node-private#393 Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Robert Nagy <ronagy@icloud.com> CVE-ID: CVE-2023-30588
1 parent 5df04e8 commit 5a92ea7

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed
 

‎src/crypto/crypto_x509.cc

+4
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,11 @@ void X509Certificate::PublicKey(const FunctionCallbackInfo<Value>& args) {
318318
X509Certificate* cert;
319319
ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
320320

321+
// TODO(tniessen): consider checking X509_get_pubkey() when the
322+
// X509Certificate object is being created.
323+
ClearErrorOnReturn clear_error_on_return;
321324
EVPKeyPointer pkey(X509_get_pubkey(cert->get()));
325+
if (!pkey) return ThrowCryptoError(env, ERR_get_error());
322326
ManagedEVPPKey epkey(std::move(pkey));
323327
std::shared_ptr<KeyObjectData> key_data =
324328
KeyObjectData::CreateAsymmetric(kKeyTypePublic, epkey);

‎test/parallel/test-crypto-x509.js

+39
Original file line numberDiff line numberDiff line change
@@ -317,3 +317,42 @@ oans248kpal88CGqsN2so/wZKxVnpiXlPHMdiNL7hRSUqlHkUi07FrP2Htg8kjI=
317317
legacyObject.serialNumber,
318318
legacyObjectCheck.serialNumber);
319319
}
320+
321+
{
322+
// This X.509 Certificate can be parsed by OpenSSL because it contains a
323+
// structurally sound TBSCertificate structure. However, the SPKI field of the
324+
// TBSCertificate contains the subjectPublicKey as a BIT STRING, and this bit
325+
// sequence is not a valid public key. Ensure that X509Certificate.publicKey
326+
// does not abort in this case.
327+
328+
const certPem = `-----BEGIN CERTIFICATE-----
329+
MIIDpDCCAw0CFEc1OZ8g17q+PZnna3iQ/gfoZ7f3MA0GCSqGSIb3DQEBBQUAMIHX
330+
MRMwEQYLKwYBBAGCNzwCAQMTAkdJMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXph
331+
dGlvbjEOMAwGA1UEBRMFOTkxOTExCzAJBgNVBAYTAkdJMRIwEAYDVQQIFAlHaWJy
332+
YWx0YXIxEjAQBgNVBAcUCUdpYnJhbHRhcjEgMB4GA1UEChQXV0hHIChJbnRlcm5h
333+
dGlvbmFsKSBMdGQxHDAaBgNVBAsUE0ludGVyYWN0aXZlIEJldHRpbmcxHDAaBgNV
334+
BAMUE3d3dy53aWxsaWFtaGlsbC5jb20wIhgPMjAxNDAyMDcwMDAwMDBaGA8yMDE1
335+
MDIyMTIzNTk1OVowgbAxCzAJBgNVBAYTAklUMQ0wCwYDVQQIEwRSb21lMRAwDgYD
336+
VQQHEwdQb21lemlhMRYwFAYDVQQKEw1UZWxlY29taXRhbGlhMRIwEAYDVQQrEwlB
337+
RE0uQVAuUE0xHTAbBgNVBAMTFHd3dy50ZWxlY29taXRhbGlhLml0MTUwMwYJKoZI
338+
hvcNAQkBFiZ2YXNlc2VyY2l6aW9wb3J0YWxpY29AdGVsZWNvbWl0YWxpYS5pdDCB
339+
nzANBgkqhkiG9w0BAQEFAAOBjQA4gYkCgYEA5m/Vf7PevH+inMfUJOc8GeR7WVhM
340+
CQwcMM5k46MSZo7kCk7VZuaq5G2JHGAGnLPaPUkeXlrf5qLpTxXXxHNtz+WrDlFt
341+
boAdnTcqpX3+72uBGOaT6Wi/9YRKuCs5D5/cAxAc3XjHfpRXMoXObj9Vy7mLndfV
342+
/wsnTfU9QVeBkgsCAwEAAaOBkjCBjzAdBgNVHQ4EFgQUfLjAjEiC83A+NupGrx5+
343+
Qe6nhRMwbgYIKwYBBQUHAQwEYjBgoV6gXDBaMFgwVhYJaW1hZ2UvZ2lmMCEwHzAH
344+
BgUrDgMCGgQUS2u5KJYGDLvQUjibKaxLB4shBRgwJhYkaHR0cDovL2xvZ28udmVy
345+
aXNpZ24uY29tL3ZzbG9nbzEuZ2lmMA0GCSqGSIb3DQEBBQUAA4GBALLiAMX0cIMp
346+
+V/JgMRhMEUKbrt5lYKfv9dil/f22ezZaFafb070jGMMPVy9O3/PavDOkHtTv3vd
347+
tAt3hIKFD1bJt6c6WtMH2Su3syosWxmdmGk5ihslB00lvLpfj/wed8i3bkcB1doq
348+
UcXd/5qu2GhokrKU2cPttU+XAN2Om6a0
349+
-----END CERTIFICATE-----`;
350+
351+
const cert = new X509Certificate(certPem);
352+
assert.throws(() => cert.publicKey, {
353+
message: common.hasOpenSSL3 ? /decode error/ : /wrong tag/,
354+
name: 'Error'
355+
});
356+
357+
assert.strictEqual(cert.checkIssued(cert), false);
358+
}

0 commit comments

Comments
 (0)
Please sign in to comment.