Using CmsEnvelopedData with CmsSignedData to verify signed data

1.8k views Asked by At

I'm are receiving signed and encrypted content from a third party. I'm informed that the message structure is PKCS7 (1.2.840.113549.1.7.4 - SignedAndEnvelopedData).
I have successfully decrypted the message content using the following code:

var message = File.ReadAllBytes(@"C:\PKI\receivedMessage");

var cmsEnvelopedData = new CmsEnvelopedData(message);

var recipients = cmsEnvelopedData.GetRecipientInfos();

var cert = GetPfxFileCertFromDisk();
var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(TransformRSAPrivateKey(cert.PrivateKey));
var privateKey = privateKeyInfo.ToAsn1Object().GetDerEncoded(); 
var myPrivateKey = PrivateKeyFactory.CreateKey(privateKey);

var decryptedMessage = string.Empty;
foreach (RecipientInformation recipientInfo in recipients.GetRecipients())
{
    byte[] data = recipientInfo.GetContent(myPrivateKey);
    decryptedMessage = Encoding.ASCII.GetString(data);
}

However I did have to make a modification to the Bouncy Castle EnvelopedData class...

public EnvelopedData(
        Asn1Sequence seq)
{
    int index = 0;

    version = (DerInteger) seq[index++];

    object tmp = seq[index++];

    if (tmp is Asn1TaggedObject)
    {
        originatorInfo = OriginatorInfo.GetInstance((Asn1TaggedObject) tmp, false);
        tmp = seq[index++];
    }

    recipientInfos = Asn1Set.GetInstance(tmp);
    index++; // ADDED THIS LINE to Bouncy Castle implementation
    encryptedContentInfo = EncryptedContentInfo.GetInstance(seq[index++]);

    if (seq.Count > index)
    {
        unprotectedAttrs = Asn1Set.GetInstance((Asn1TaggedObject) seq[index], false);
    }
}

The structure of the message we are receiving does not appear to be CMSEvelopedData according to RFC 5652, hence adding the additional index++ to enable successful parsing.
I added the additional index++ to skip an item in the ASNSequence containing content marked as ASN.1 1.3.14.3.2.26 (SHA-1), however there is no actual hashed content present.
Of note the ASN1Sequence also contains an item containing Signer Information. I can parse it out to an instance of the SignerInformationStore class.

From here I'm not sure how I can verify the message signature? I have studied examples of using the CmsSignedData class, however I'm still confused about how to create a CmsSignedData instance and verify the message.

0

There are 0 answers