import { describe, expect, it } from 'bun:test'; import { checkCertificateRevocationAgainstCrl, createCertificate, createCertificateRevocationList, createOcspResponse, createPfx, createPkcs7CertBag, createSelfSignedCertificate, exportEncryptedPkcs8Der, exportPkcs8Pem, generateKeyPair, matchServiceIdentity, parseCertificatePem, parseCertificateRevocationListPemOrThrow, parseOcspResponseDerOrThrow, unwrap, validateOcspResponse, verifyCertificateChain, } from '#micro509'; import { toHex } from '#micro509/internal/asn1/asn1'; import { encodeName } from '#micro509/x509'; import { differentialEnabled, hexToBytes, issueChain, openSslAvailable } from '#test/helpers'; import { checkIdentityWithOpenSsl, checkRevocationWithOpenSsl, decryptPkcs8WithOpenSsl, issueAndValidateOcspResponseWithOpenSsl, readCertificateAiaWithOpenSsl, readCertificateSanWithOpenSsl, readPfxWithOpenSsl, readPkcs7CertBagWithOpenSsl, validateMicro509OcspResponseWithOpenSsl, verifyChainWithOpenSsl, } from '#test/oracles/openssl'; describe.skipIf(!openSslAvailable || !differentialEnabled)('OpenSSL differential harness', () => { it('matches OpenSSL path verdicts for valid and path-length-exceeded chains', async () => { const validChain = await issueChain(); const validMicro = await verifyCertificateChain({ leaf: validChain.leaf.der, intermediates: [validChain.intermediate.der], roots: [validChain.root.certificate.der], }); const validOpenSsl = await verifyChainWithOpenSsl({ leafPem: validChain.leaf.pem, intermediatePems: [validChain.intermediate.pem], rootPem: validChain.root.certificate.pem, }); expect(validMicro.ok).toBe(true); expect(validOpenSsl.valid).toBe(validMicro.ok); const root = await createSelfSignedCertificate({ subject: { commonName: 'Diff Root CA' }, extensions: { basicConstraints: { ca: true, pathLength: 2 }, keyUsage: ['keyCertSign', 'cRLSign'], }, }); const intermediateKeys = await generateKeyPair(); const intermediate = await createCertificate({ issuer: { commonName: 'Diff Root CA' }, subject: { commonName: 'Diff Intermediate CA' }, publicKey: intermediateKeys.publicKey, signerPrivateKey: root.keyPair.privateKey, issuerPublicKey: root.keyPair.publicKey, extensions: { basicConstraints: { ca: true, pathLength: 0 }, keyUsage: ['keyCertSign', 'cRLSign'], }, }); const subCaKeys = await generateKeyPair(); const subCa = await createCertificate({ issuer: { commonName: 'Diff Intermediate CA' }, subject: { commonName: 'Diff Sub CA' }, publicKey: subCaKeys.publicKey, signerPrivateKey: intermediateKeys.privateKey, issuerPublicKey: intermediateKeys.publicKey, extensions: { basicConstraints: { ca: true, pathLength: 0 }, keyUsage: ['keyCertSign', 'cRLSign'], }, }); const leafKeys = await generateKeyPair(); const leaf = await createCertificate({ issuer: { commonName: 'Diff Sub CA' }, subject: { commonName: 'diff.example' }, publicKey: leafKeys.publicKey, signerPrivateKey: subCaKeys.privateKey, issuerPublicKey: subCaKeys.publicKey, extensions: { keyUsage: ['digitalSignature'], extendedKeyUsage: ['serverAuth'], subjectAltNames: [{ type: 'dns', value: 'diff.example' }], }, }); const invalidMicro = await verifyCertificateChain({ leaf: leaf.der, intermediates: [subCa.der, intermediate.der], roots: [root.certificate.der], }); const invalidOpenSsl = await verifyChainWithOpenSsl({ leafPem: leaf.pem, intermediatePems: [subCa.pem, intermediate.pem], rootPem: root.certificate.pem, }); expect(invalidMicro).toMatchObject({ ok: false, code: 'path_length_exceeded' }); expect(invalidOpenSsl.valid).toBe(false); expect(invalidOpenSsl.failureClass).toBe('path_length'); }); it('matches OpenSSL direct CRL metadata and revocation verdicts', async () => { const now = new Date(); const nextUpdate = new Date(now.getTime() + 86_400_000); const issuer = await createSelfSignedCertificate({ subject: { commonName: 'Diff CRL CA' }, extensions: { basicConstraints: { ca: true, pathLength: 0 }, keyUsage: ['keyCertSign', 'cRLSign'], }, }); const leafKeys = await generateKeyPair(); const leaf = await createCertificate({ issuer: { commonName: 'Diff CRL CA' }, subject: { commonName: 'crl.example' }, publicKey: leafKeys.publicKey, signerPrivateKey: issuer.keyPair.privateKey, issuerPublicKey: issuer.keyPair.publicKey, }); const parsedLeaf = unwrap(parseCertificatePem(leaf.pem)); const goodCrl = await createCertificateRevocationList({ issuer: { commonName: 'Diff CRL CA' }, signerPrivateKey: issuer.keyPair.privateKey, issuerPublicKey: issuer.keyPair.publicKey, crlNumber: 7, thisUpdate: now, nextUpdate: nextUpdate, }); const revokedCrl = await createCertificateRevocationList({ issuer: { commonName: 'Diff CRL CA' }, signerPrivateKey: issuer.keyPair.privateKey, issuerPublicKey: issuer.keyPair.publicKey, crlNumber: 8, thisUpdate: now, nextUpdate: nextUpdate, revokedCertificates: [{ serialNumber: hexToBytes(parsedLeaf.serialNumberHex) }], }); const goodMicro = await checkCertificateRevocationAgainstCrl({ certificate: leaf.pem, issuerCertificate: issuer.certificate.pem, crl: goodCrl.pem, }); const goodOpenSsl = await checkRevocationWithOpenSsl({ certificatePem: leaf.pem, issuerCertificatePem: issuer.certificate.pem, crlPem: goodCrl.pem, }); expect(goodMicro).toMatchObject({ ok: true, value: { status: 'good' } }); expect(goodOpenSsl.status).toBe('good'); expect(goodOpenSsl.crlNumber).toBe( parseCertificateRevocationListPemOrThrow(goodCrl.pem).crlNumber, ); expect(goodOpenSsl.issuer).toContain('CN=Diff CRL CA'); const revokedMicro = await checkCertificateRevocationAgainstCrl({ certificate: leaf.pem, issuerCertificate: issuer.certificate.pem, crl: revokedCrl.pem, }); const revokedOpenSsl = await checkRevocationWithOpenSsl({ certificatePem: leaf.pem, issuerCertificatePem: issuer.certificate.pem, crlPem: revokedCrl.pem, }); expect(revokedMicro).toMatchObject({ ok: true, value: { status: 'revoked' } }); expect(revokedOpenSsl.status).toBe('revoked'); }); it('matches OpenSSL path verdicts for RSA-PSS and P-521 chains', async () => { const rsaPssRoot = await createSelfSignedCertificate({ subject: { commonName: 'Diff RSA-PSS Root CA' }, algorithm: { kind: 'rsa', modulusLength: 2048, hash: 'SHA-256', scheme: 'pss', }, signature: { kind: 'rsa-pss' }, extensions: { basicConstraints: { ca: true, pathLength: 0 }, keyUsage: ['keyCertSign', 'cRLSign'], }, }); const rsaPssLeafKeys = await generateKeyPair(); const rsaPssLeaf = await createCertificate({ issuer: { commonName: 'Diff RSA-PSS Root CA' }, subject: { commonName: 'diff-rsa-pss.example' }, publicKey: rsaPssLeafKeys.publicKey, signerPrivateKey: rsaPssRoot.keyPair.privateKey, issuerPublicKey: rsaPssRoot.keyPair.publicKey, signature: { kind: 'rsa-pss' }, extensions: { subjectAltNames: [{ type: 'dns', value: 'diff-rsa-pss.example' }], }, }); const rsaPssMicro = await verifyCertificateChain({ leaf: rsaPssLeaf.pem, roots: [rsaPssRoot.certificate.pem], }); const rsaPssOpenSsl = await verifyChainWithOpenSsl({ leafPem: rsaPssLeaf.pem, rootPem: rsaPssRoot.certificate.pem, }); expect(rsaPssMicro.ok).toBe(true); expect(rsaPssOpenSsl.valid).toBe(true); const p521Root = await createSelfSignedCertificate({ subject: { commonName: 'Diff P-521 Root CA' }, algorithm: { kind: 'ecdsa', curve: 'P-521' }, extensions: { basicConstraints: { ca: true, pathLength: 0 }, keyUsage: ['keyCertSign', 'cRLSign'], }, }); const p521LeafKeys = await generateKeyPair({ kind: 'ecdsa', curve: 'P-521' }); const p521Leaf = await createCertificate({ issuer: { commonName: 'Diff P-521 Root CA' }, subject: { commonName: 'diff-p521.example' }, publicKey: p521LeafKeys.publicKey, signerPrivateKey: p521Root.keyPair.privateKey, issuerPublicKey: p521Root.keyPair.publicKey, extensions: { subjectAltNames: [{ type: 'dns', value: 'diff-p521.example' }], }, }); const p521Micro = await verifyCertificateChain({ leaf: p521Leaf.pem, roots: [p521Root.certificate.pem], }); const p521OpenSsl = await verifyChainWithOpenSsl({ leafPem: p521Leaf.pem, rootPem: p521Root.certificate.pem, }); expect(p521Micro.ok).toBe(true); expect(p521OpenSsl.valid).toBe(true); }); it('matches OpenSSL issuer-signed OCSP status for good and revoked responses', async () => { const issuer = await createSelfSignedCertificate({ subject: { commonName: 'Diff OCSP CA' }, extensions: { basicConstraints: { ca: true, pathLength: 0 }, keyUsage: ['keyCertSign', 'cRLSign', 'digitalSignature'], }, }); const leafKeys = await generateKeyPair(); const leaf = await createCertificate({ issuer: { commonName: 'Diff OCSP CA' }, subject: { commonName: 'ocsp.example' }, publicKey: leafKeys.publicKey, signerPrivateKey: issuer.keyPair.privateKey, issuerPublicKey: issuer.keyPair.publicKey, }); const issuerPrivateKeyPem = await exportPkcs8Pem(issuer.keyPair.privateKey); for (const status of ['good', 'revoked'] as const) { const openSsl = await issueAndValidateOcspResponseWithOpenSsl({ issuerCertificatePem: issuer.certificate.pem, issuerPrivateKeyPem, certificatePem: leaf.pem, certificateStatus: status, revocationTime: new Date('2026-03-12T01:02:03Z'), }); const micro = await validateOcspResponse({ response: openSsl.responseDer, issuerCertificate: issuer.certificate.pem, }); const parsed = parseOcspResponseDerOrThrow(openSsl.responseDer); expect(openSsl.accepted).toBe(true); expect(micro.ok).toBe(openSsl.accepted); expect(parsed.responses?.[0]?.certStatus).toBe(openSsl.status); } }); it('OpenSSL parses a micro509 certificate with directoryName and SRV-ID SANs', async () => { const directoryNameDer = toHex(encodeName([{ type: 'commonName', value: 'Diff Dir CA' }])); const { certificate } = await createSelfSignedCertificate({ subject: { commonName: 'san-encode.example' }, extensions: { subjectAltNames: [ { type: 'dns', value: 'san-encode.example' }, { type: 'srv', value: '_xmpp.example.com' }, { type: 'directoryName', derHex: directoryNameDer }, ], }, }); const openSsl = await readCertificateSanWithOpenSsl(certificate.pem); expect(openSsl.accepted).toBe(true); // OpenSSL decodes the directoryName [4] SAN (full Name TLV wrapped) and the // SRV-ID otherName [0] (direct type-id/value fields). Assert the decoded // labels and values, not the separator formatting, which varies by version // (`SRVName:` vs `SRVName::`). const san = openSsl.subjectAltName ?? ''; expect(san).toContain('DirName'); expect(san).toContain('Diff Dir CA'); expect(san).toContain('SRVName'); expect(san).toContain('_xmpp.example.com'); }); it('OpenSSL parses a micro509 certificate with URI and directoryName AIA locations', async () => { const issuerNameDer = toHex(encodeName([{ type: 'commonName', value: 'AIA Issuer CA' }])); const { certificate } = await createSelfSignedCertificate({ subject: { commonName: 'aia-encode.example' }, extensions: { authorityInfoAccess: [ { method: 'ocsp', location: { type: 'uri', value: 'http://ocsp.example.test' } }, { method: 'caIssuers', location: { type: 'directoryName', derHex: issuerNameDer } }, ], }, }); const openSsl = await readCertificateAiaWithOpenSsl(certificate.pem); expect(openSsl.accepted).toBe(true); // OpenSSL decodes the URI OCSP responder and the directoryName caIssuers. const aia = openSsl.authorityInfoAccess ?? ''; expect(aia).toContain('http://ocsp.example.test'); expect(aia).toContain('CA Issuers'); expect(aia).toContain('DirName'); expect(aia).toContain('AIA Issuer CA'); }); it('OpenSSL accepts an OCSP response produced by micro509', async () => { const issuer = await createSelfSignedCertificate({ subject: { commonName: 'Reverse OCSP CA' }, extensions: { basicConstraints: { ca: true }, keyUsage: ['keyCertSign', 'cRLSign', 'digitalSignature'], }, }); const leafKeys = await generateKeyPair(); const leaf = await createCertificate({ issuer: { commonName: 'Reverse OCSP CA' }, subject: { commonName: 'reverse-ocsp.example' }, publicKey: leafKeys.publicKey, signerPrivateKey: issuer.keyPair.privateKey, issuerPublicKey: issuer.keyPair.publicKey, }); const material = await createOcspResponse({ signerPrivateKey: issuer.keyPair.privateKey, signerCertificate: issuer.certificate.pem, includedCertificates: [issuer.certificate.pem], responses: [ { certificate: leaf.pem, issuerCertificate: issuer.certificate.pem, certStatus: 'good', thisUpdate: new Date(), nextUpdate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), }, ], }); const openSsl = await validateMicro509OcspResponseWithOpenSsl({ issuerCertificatePem: issuer.certificate.pem, certificatePem: leaf.pem, responseDer: material.der, }); expect(openSsl.accepted).toBe(true); expect(openSsl.status).toBe('good'); }); it('matches OpenSSL DNS and IP identity verdicts', async () => { const dnsCertificate = await createSelfSignedCertificate({ subject: { commonName: 'ignored.example' }, extensions: { subjectAltNames: [ { type: 'dns', value: 'api.example.com' }, { type: 'dns', value: '*.wild.example.com' }, ], }, }); const parsedDns = unwrap(parseCertificatePem(dnsCertificate.certificate.pem)); for (const dnsCase of [ { value: 'api.example.com', expected: true }, { value: 'service.wild.example.com', expected: true }, { value: 'mismatch.example.com', expected: false }, ] as const) { const micro = matchServiceIdentity({ certificate: parsedDns, serviceIdentity: { type: 'dns', value: dnsCase.value }, }); const openSsl = await checkIdentityWithOpenSsl({ certificatePem: dnsCertificate.certificate.pem, kind: 'dns', value: dnsCase.value, }); expect(micro.ok).toBe(dnsCase.expected); expect(openSsl.matches).toBe(dnsCase.expected); expect(micro.ok).toBe(openSsl.matches); } const ipCertificate = await createSelfSignedCertificate({ subject: { commonName: 'ignored-ip.example' }, extensions: { subjectAltNames: [{ type: 'ip', value: '2001:db8::1' }], }, }); const parsedIp = unwrap(parseCertificatePem(ipCertificate.certificate.pem)); const ipMicro = matchServiceIdentity({ certificate: parsedIp, serviceIdentity: { type: 'ip', value: '2001:0db8:0:0:0:0:0:1' }, }); const ipOpenSsl = await checkIdentityWithOpenSsl({ certificatePem: ipCertificate.certificate.pem, kind: 'ip', value: '2001:0db8:0:0:0:0:0:1', }); expect(ipMicro.ok).toBe(true); expect(ipOpenSsl.matches).toBe(true); expect(ipMicro.ok).toBe(ipOpenSsl.matches); }); it('produces a PKCS#7 cert bag OpenSSL parses with canonical CertificateSet ordering', async () => { const a = await createSelfSignedCertificate({ subject: { commonName: 'Bag Cert A' } }); const b = await createSelfSignedCertificate({ subject: { commonName: 'Bag Cert B' } }); const bag = unwrap(createPkcs7CertBag([a.certificate.pem, b.certificate.pem])); const reversed = unwrap(createPkcs7CertBag([b.certificate.pem, a.certificate.pem])); expect(toHex(bag.der)).toBe(toHex(reversed.der)); const openssl = await readPkcs7CertBagWithOpenSsl(bag.der); expect(openssl.exitCode).toBe(0); expect(openssl.subjectCount).toBe(2); }); it('OpenSSL decrypts an encrypted PKCS#8 whose PBKDF2 omits the DEFAULT HMAC-SHA-1 prf', async () => { const keyPair = await generateKeyPair(); const encrypted = await exportEncryptedPkcs8Der(keyPair.privateKey, { password: 'pw', prf: 'HMAC-SHA-1', iterations: 2048, }); const openssl = await decryptPkcs8WithOpenSsl(encrypted, 'pw'); expect(openssl.exitCode).toBe(0); expect(openssl.decrypted).toBe(true); }); it('OpenSSL parses a PFX whose MacData omits the DEFAULT iteration count', async () => { const keyPair = await generateKeyPair(); const cert = await createSelfSignedCertificate({ subject: { commonName: 'Diff PFX Iter One' }, }); const pfx = unwrap( await createPfx({ certificates: [{ certificate: cert.certificate.pem }], privateKeys: [{ privateKey: keyPair.privateKey }], mac: { password: 'pw', iterations: 1 }, }), ); const openssl = await readPfxWithOpenSsl(pfx.der, 'pw'); expect(openssl.exitCode).toBe(0); }); });