Open dhensby opened 3 years ago
Here's an example of creating a OCSPRequest and then decoding it and where the problem is:
const { createHash }= require('crypto');
const pkijs = require('pkijs');
const asn1js = require('asn1js');
function pemToCert(pem) {
const certData = pem
.replace(/-{5}([^-]+)-{5}/g, '')
.replace(/\n|\r/g, '');
const certBuffer = Buffer.from(certData, 'base64');
return new pkijs.Certificate({
schema: asn1js.fromBER(new Uint8Array(certBuffer).buffer).result,
});
}
function getCertSerialNumber(certificate) {
return Buffer.from(certificate.serialNumber.valueBlock.valueHex);
}
function getIssuerKeyHash(certificate) {
const aki = certificate.extensions.find(({ extnID }) => extnID === '2.5.29.35');
return Buffer.from(aki.parsedValue.keyIdentifier.valueBlock.valueHex);
}
(async () => {
const cert = pemToCert(certPem);
const issuerCert = pemToCert(issuerPem);
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.optionalSignature = new pkijs.Signature({
certs: [issuerCert],
});
await request.sign(..., 'SHA-512');
// logs 1.2.840.113549.1.1.13 - the correct OID for SHA-512
console.log(request.optionalSignature.signatureAlgorithm.algorithmId.toString())
const ocspRequest = Buffer.from(request.toSchema(true).toBER(false));
const decoded = new pkijs.OCSPRequest({ schema: asn1js.fromBER(new Uint8Array(ocspRequest).buffer).result });
// logs 1.2.840.113549.1.1.5 - the OID for sha1 - the alg of the issuer cert signature
console.log(decoded.optionalSignature.signatureAlgorithm.algorithmId.toString());
})().catch(console.error);
I've had a good dig into this and can't see how to set the naming such that the signatureAlgorithm
isn't overridden by the Certs or to have it stored against a different entry (like ocspRequest.signatureAlg
).
@dhensby Could you share ASN.1 encoded OSCP request?
Hi @microshine - the encoded request doesn't really matter because it's about the encoding process and the way that the objects are stored against a "root" schema object with shared names.
Here is a request, though:
3082046c308193a14aa4483046310b300906035504061302555331133011060355040a130a476f6f676c6520496e633122302006035504031319476f6f676c6520496e7465726e657420417574686f72697479304530433041300706052b0e03021a0414d43b6713ab1a8679f0b70e169e9df889ed387a4b0414bfc030ebf543113e67ba9e91fb
fc6adae36b1224020a43c7e38e0000000061dea08203d2308203ce300b06092a864886f70d01010d038201010083767e1458a3545d564099375318cc443299db93d032f5c039c96f0bce358cbd5dc7463e676a00f982d5e21281027646512b39b181d1df82f4556a3305e3b781b1d3fc1904391d0178da0b8f74e9bf8ff43bb006098797f6cd9d
5a934fe6d5988e13671a12c2a4dcf5a02d03cc25cc9beb330edbe4ec597bf33750003e9e24143b7e82d242e059ca6e1e3e32027d0028eb45997b00ce724e9019d62b17bc5cb8a6bc89e637b0fd9ce815dd90a8d86164c6774304abb8208f5607b714468cacdd2f28060914cee3b9cdb53d9bf149300ddbcfe7dd1f8e2088e9f1d9266448ae6e55
9e13c85d41090d5158fc503e5b0fbb1571527a21cf5976df88fd5247591d0fa08202b8308202b4308202b030820219a00302010202030b6771300d06092a864886f70d0101050500304e310b30090603550406130255533110300e060355040a130745717569666178312d302b060355040b132445717569666178205365637572652043657274
6966696361746520417574686f72697479301e170d3039303630383230343332375a170d3133303630373139343332375a3046310b300906035504061302555331133011060355040a130a476f6f676c6520496e633122302006035504031319476f6f676c6520496e7465726e657420417574686f7269747930819f300d06092a864886f70d01
0101050003818d0030818902818100c9edb7a48b9c57e7843e407d84f48fd171635399e7797414af44993320928d7be5280cbaad6c497e835f34594e0a7a30cdd0d7c45745edd5aad67326cead3213b8d70f1d3bdfdddc0836a86f51449bcad6205273b72687356adba9e5d459a52bfc671939fa9318186cdedd258a0e331447c2ef015079e4fd
69d1a7c0ace2576f0203010001a381a33081a0300e0603551d0f0101ff040403020106301d0603551d0e04160414bfc030ebf543113e67ba9e91fbfc6adae36b1224301f0603551d2304183016801448e668f92bd2b295d747d82320104f3398909fd430120603551d130101ff040830060101ff020100303a0603551d1f04333031302fa02da0
2b8629687474703a2f2f63726c2e67656f74727573742e636f6d2f63726c732f73656375726563612e63726c300d06092a864886f70d010105050003818100b88a23c64896b1117c60775e059aaba1c6fa821c1807c4eb81b0a866eb49a8e90cd329adf5ef244cfde44bca7f5e63ab9927cb9f36212cb9106067cdd2b4f0f0ab71e58b5a892711
84aa8ebf99f09d09210a52199a5a09d290b7fa0cf87e78a2b085af5c4c99d95c5529f9a551422e3acb388c783bcbf8fb9587bcbc90f95032
@dhensby Have you seen @peculiar/asn1-schema
and @peculiar/asn1-ocsp
modules? These modules declare ASN.1 schemas only
I've created a simple example of parsing the OCSP request you shared.
https://codesandbox.io/s/parse-ocsp-request-53yr2
Does it return correct data?
As I can remember the problem with naming collision is in ASN1js module. It must use unique names for schema entries. Cause it returns all named schemas in a single object and doesn't keep the data structure.
It shows different mechanisms for certificate.signatureAlgorithm
and optionalSignature.signatureAlgorithm
Here is the result of Object.keys
for asn1.result
from Signature
Signature: [
'blockLength',
'error',
'warnings',
'valueBeforeDecode',
'idBlock',
'lenBlock',
'valueBlock',
'signatureAlgorithm',
'signature',
'tbsCertificate',
'tbsCertificate.version',
'tbsCertificate.serialNumber',
'tbsCertificate.signature',
'',
'tbsCertificate.issuer',
'tbsCertificate.validity',
'tbsCertificate.notBefore',
'tbsCertificate.notAfter',
'tbsCertificate.subject',
'tbsCertificate.subjectPublicKeyInfo',
'tbsCertificate.extensions',
'signatureValue',
'certs'
]
You can see that Signatute
fields are mixed with the fields of the Certificate
. And each Certificate
field will be contain data from the last certificate in list
Thanks for the replies @microshine.
Have you seen @peculiar/asn1-schema and @peculiar/asn1-ocsp modules? These modules declare ASN.1 schemas only
I haven't see these, I'll take a look.
As I can remember the problem with naming collision is in ASN1js module. It must use unique names for schema entries. Cause it returns all named schemas in a single object and doesn't keep the data structure.
You can see that
Signatute
fields are mixed with the fields of theCertificate
. And eachCertificate
field will be contain data from the last certificate in list
Yes, this is precisely the problem. The names that are being passed to the asn1js module aren't taking account of "context" (ie: that they are nested). There appears to be a local
option that can be passed to Repeated
schemas, which I've tried to use for the certs
but this doesn't seem to entirely solve the problem.
It looks to be like it would be best if the OCSPRequest.fromSchema
method could pass down the names of the tbsCertificate signatures so that the naming collision is avoided but I could quite figure out how to do it.
It shows different mechanisms for
certificate.signatureAlgorithm
andoptionalSignature.signatureAlgorithm
That looks correct; I'll do some investigating.
In summary, does this mean that essentially it's a known-issue either with this lib or asn1js and there's not a lot to be done about it?
I'll take a look at this problem and try to fix it in PKIjs. But ideally, we need to update ASN1js API which requires update PKIjs too (it's a lot of changes). Right now I'm busy on another project and going to do these updates after that.
@peculiar/asn1-schema
is based on ASN1js library and solves that problem
@dhensby If you do worry about same naming then better way is to change default naming in schema
function:
static schema(parameters = {})
{
/**
* @type {Object}
* @property {string} [blockName]
* @property {string} [tbsRequest]
* @property {string} [optionalSignature]
*/
const names = getParametersValue(parameters, "names", {});
return (new asn1js.Sequence({
name: names.blockName || "OCSPRequest",
value: [
TBSRequest.schema(names.tbsRequest || {
names: {
blockName: "tbsRequest"
}
}),
new asn1js.Constructed({
optional: true,
idBlock: {
tagClass: 3, // CONTEXT-SPECIFIC
tagNumber: 0 // [0]
},
value: [
Signature.schema(names.optionalSignature || {
names: {
blockName: "optionalSignature",
signatureAlgorithm: {
names: {
blockName: "optionalSignatureAlgorithm"
}
},
}
})
]
})
]
}));
}
Each naming could be configured via a parameters to schema
function.
Also this line is unnecessary - the optional
flag works during schema parsing only.
@YuryStrozhevsky - I don't think the naming works deep enough because we want to change the name of optionalSignature
on the certs
that are extracted inside the Signature
.
Also, becuase we're using fromSchema
which then just loads a Signature
, I think it's the Signature.schema
that needs changing?
@dhensby It do works "deep enough" :) Just check the schema
functions for all related subelements.
Also, becuase we're using fromSchema which then just loads a Signature, I think it's the Signature.schema that needs changing?
No, only a parameter to the function call should be changed.
static schema(parameters = {})
{
/**
* @type {Object}
* @property {string} [blockName]
* @property {string} [tbsRequest]
* @property {string} [optionalSignature]
*/
const names = getParametersValue(parameters, "names", {});
return (new asn1js.Sequence({
name: names.blockName || "OCSPRequest",
value: [
TBSRequest.schema(names.tbsRequest || {
names: {
blockName: "tbsRequest"
}
}),
new asn1js.Constructed({
optional: true,
idBlock: {
tagClass: 3, // CONTEXT-SPECIFIC
tagNumber: 0 // [0]
},
value: [
Signature.schema(names.optionalSignature || {
names: {
blockName: "optionalSignature",
signatureAlgorithm: {
names: {
blockName: "optionalSignatureAlgorithm"
}
},
certs: {
signatureAlgorithm: {
names: {
blockName: "certificateOptionalSignatureAlgorithm"
}
},
}
}
})
]
})
]
}));
}
@dhensby In fact you do not need to change PKIjs for this. All you need is to make you own class which would be a "successor" for OCSPRequest
then make you own fromSchema
function in the class and the just call schema
with necessary parameters. So, all other functions of the new class would works same with OCSPRequest
, but schema parsing would satisfy your specific needs.
@YuryStrozhevsky my specific needs are to parse standards compliant OCSP requests, which I'd suggest is what the library is intended for. I'm happy to implement a custom class locally that works, but I've opened this issue to highlight that the current implementation doesn't work correctly.
Thanks for the example code, I'll give that a run and see if it makes a difference.
Also, I think that on inspection the problem isn't really with the OCSPRequest implementation (though it may well be "fixable" there) but with the fact that there is a naming collision with Certificate.signatureAlgorithm
and Signature.signatureAlgorithm
. There is also the possibility that the array of Certificates in OCSPRequest will cause this Certificate naming collision to be a problem as well if more than 1 certificate is supplied to the array.
@YuryStrozhevsky - I've tested the change locally with your suggestion from https://github.com/PeculiarVentures/PKI.js/issues/313#issuecomment-827494462 and it does not make any difference
@dhensby I am not at work at the moment. As soon as I will I promise to test it myself. In any case I do suggest you to inspect “schema” functions deeper - it do satisfy all you possible needs. As for “current implementation doesn’t work correctly”: I don’t see any errors in your findings. All you described is that names overrides. Please specify where exactly you think PKIJS works incorrectly.
I spent about 4 hours yesterday stepping through the parsing in a debugger, so I've looked pretty deeply into how this is working and I'm not completely able to follow it all the way down and not to the point of being able to fix the problem. It looks like @microshine understands that there is indeed some naming collision issues going on, so maybe he knows best how to resolve it.
The high level problem is this: I parse a valid (accepted by the VA server) OCSP Request, this request has an optionalSignature
which has signatureAlgorithm
of sha512WithRsaEncryption. When the parsing of the request is finished by the library the signature algorithm is reported as sha256WithRsaEncryption. When I step through with the debugger I can see up to this line https://github.com/PeculiarVentures/PKI.js/blob/master/src/OCSPRequest.js#L160 the algorithmIdentifier is correctly extracted - ie: asn1.result.optionalSignature.signatureAlgorithm
is correct. However, once it is processed by Signature.fromSchema
the asn1.result.optionalSignature.signatureAlgorithm
has been overwritten by the algorithmIdentifier that was extracted from the last Certificate
entry in the certs
array that forms part of the optionalSignature
. Therefore when the OCSPRequest is reencoded to asn1 the optionalSignature.signatureAlgorithm
is erroneously declared as sha256WithRsaEncryption.
I think the root cause of the problem is that there is a naming collision with signatureAlgorithm
in both OCSPRequest
and Certificate
and that this isn't name-spaced in any way to prevent this from happening. The fact that there is also a collision with Certificate and itself meaning an array of certificates will continuously override the value of the previous one. See https://github.com/PeculiarVentures/PKI.js/blob/v2.1.95/src/Signature.js#L122-L125
@dhensby OK I have tested it. Code should be like this ![Uploading 480E407C-46AA-444F-B722-8110F469D7E9.jpeg…]()
static schema(parameters = {}) {
/**
* @type {Object}
* @property {string} [blockName]
* @property {string} [tbsRequest]
* @property {string} [optionalSignature]
*/
const names = getParametersValue(parameters, "names", {});
return new asn1js.Sequence({
name: names.blockName || "OCSPRequest",
value: [TBSRequest.schema(names.tbsRequest || {
names: {
blockName: "tbsRequest"
}
}), new asn1js.Constructed({
optional: true,
idBlock: {
tagClass: 3,
// CONTEXT-SPECIFIC
tagNumber: 0 // [0]
},
value: [Signature.schema(names.optionalSignature || {
names: {
blockName: "optionalSignature",
certs: {
names: {
signatureAlgorithm: {
names: {
blockName: 'otpionalCertSignAlgorithm',
}
}
}
}
}
})]
})]
});
}
Thanks for that. Using your code:
static schema(parameters = {}) {
/**
* @type {Object}
* @property {string} [blockName]
* @property {string} [tbsRequest]
* @property {string} [optionalSignature]
*/
const names = getParametersValue(parameters, "names", {});
return new asn1js.Sequence({
name: names.blockName || "OCSPRequest",
value: [TBSRequest.schema(names.tbsRequest || {
names: {
blockName: "tbsRequest"
}
}), new asn1js.Constructed({
optional: true,
idBlock: {
tagClass: 3,
// CONTEXT-SPECIFIC
tagNumber: 0 // [0]
},
value: [Signature.schema(names.optionalSignature || {
names: {
blockName: "optionalSignature",
certs: {
names: {
signatureAlgorithm: {
names: {
blockName: 'otpionalCertSignAlgorithm',
}
}
}
}
}
})]
})]
});
}
The encoded data still reports the signature algorithm as 1.2.840.113549.1.1.11
(sha256WithRSAEncryption) and not 1.2.840.113549.1.1.13
(sha512WithRSAEncryption). So it does not appear to resolve the problem.
@dhensby I don’t have any more time today for you and again suggest you to inspect how pkijs names any objects inside schema static functions. Will continue tomorrow.
I have a slight feeling that the solution is to add local: true
to here https://github.com/PeculiarVentures/PKI.js/blob/v2.1.95/src/Signature.js#L122-L125
But that causes quite a large change to the parsing behaviour and something I don't have the knowledge or time to fix throughout the library.
@dhensby No, all this not a big problem at all. But yes, it was a mistake, but a mistake not in OCSPRequest
class but in Signature
. So, here is the correct code for Signature.fromSchema
function:
fromSchema(schema)
{
//region Clear input data first
clearProps(schema, [
"signatureAlgorithm",
"signature",
"certs"
]);
//endregion
//region Check the schema is valid
const asn1 = asn1js.compareSchema(schema,
schema,
Signature.schema({
names: {
signatureAlgorithm: {
names: {
blockName: "signatureAlgorithm"
}
},
signature: "signature",
certs: {
names: {
signatureAlgorithm: {
names: {
blockName: "certSignatureAlgorithm"
}
}
}
}
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for Signature");
//endregion
//region Get internal properties from parsed schema
this.signatureAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.signatureAlgorithm });
this.signature = asn1.result.signature;
if("certs" in asn1.result)
this.certs = Array.from(asn1.result.certs, element => new Certificate({ schema: element }));
//endregion
}
As you can see all the changes are about simple changes in schema naming.
Thank you, it is really hard to find such errors. And the error could have a big "consiquences".
@dhensby Please take a look at this example
import { X509CertificateGenerator, Name as X509Name } from "@peculiar/x509";
import { Certificate, GeneralName, Name } from "@peculiar/asn1-x509";
import { sha1, sha256WithRSAEncryption } from "@peculiar/asn1-rsa";
import { Crypto } from "@peculiar/webcrypto";
import { AsnConvert, OctetString } from "@peculiar/asn1-schema";
import { CertID, OCSPRequest, Request, Signature, TBSRequest } from "@peculiar/asn1-ocsp";
import { Convert } from "pvtsutils";
const crypto = new Crypto();
async function main() {
const year = 31104e6;
const alg = {
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1])
};
// Create CA cert
const caKeys = await crypto.subtle.generateKey(alg, false, [
"sign",
"verify"
]);
const caCert = await X509CertificateGenerator.createSelfSigned(
{
name: "CN=Test Root CA",
keys: caKeys,
notBefore: new Date(),
notAfter: new Date(Date.now() + (2 * year)), // + 2y
serialNumber: "01",
signingAlgorithm: alg
},
crypto
);
console.log("CA certificate created");
// Create LEaf cert
const leafKeys = await crypto.subtle.generateKey(alg, false, [
"sign",
"verify"
]);
const leafCert = await X509CertificateGenerator.create(
{
subject: "CN=Test cert",
issuer: caCert.subject,
signingKey: caKeys.privateKey,
publicKey: leafKeys.publicKey,
notBefore: new Date(),
notAfter: new Date(Date.now() + year), // + 1y
serialNumber: "02",
signingAlgorithm: alg
},
crypto
);
console.log("Leaf certificate created");
const issuerNameHash = await crypto.subtle.digest("SHA-1", new X509Name(leafCert.issuer).toArrayBuffer());
const issuerKeyHash = await leafCert.publicKey.getThumbprint("SHA-1", crypto);
// Create OCSP request
const tbsRequest = new TBSRequest({
requestorName: new GeneralName({
directoryName: AsnConvert.parse(new X509Name(leafCert.subject).toArrayBuffer(), Name),
}),
requestList: [
new Request({
reqCert: new CertID({
hashAlgorithm: sha1,
issuerNameHash: new OctetString(issuerNameHash),
issuerKeyHash: new OctetString(issuerKeyHash),
serialNumber: Convert.FromHex(leafCert.serialNumber),
}),
}),
],
});
const signature = await crypto.subtle.sign(alg, leafKeys.privateKey, AsnConvert.serialize(tbsRequest));
const ocspRequest = new OCSPRequest({
tbsRequest,
optionalSignature: new Signature({
certs: [AsnConvert.parse(leafCert.rawData, Certificate)],
signatureAlgorithm: sha256WithRSAEncryption,
signature,
}),
});
const ocspRequestRaw = AsnConvert.serialize(ocspRequest);
console.log("OCSP request:");
console.log(Convert.ToHex(ocspRequestRaw));
}
main().catch((e) => console.error(e));
CA certificate created
Leaf certificate created
OCSP request:
3082042c305aa118a41630143112301006035504031309546573742063657274303e303c303a300906052b0e03021a050004148f560cabb8fd639be521e57651e35b17258e07d4041427efa936161ed849527c3e0c47f085ca57ef1476020102a08203cc308203c8300d06092a864886f70d0101100500038201010079542da667db1af29aaa071d971ca39496502d8f262679074341c476cc718bfe6602a47cec39529e4c24ba5240bcfe773cc3f1c20d7a58c3f6fd5deb49d65df6b8faf2301fb3aa97d9f61bb5a7c4a2046ab59e3d8bc913d9be179ec2dfa493b43758a6508ae7407c4cb99e5132269bed8df0e7d79bf661ff24a8927a176daa6a7718b250826e0696b1dbad047f377de945625103e900dbe39172399a785f23625b485c08de56156cef790716cd604c5edb3658abc0401a977329f5035a3a90442e22ee717d3a9f1221683dd7ff3d3374a45c8a7fd03eb690c04f027d2b593a4b00f4ad038426b1e898bdb0e88330c7d0ad231e9ee2e589856bf915755fe4f640a08202b0308202ac308202a830820190a003020102020102300d06092a864886f70d01010b05003017311530130603550403130c5465737420526f6f74204341301e170d3231303432373133323435395a170d3232303432323133323435395a3014311230100603550403130954657374206365727430820122300d06092a864886f70d01010105000382010f003082010a02820101009ac77db2ee36cdca5ed2b7044d0d5726e59f774e32a2eec13eed6805ae311b4cc9b7cbece9c938b767bec4ce1f3f56b2fe4613172e4b35e109ae23a7b1a6a3d4b70a236eba506378b6832acf96446316ed838a1f0f985fac6bfe60b4966906e604b93f9412bc4b670ff3726370a8ae7e3967e8c9c9dc7cf230bd7900c4800db7ce65be46acb603f07bc0de2f1ba4ec3537e50f5fc07259663ffe9f1132bb7da060de197a5b524ed0ddd16e2a075d830a68c3ce3eb9720f6259aead640ea9b42272f88873368441a945a7f9b6363c92a73251da5a100e3ea9bf276f22cae76e6070fc15f52360e2166b8770e00c8caa4ec15150736027f5f39dc650488b42e14d0203010001a3023000300d06092a864886f70d01010b05000382010100b7439b6dc23422635502a3442d40e170fe3bf5ffd7e503d2d9fa7f4221cc0a01b5b83e5e9097d04a01b43dc1116e8fc51e955a8e32385f992f16e71cb7c490387e27384c28688c054a22b33a2c0ac4c0fa205c82ad183fe05c9fcbe99f41b3df5152d0ffe2ceec2f972001bc9c28af4a483934562e371d3a04ee87bbd1bf648d0b5a99081caa4b93f38fa4f2f355b605783b35e354ce6993f623ed2c67efc9f5baf3513340b19445d266016c734f2f186ff177726d9e2b9186cd2abe3804a419c6278f220b7c3461f15bcb0b657c0d41dd41a1c24004cb2e6442d1305a7f3c9388e873da0bd93d1f260663eed3c2eb52e13da5a46cc0c3404645f67173e2aa7f
@microshine I've been looking at those other libraries and they do appear to be much more reliable and do decode and encode OSCPRequests successfully, so I am building out a proof of concept with those; thanks for the proof-of-concept code :)
The only small part that is a bit more work is that the built-in extension parsing has not been implemented.
@peculiar/x509
does it. It also allows registering known extensions in runtime.
By default, it implements these extensions
Here is one more example of @peculiar/x509
usage
https://codesandbox.io/s/generate-cert-fjwfh?file=/src/main.js
As you can see each extension has got parsed values
Interesting - is there any docs on how to register the extensions at runtime? It doesn't appear to be doing it for AsnConvert.parse(certBuffer, Certificate);
As part of the OCSPRequest specification , OCSP requests can be signed by the private key of the certificate making the OCSP Request. This forms the
optionalSignature
part of the Request.The
optionalSignature
is formed of a signature algorithm, the signature itself and then an optional sequence of 1 or more certificates (usually the issuing certificate, but it can be a chain of certs).When decoding an
OCSPRequest
, the current implementation will erroneously decode the signing algorithm used.I believe this is because of a naming collision for
signatureAlgorithm
, which is used both myoptionalSignature
and the nestedCertificate
that forms part ofoptionalSignature
.Given that there can be multiple certificates in the sequence, it also appears that the previous certificate's
signatureAlgorithm
is overridden by that of the next.So there appear to be two problems (though I have not verified the 2nd):
signatureAlgorithm
from the sequence of certificates overwrites that of theoptionalSignature
signatureAlgorithm