PeculiarVentures / PKI.js

PKI.js is a pure JavaScript library implementing the formats that are used in PKI applications (signing, encryption, certificate requests, OCSP and TSP requests/responses). It is built on WebCrypto (Web Cryptography API) and requires no plug-ins.
http://pkijs.org
Other
1.3k stars 204 forks source link

OCSPRequest - does not produce valid schema with optionalSignature #311

Closed dhensby closed 3 years ago

dhensby commented 3 years ago

According to the specification for OCSP Requests, the optionalSignature must be numbered [0]. However, when constructing an OCSP Request with an optionalSignature and encoding it, the encoded output is not valid as the optionalSignature is not correctly tagged.

The following code will fail:

const cert = getCert(certPem);
const issuerCert = getIssuer(issuerPem);

const ocspUrl = getOCSPUrl(cert);
const issuerNameHash = createHash('sha1').update(Buffer.from(cert.issuer.valueBeforeDecode)).digest();
const issuerKeyHash = getIssuerKeyHash(cert);
const serialNumber = getCertSerialNumber(cert);

const request = new pkijs.OCSPRequest();
request.tbsRequest.requestorName = new pkijs.GeneralName({
    type: 4, // directoryName
    value: cert.issuer,
});
request.tbsRequest.requestList = [
    new pkijs.Request({
        reqCert: new pkijs.CertID({
            hashAlgorithm: new pkijs.AlgorithmIdentifier({
                algorithmId: '1.3.14.3.2.26', // SHA-1
            }),
            issuerNameHash: new asn1js.OctetString({ valueHex: issuerNameHash }),
            issuerKeyHash: new asn1js.OctetString({ valueHex: issuerKeyHash }),
            serialNumber: new asn1js.Integer({ valueHex: serialNumber }),
        }),
    }),
];
request.tbsRequest.requestExtensions = [
    new pkijs.Extension({
        extnID: '1.3.6.1.5.5.7.48.1.2', // ocsp nonce
        extnValue: createHash('sha1').update(Date.now().toString()).digest(),
    }),
];
request.optionalSignature = new pkijs.Signature({
    certs: [issuerCert],
});

await request.sign(...);

// Let's encode and decode the request to see what happens - throws an error
const redecode = new pkijs.OCSPRequest({
    schema: asn1js.fromBER(request.toSchema().toBER(false)).result,
});

Error thrown: Error: Object's schema was not verified against input data for OCSPRequest