Skip to content

Include counter-signature hash algorithm into SignedData.digestAlgorithms  #955

Description

@bsanchezb

Hello,

RFC 5652 highly recommends to add used hash algorithms within the SignedData.digestAlgorithms field:

digestAlgorithms is a collection of message digest algorithm identifiers.
...
Implementations MAY fail to validate signatures that use a digest algorithm that is not included in this set.

and

The message digest algorithm SHOULD be among those listed in the digestAlgorithms field of the associated SignerData.

However, with BC I have a problem to fulfil this requirement when working with counter-signatures.

When I create a counter-signature with a hash algorithm different from the one used in the main signature, the produced CMSSignedData does not contain the new hash algorithm and I do not see a way to add it.

The code what I use to create a counter-signature is:

SignerInformationStore signerInformationStore = originalCMSSignedData.getSignerInfos();
List<SignerInformation> result = new LinkedList<>();
for (SignerInformation signerInformation : signerInformationStore) {
    CMSSignedDataGenerator cmsSignedDataGenerator = *build the generator*;
    SignerInformationStore counterSignatureSignerInfoStore = CMSUtils.generateCounterSigners(cmsSignedDataGenerator, signerInformation);
    result.add(SignerInformation.addCounterSigners(signerInformation, counterSignatureSignerInfoStore));
}
CMSSignedData updatedCMSSignedData = CMSSignedData.replaceSigners(originalCMSSignedData, new SignerInformationStore(result));

The resulting updatedCMSSignedData does not contain the hash algorithm used to create the counter-signature, which is stored within a SignerInformation object corresponding to the counter-signature.

The method CMSSignedData.replaceSigners(...) collects all digest algorithms from the SignerInformations, therefore it collects the algorithms in case of parallel signatures, however it does not take counter-signatures into account.
Would be nice to collect the algorithms from counter-signatures as well, especially that the code could be adapted easely:

Iterator it = signerInformationStore.getSigners().iterator();
while (it.hasNext()) {
    SignerInformation signer = (SignerInformation)it.next();            
    digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID()));
    SignerInformationStore counterSignaturesStore = signerInformation.getCounterSignatures();
    Iterator<SignerInformation> counterSignatureIt = counterSignatureStore.iterator();
    while (counterSignatureIt.hasNext()) {
        SignerInformation counterSigner = counterSignatureIt.next();
        digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(counterSigner.getDigestAlgorithmID()));
    }
    vec.add(signer.toASN1Structure());        
}

Or, as an alternative, a new method, similar to CMSSignedData.replaceCertificatesAndCRLs(...) could be added, allowed replacing the digestAlgorithms field value.

If another solution is possible, I would appreciate any help as well.

Thank you.

Best regards,
Aleksandr.

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