public MimeEntity DecryptEntity(byte[] encryptedBytes, X509Certificate2 decryptingCertificate)
{
try
{
if (decryptingCertificate == null)
{
throw new EncryptionException(EncryptionError.NoCertificates);
}
// TODO: introduce buffering if you are using large files
// CMSEnvelopeData is a PKCS# structure rfc4134
var envelopedData = new CmsEnvelopedData(encryptedBytes);
var envData = EnvelopedData.GetInstance(envelopedData.ContentInfo.Content);
using (var session = GetSession())
{
if (session == null)
{
return(null);
}
foreach (Asn1Sequence asn1Set in envData.RecipientInfos)
{
var recip = RecipientInfo.GetInstance(asn1Set);
var keyTransRecipientInfo = KeyTransRecipientInfo.GetInstance(recip.Info);
var sessionKey = Pkcs11Util.Decrypt(session, keyTransRecipientInfo, decryptingCertificate);
#if DEBUG
Console.WriteLine(Asn1Dump.DumpAsString(envData));
#endif
if (sessionKey == null)
{
continue;
}
var recipientId = new RecipientID();
var issuerAndSerialNumber = (IssuerAndSerialNumber)keyTransRecipientInfo.RecipientIdentifier.ID;
recipientId.Issuer = issuerAndSerialNumber.Name;
recipientId.SerialNumber = issuerAndSerialNumber.SerialNumber.Value;
var recipientInformation = envelopedData.GetRecipientInfos().GetRecipients(recipientId);
var recipients = new ArrayList(recipientInformation);
//
// read the encrypted content info
//
var encInfo = envData.EncryptedContentInfo;
var encAlg = encInfo.ContentEncryptionAlgorithm;
var readable = new CmsProcessableByteArray(encInfo.EncryptedContent.GetOctets());
var keyParameter = ParameterUtilities.CreateKeyParameter(encAlg.Algorithm.Id, sessionKey);
// Todo: does this work with multi recipient?
foreach (RecipientInformation recipient in recipients)
{
var cmsReadable = GetReadable(keyParameter, encAlg, readable);
var cmsTypedStream = new CmsTypedStream(cmsReadable.GetInputStream());
var contentBytes = StreamToByteArray(cmsTypedStream.ContentStream);
var mimeEntity = MimeSerializer.Default.Deserialize <MimeEntity>(contentBytes);
return(mimeEntity);
}
}
}
}
catch (Exception ex)
{
Error.NotifyEvent(this, ex);
}
return(null);
}