Skip to content

CMS signature: signedAttrs should use DER encoding instead of BER #402

Open
@mholy-arbes

Description

@mholy-arbes

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 })],
        }),
    ],
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions