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.
Hello,
according to the RFC 5652, when using SignedAttrs, the message digest should be calculated as
the complete DER encoding of the SignedAttrs value contained in the signedAttrs field
However, this is not happening right now as per code in SignedData.ts which uses BER encoding:
if (signerInfo.signedAttrs) {
if (signerInfo.signedAttrs.encodedValue.byteLength !== 0)
data = signerInfo.signedAttrs.encodedValue;
else {
data = signerInfo.signedAttrs.toSchema().toBER();
//#region Change type from "[0]" to "SET" accordingly to standard
const view = pvtsutils.BufferSourceConverter.toUint8Array(data);
view[0] = 0x31;
//#endregion
}
}
The main problem that I have is that when passing attributes into the SignedAndUnsignedAttributes, the message digest depends on the order I specify the attributes. I believe this should not be happening and the message digest should be the same, independent of the attributes order.
This causes problems when verifying the signature with Java Bouncy Castle library, which expects the DER (ordered) encoding of the signed attributes.
Examples
This attribute order does not validate
const signedAttrs = new SignedAndUnsignedAttributes({
type: 0,
attributes: [
new Attribute({
type: OID.ContentType,
values: [new asn1js.ObjectIdentifier({ value: OID.Data })],
}),
new Attribute({
type: OID.MessageDigest,
values: [new asn1js.OctetString({ valueHex: dataDigest })],
}),
new Attribute({
type: OID.SigningTime,
values: [new asn1js.UTCTime({ valueDate: new Date() })],
}),
],
});
Switching positions of SigningTime and MessageDigest produces a valid signature
const signedAttrs = new SignedAndUnsignedAttributes({
type: 0,
attributes: [
new Attribute({
type: OID.ContentType,
values: [new asn1js.ObjectIdentifier({ value: OID.Data })],
}),
new Attribute({
type: OID.SigningTime,
values: [new asn1js.UTCTime({ valueDate: new Date() })],
}),
new Attribute({
type: OID.MessageDigest,
values: [new asn1js.OctetString({ valueHex: dataDigest })],
}),
],
});
Hello, according to the RFC 5652, when using SignedAttrs, the message digest should be calculated as
However, this is not happening right now as per code in SignedData.ts which uses BER encoding:
The main problem that I have is that when passing attributes into the SignedAndUnsignedAttributes, the message digest depends on the order I specify the attributes. I believe this should not be happening and the message digest should be the same, independent of the attributes order.
This causes problems when verifying the signature with Java Bouncy Castle library, which expects the DER (ordered) encoding of the signed attributes.
Examples
This attribute order does not validate
Switching positions of SigningTime and MessageDigest produces a valid signature