fix(crypto): fix segfault in X509Certificate.issuerCertificate getter (#27025)

This commit is contained in:
robobun
2026-02-14 05:58:41 -08:00
committed by GitHub
parent 883e43c371
commit 38f41dccdf
2 changed files with 37 additions and 14 deletions

View File

@@ -560,6 +560,8 @@ JSC_DEFINE_CUSTOM_GETTER(jsX509CertificateGetter_infoAccess, (JSGlobalObject * g
return JSValue::encode(jsUndefined());
BUF_MEM* bptr = bio;
if (!bptr)
return JSValue::encode(jsUndefined());
return JSValue::encode(undefinedIfEmpty(jsString(vm, String::fromUTF8(std::span(bptr->data, bptr->length)))));
}
@@ -602,20 +604,10 @@ JSC_DEFINE_CUSTOM_GETTER(jsX509CertificateGetter_issuerCertificate, (JSGlobalObj
return {};
}
auto issuerCert = thisObject->view().getIssuer();
if (!issuerCert)
return JSValue::encode(jsUndefined());
auto bio = issuerCert.get();
BUF_MEM* bptr = nullptr;
BIO_get_mem_ptr(bio, &bptr);
std::span<const uint8_t> span(reinterpret_cast<const uint8_t*>(bptr->data), bptr->length);
auto* zigGlobalObject = defaultGlobalObject(globalObject);
auto* structure = zigGlobalObject->m_JSX509CertificateClassStructure.get(zigGlobalObject);
auto jsIssuerCert = JSX509Certificate::create(vm, structure, globalObject, span);
RETURN_IF_EXCEPTION(scope, {});
return JSValue::encode(jsIssuerCert);
// issuerCertificate is only available when the certificate was obtained from
// a TLS connection with a peer certificate chain. For certificates parsed
// directly from PEM/DER data, it is always undefined (matching Node.js behavior).
return JSValue::encode(jsUndefined());
}
JSC_DEFINE_CUSTOM_GETTER(jsX509CertificateGetter_publicKey, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName))

View File

@@ -0,0 +1,31 @@
import { expect, test } from "bun:test";
import { X509Certificate } from "crypto";
import { readFileSync } from "fs";
import { join } from "path";
const certPem = readFileSync(join(import.meta.dir, "../../js/node/test/fixtures/keys/agent1-cert.pem"));
test("issuerCertificate should return undefined for directly-parsed certificates without crashing", () => {
const cert = new X509Certificate(certPem);
// issuerCertificate is only populated for certificates obtained from TLS
// connections with a peer certificate chain. For directly parsed certs,
// it should be undefined (matching Node.js behavior).
expect(cert.issuerCertificate).toBeUndefined();
});
test("X509Certificate properties should not crash on valid certificates", () => {
const cert = new X509Certificate(certPem);
// These should all work without segfaulting
expect(cert.subject).toBeDefined();
expect(cert.issuer).toBeDefined();
expect(cert.validFrom).toBeDefined();
expect(cert.validTo).toBeDefined();
expect(cert.fingerprint).toBeDefined();
expect(cert.fingerprint256).toBeDefined();
expect(cert.fingerprint512).toBeDefined();
expect(cert.serialNumber).toBeDefined();
expect(cert.raw).toBeInstanceOf(Uint8Array);
expect(cert.ca).toBe(false);
});