private static void TestSimpleDecrypt_RoundTrip(CertLoader certLoader, ContentInfo contentInfo, string algorithmOidValue, SubjectIdentifierType type) { // Deep-copy the contentInfo since the real ContentInfo doesn't do this. This defends against a bad implementation changing // our "expectedContentInfo" to match what it produces. ContentInfo expectedContentInfo = new ContentInfo(new Oid(contentInfo.ContentType), (byte[])(contentInfo.Content.Clone())); string certSubjectName; byte[] encodedMessage; using (X509Certificate2 certificate = certLoader.GetCertificate()) { certSubjectName = certificate.Subject; AlgorithmIdentifier alg = new AlgorithmIdentifier(new Oid(algorithmOidValue)); EnvelopedCms ecms = new EnvelopedCms(contentInfo, alg); CmsRecipient cmsRecipient = new CmsRecipient(type, certificate); ecms.Encrypt(cmsRecipient); encodedMessage = ecms.Encode(); } // We don't pass "certificate" down because it's expected that the certificate used for encrypting doesn't have a private key (part of the purpose of this test is // to ensure that you don't need the recipient's private key to encrypt.) The decrypt phase will have to locate the matching cert with the private key. VerifySimpleDecrypt(encodedMessage, certLoader, expectedContentInfo); }
private static void VerifySimpleDecrypt(byte[] encodedMessage, CertLoader certLoader, ContentInfo expectedContent) { EnvelopedCms ecms = new EnvelopedCms(); ecms.Decode(encodedMessage); using (X509Certificate2 cert = certLoader.TryGetCertificateWithPrivateKey()) { if (cert == null) return; // Sorry - CertLoader is not configured to load certs with private keys - we've tested as much as we can. X509Certificate2Collection extraStore = new X509Certificate2Collection(cert); ecms.Decrypt(extraStore); ContentInfo contentInfo = ecms.ContentInfo; Assert.Equal(expectedContent.ContentType.Value, contentInfo.ContentType.Value); Assert.Equal<byte>(expectedContent.Content, contentInfo.Content); } }
public static void DecryptMultipleRecipients() { // Force Decrypt() to try multiple recipients. Ensure that a failure to find a matching cert in one doesn't cause it to quit early. CertLoader[] certLoaders = new CertLoader[] { Certificates.RSAKeyTransfer1, Certificates.RSAKeyTransfer2, Certificates.RSAKeyTransfer3, }; byte[] content = { 6, 3, 128, 33, 44 }; EnvelopedCms ecms = new EnvelopedCms(new ContentInfo(content), new AlgorithmIdentifier(new Oid(Oids.Aes256))); CmsRecipientCollection recipients = new CmsRecipientCollection(); foreach (CertLoader certLoader in certLoaders) { recipients.Add(new CmsRecipient(certLoader.GetCertificate())); } ecms.Encrypt(recipients); byte[] encodedMessage = ecms.Encode(); ecms = new EnvelopedCms(); ecms.Decode(encodedMessage); // How do we know that Decrypt() tries receipients in the order they appear in ecms.RecipientInfos? Because we wrote the implementation. // Not that some future implementation can't ever change it but it's the best guess we have. RecipientInfo me = ecms.RecipientInfos[2]; CertLoader matchingCertLoader = null; for (int index = 0; index < recipients.Count; index++) { if (recipients[index].Certificate.Issuer == ((X509IssuerSerial)(me.RecipientIdentifier.Value)).IssuerName) { matchingCertLoader = certLoaders[index]; break; } } Assert.NotNull(matchingCertLoader); using (X509Certificate2 cert = matchingCertLoader.TryGetCertificateWithPrivateKey()) { if (cert == null) return; // Sorry - CertLoader is not configured to load certs with private keys - we've tested as much as we can. X509Certificate2Collection extraStore = new X509Certificate2Collection(); extraStore.Add(cert); ecms.Decrypt(extraStore); } ContentInfo contentInfo = ecms.ContentInfo; Assert.Equal<byte>(content, contentInfo.Content); }