Skip to content

Commit

Permalink
Merge branch 'nit/split-up-signer-information-doVerify' of https://gi…
Browse files Browse the repository at this point in the history
…thub.com/ties/bc-java into ties-nit/split-up-signer-information-doVerify
  • Loading branch information
mwcw committed Oct 6, 2021
2 parents 2f82dfa + b3ead84 commit 8733846
Showing 1 changed file with 128 additions and 102 deletions.
230 changes: 128 additions & 102 deletions pkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
Original file line number Diff line number Diff line change
Expand Up @@ -436,153 +436,179 @@ else if (signedAttributeSet != null)
}

// RFC 3852 11.1 Check the content-type attribute is correct
{
ASN1Primitive validContentType = getSingleValuedSignedAttribute(
CMSAttributes.contentType, "content-type");
if (validContentType == null)
{
if (!isCounterSignature && signedAttributeSet != null)
{
throw new CMSException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
}
}
else
{
if (isCounterSignature)
{
throw new CMSException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
}
doVerify_checkContentTypeAttributeValue();

if (!(validContentType instanceof ASN1ObjectIdentifier))
{
throw new CMSException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
}
AttributeTable signedAttrTable = this.getSignedAttributes();

ASN1ObjectIdentifier signedContentType = (ASN1ObjectIdentifier)validContentType;
// RFC 6211 Validate Algorithm Identifier protection attribute if present
doVerify_validateAlgorithmIdentifierProtectionAttribute(signedAttrTable);

if (!signedContentType.equals(contentType))
{
throw new CMSException("content-type attribute value does not match eContentType");
}
}
}
// RFC 3852 11.2 Check the message-digest attribute is correct
doVerify_checkMessageDigestAttribute();

AttributeTable signedAttrTable = this.getSignedAttributes();
// RFC 3852 11.4 Validate countersignature attribute(s)
doVerify_validateCounterSignatureAttribute(signedAttrTable);

// RFC 6211 Validate Algorithm Identifier protection attribute if present
try
{
AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
if (unsignedAttrTable != null && unsignedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect).size() > 0)
{
throw new CMSException("A cmsAlgorithmProtect attribute MUST be a signed attribute");
}
if (signedAttrTable != null)
if (signedAttributeSet == null && resultDigest != null)
{
ASN1EncodableVector protectionAttributes = signedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect);
if (protectionAttributes.size() > 1)
if (contentVerifier instanceof RawContentVerifier)
{
throw new CMSException("Only one instance of a cmsAlgorithmProtect attribute can be present");
}
RawContentVerifier rawVerifier = (RawContentVerifier)contentVerifier;

if (protectionAttributes.size() > 0)
{
Attribute attr = Attribute.getInstance(protectionAttributes.get(0));
if (attr.getAttrValues().size() != 1)
if (encName.equals("RSA"))
{
throw new CMSException("A cmsAlgorithmProtect attribute MUST contain exactly one value");
}

CMSAlgorithmProtection algorithmProtection = CMSAlgorithmProtection.getInstance(attr.getAttributeValues()[0]);
DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest);

if (!CMSUtils.isEquivalent(algorithmProtection.getDigestAlgorithm(), info.getDigestAlgorithm()))
{
throw new CMSException("CMS Algorithm Identifier Protection check failed for digestAlgorithm");
return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature());
}

if (!CMSUtils.isEquivalent(algorithmProtection.getSignatureAlgorithm(), info.getDigestEncryptionAlgorithm()))
{
throw new CMSException("CMS Algorithm Identifier Protection check failed for signatureAlgorithm");
}
return rawVerifier.verify(resultDigest, this.getSignature());
}
}

return contentVerifier.verify(this.getSignature());
}
catch (IOException e)
{
throw new CMSException("can't process mime object to create signature.", e);
}
}

// RFC 3852 11.2 Check the message-digest attribute is correct
/**
* RFC 3852 11.1 Check the content-type attribute is correct
* @throws CMSException when content-type was invalid.
*/
private void doVerify_checkContentTypeAttributeValue() throws CMSException {
ASN1Primitive validContentType = getSingleValuedSignedAttribute(
CMSAttributes.contentType, "content-type");
if (validContentType == null)
{
ASN1Primitive validMessageDigest = getSingleValuedSignedAttribute(
CMSAttributes.messageDigest, "message-digest");
if (validMessageDigest == null)
if (!isCounterSignature && signedAttributeSet != null)
{
if (signedAttributeSet != null)
{
throw new CMSException("the message-digest signed attribute type MUST be present when there are any signed attributes present");
}
throw new CMSException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
}
else
}
else
{
if (isCounterSignature)
{
if (!(validMessageDigest instanceof ASN1OctetString))
{
throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
}
throw new CMSException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
}

if (!(validContentType instanceof ASN1ObjectIdentifier))
{
throw new CMSException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
}

ASN1OctetString signedMessageDigest = (ASN1OctetString)validMessageDigest;
ASN1ObjectIdentifier signedContentType = (ASN1ObjectIdentifier)validContentType;

if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets()))
{
throw new CMSSignerDigestMismatchException("message-digest attribute value does not match calculated value");
}
if (!signedContentType.equals(contentType))
{
throw new CMSException("content-type attribute value does not match eContentType");
}
}
}

// RFC 3852 11.4 Validate countersignature attribute(s)
/**
* RFC 3852 11.2 Check the message-digest attribute is correct
* @throws CMSException when message-digest attribute was rejected
*/
private void doVerify_checkMessageDigestAttribute() throws CMSException {
ASN1Primitive validMessageDigest = getSingleValuedSignedAttribute(
CMSAttributes.messageDigest, "message-digest");
if (validMessageDigest == null)
{
if (signedAttrTable != null
&& signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0)
if (signedAttributeSet != null)
{
throw new CMSException("A countersignature attribute MUST NOT be a signed attribute");
throw new CMSException("the message-digest signed attribute type MUST be present when there are any signed attributes present");
}

AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
if (unsignedAttrTable != null)
}
else
{
if (!(validMessageDigest instanceof ASN1OctetString))
{
ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature);
for (int i = 0; i < csAttrs.size(); ++i)
{
Attribute csAttr = Attribute.getInstance(csAttrs.get(i));
if (csAttr.getAttrValues().size() < 1)
{
throw new CMSException("A countersignature attribute MUST contain at least one AttributeValue");
}
throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
}

// Note: We don't recursively validate the countersignature value
}
ASN1OctetString signedMessageDigest = (ASN1OctetString)validMessageDigest;

if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets()))
{
throw new CMSSignerDigestMismatchException("message-digest attribute value does not match calculated value");
}
}
}

try
/**
* RFC 6211 Validate Algorithm Identifier protection attribute if present
* @param signedAttrTable signed attributes
* @throws CMSException when cmsAlgorihmProtect attribute was rejected
*/
private void doVerify_validateAlgorithmIdentifierProtectionAttribute(AttributeTable signedAttrTable) throws CMSException {
AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
if (unsignedAttrTable != null && unsignedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect).size() > 0)
{
if (signedAttributeSet == null && resultDigest != null)
throw new CMSException("A cmsAlgorithmProtect attribute MUST be a signed attribute");
}
if (signedAttrTable != null)
{
ASN1EncodableVector protectionAttributes = signedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect);
if (protectionAttributes.size() > 1)
{
if (contentVerifier instanceof RawContentVerifier)
throw new CMSException("Only one instance of a cmsAlgorithmProtect attribute can be present");
}

if (protectionAttributes.size() > 0)
{
Attribute attr = Attribute.getInstance(protectionAttributes.get(0));
if (attr.getAttrValues().size() != 1)
{
RawContentVerifier rawVerifier = (RawContentVerifier)contentVerifier;
throw new CMSException("A cmsAlgorithmProtect attribute MUST contain exactly one value");
}

if (encName.equals("RSA"))
{
DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest);
CMSAlgorithmProtection algorithmProtection = CMSAlgorithmProtection.getInstance(attr.getAttributeValues()[0]);

return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature());
}
if (!CMSUtils.isEquivalent(algorithmProtection.getDigestAlgorithm(), info.getDigestAlgorithm()))
{
throw new CMSException("CMS Algorithm Identifier Protection check failed for digestAlgorithm");
}

return rawVerifier.verify(resultDigest, this.getSignature());
if (!CMSUtils.isEquivalent(algorithmProtection.getSignatureAlgorithm(), info.getDigestEncryptionAlgorithm()))
{
throw new CMSException("CMS Algorithm Identifier Protection check failed for signatureAlgorithm");
}
}
}
}

return contentVerifier.verify(this.getSignature());
/**
* RFC 3852 11.4 Validate countersignature attribute(s)
* @param signedAttrTable signed attributes
* @throws CMSException when countersignature attribute was rejected
*/
private void doVerify_validateCounterSignatureAttribute(AttributeTable signedAttrTable) throws CMSException {
if (signedAttrTable != null
&& signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0)
{
throw new CMSException("A countersignature attribute MUST NOT be a signed attribute");
}
catch (IOException e)

AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
if (unsignedAttrTable != null)
{
throw new CMSException("can't process mime object to create signature.", e);
ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature);
for (int i = 0; i < csAttrs.size(); ++i)
{
Attribute csAttr = Attribute.getInstance(csAttrs.get(i));
if (csAttr.getAttrValues().size() < 1)
{
throw new CMSException("A countersignature attribute MUST contain at least one AttributeValue");
}

// Note: We don't recursively validate the countersignature value
}
}
}

Expand Down

0 comments on commit 8733846

Please sign in to comment.