public sealed override byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes) { using (SafeCryptMsgHandle hCryptMsg = EncodeHelpers.CreateCryptMsgHandleToEncode(recipients, contentInfo.ContentType, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes)) { byte[] encodedContent; if (contentInfo.ContentType.Value.Equals(Oids.Pkcs7Data, StringComparison.OrdinalIgnoreCase)) { unsafe { byte[] content = contentInfo.Content; fixed (byte* pContent = content) { DATA_BLOB blob = new DATA_BLOB((IntPtr)pContent, (uint)(content.Length)); encodedContent = Interop.Crypt32.CryptEncodeObjectToByteArray(CryptDecodeObjectStructType.X509_OCTET_STRING, &blob); } } } else { encodedContent = contentInfo.Content; } if (encodedContent.Length > 0) { if (!Interop.Crypt32.CryptMsgUpdate(hCryptMsg, encodedContent, encodedContent.Length, fFinal: true)) throw Marshal.GetLastWin32Error().ToCryptographicException(); } byte[] encodedMessage = hCryptMsg.GetMsgParamAsByteArray(CryptMsgParamType.CMSG_CONTENT_PARAM); return encodedMessage; } }
public static void Rc4AndCngWrappersDontMixTest() { // // Combination of RC4 over a CAPI certificate. // // This works as long as the PKCS implementation opens the cert using CAPI. If he creates a CNG wrapper handle (by passing CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG), // the test fails with a NOTSUPPORTED crypto exception inside Decrypt(). The same happens if the key is genuinely CNG. // byte[] content = { 6, 3, 128, 33, 44 }; AlgorithmIdentifier rc4 = new AlgorithmIdentifier(new Oid(Oids.Rc4)); EnvelopedCms ecms = new EnvelopedCms(new ContentInfo(content), rc4); CmsRecipientCollection recipients = new CmsRecipientCollection(new CmsRecipient(Certificates.RSAKeyTransferCapi1.GetCertificate())); ecms.Encrypt(recipients); byte[] encodedMessage = ecms.Encode(); ecms = new EnvelopedCms(); ecms.Decode(encodedMessage); using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.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); }
// Perform a deep copy of a certificate collection private CmsRecipientCollection(CmsRecipientCollection other) { m_recipients = new ArrayList(other.m_recipients.Count); foreach (CmsRecipient recipient in other.m_recipients) { m_recipients.Add(new CmsRecipient(recipient.RecipientIdentifierType, new X509Certificate2(recipient.Certificate))); } }
public void Encrypt(CmsRecipientCollection recipients) { if (recipients == null) { throw new ArgumentNullException("recipients"); } // ? foreach on Encrypt CmsRecipient ? }
public static void Twoary_Ski() { CmsRecipient a0 = s_cr0; CmsRecipientCollection c = new CmsRecipientCollection(SubjectIdentifierType.SubjectKeyIdentifier, new X509Certificate2Collection(a0.Certificate)); Assert.Equal(1, c.Count); CmsRecipient actual = c[0]; Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, actual.RecipientIdentifierType); Assert.Equal(a0.Certificate, actual.Certificate); }
public static void Twoary() { CmsRecipient a0 = s_cr0; CmsRecipientCollection c = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, new X509Certificate2Collection(a0.Certificate)); Assert.Equal(1, c.Count); CmsRecipient actual = c[0]; Assert.Equal(a0.RecipientIdentifierType, actual.RecipientIdentifierType); Assert.Equal(a0.Certificate, actual.Certificate); }
RealCmsRecipientCollection GetRealCmsRecipients (IEnumerable<MailboxAddress> mailboxes) { var recipients = new RealCmsRecipientCollection (); foreach (var mailbox in mailboxes) recipients.Add (GetRealCmsRecipient (mailbox)); return recipients; }
public static void DecodeRecipients3_RoundTrip() { ContentInfo contentInfo = new ContentInfo(new byte[] { 1, 2, 3 }); EnvelopedCms ecms = new EnvelopedCms(contentInfo); CmsRecipientCollection recipients = new CmsRecipientCollection(); foreach (X509Certificate2 cert in s_certs) { recipients.Add(new CmsRecipient(cert)); } ecms.Encrypt(recipients); byte[] encodedMessage = ecms.Encode(); VerifyRecipients3(encodedMessage); }
/// <summary> /// Gets the preferred encryption algorithm to use for encrypting to the specified recipients. /// </summary> /// <remarks> /// <para>Gets the preferred encryption algorithm to use for encrypting to the specified recipients /// based on the encryption algorithms supported by each of the recipients, the /// <see cref="SecureMimeContext.EnabledEncryptionAlgorithms"/>, and the /// <see cref="SecureMimeContext.EncryptionAlgorithmRank"/>.</para> /// <para>If the supported encryption algorithms are unknown for any recipient, it is assumed that /// the recipient supports at least the Triple-DES encryption algorithm.</para> /// </remarks> /// <returns>The preferred encryption algorithm.</returns> /// <param name="recipients">The recipients.</param> protected virtual EncryptionAlgorithm GetPreferredEncryptionAlgorithm(RealCmsRecipientCollection recipients) { var votes = new int[EncryptionAlgorithmCount]; foreach (var recipient in recipients) { var supported = CmsRecipient.GetEncryptionAlgorithms(recipient.Certificate); int cast = EncryptionAlgorithmCount; foreach (var algorithm in supported) { votes[(int)algorithm] += cast; cast--; } } // Starting with S/MIME v3 (published in 1999), Triple-DES is a REQUIRED algorithm. // S/MIME v2.x and older only required RC2/40, but SUGGESTED Triple-DES. // Considering the fact that Bruce Schneier was able to write a // screensaver that could crack RC2/40 back in the late 90's, let's // not default to anything weaker than Triple-DES... EncryptionAlgorithm chosen = EncryptionAlgorithm.TripleDes; int nvotes = 0; // iterate through the algorithms, from strongest to weakest, keeping track // of the algorithm with the most amount of votes (between algorithms with // the same number of votes, choose the strongest of the 2 - i.e. the one // that we arrive at first). var algorithms = EncryptionAlgorithmRank; for (int i = 0; i < algorithms.Length; i++) { var algorithm = algorithms[i]; if (!IsEnabled(algorithm)) { continue; } if (votes[(int)algorithm] > nvotes) { nvotes = votes[(int)algorithm]; chosen = algorithm; } } return(chosen); }
RealCmsRecipientCollection GetRealCmsRecipients(IEnumerable <MailboxAddress> recipients) { var collection = new RealCmsRecipientCollection(); foreach (var recipient in recipients) { collection.Add(GetRealCmsRecipient(recipient)); } if (collection.Count == 0) { throw new ArgumentException("No recipients specified.", nameof(recipients)); } return(collection); }
public static void Add() { CmsRecipient a0 = s_cr0; CmsRecipient a1 = s_cr1; CmsRecipient a2 = s_cr2; CmsRecipientCollection c = new CmsRecipientCollection(); int index; index = c.Add(a0); Assert.Equal(0, index); index = c.Add(a1); Assert.Equal(1, index); index = c.Add(a2); Assert.Equal(2, index); AssertEquals(c, new CmsRecipient[] { a0, a1, a2 }); }
Stream Envelope(RealCmsRecipientCollection recipients, Stream content, EncryptionAlgorithm encryptionAlgorithm) { var contentInfo = new ContentInfo(ReadAllBytes(content)); RealAlgorithmIdentifier algorithm; switch (encryptionAlgorithm) { case EncryptionAlgorithm.Aes256: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.Aes256Cbc)); break; case EncryptionAlgorithm.Aes192: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.Aes192Cbc)); break; case EncryptionAlgorithm.Aes128: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.Aes128Cbc)); break; case EncryptionAlgorithm.RC2128: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.RC2Cbc), 128); break; case EncryptionAlgorithm.RC264: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.RC2Cbc), 64); break; case EncryptionAlgorithm.RC240: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.RC2Cbc), 40); break; default: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.DesEde3Cbc)); break; } var envelopedData = new EnvelopedCms(contentInfo, algorithm); envelopedData.Encrypt(recipients); return(new MemoryStream(envelopedData.Encode(), false)); }
public void Encrypt(CmsRecipientCollection recipients) { if (recipients == null) { throw new ArgumentNullException(nameof(recipients)); } // .NET Framework compat note: Unlike the desktop, we don't provide a free UI to select the recipient. The app must give it to us programmatically. if (recipients.Count == 0) { throw new PlatformNotSupportedException(SR.Cryptography_Cms_NoRecipients); } if (_decryptorPal != null) { _decryptorPal.Dispose(); _decryptorPal = null; } _encodedMessage = PkcsPal.Instance.Encrypt(recipients, ContentInfo, ContentEncryptionAlgorithm, Certificates, UnprotectedAttributes); _lastCall = LastCall.Encrypt; }
public static SafeCryptMsgHandle CreateCryptMsgHandleToEncode(CmsRecipientCollection recipients, Oid innerContentType, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes) { using (HeapBlockRetainer hb = new HeapBlockRetainer()) { // Deep copy the CmsRecipients (and especially their underlying X509Certificate2 objects). This will prevent malicious callers from altering them or disposing them while we're performing // unsafe memory crawling inside them. recipients = recipients.DeepCopy(); // We must keep all the certificates inside recipients alive until the call to CryptMsgOpenToEncode() finishes. The CMSG_ENVELOPED_ENCODE_INFO* structure we passed to it // contains direct pointers to memory owned by the CERT_INFO memory block whose lifetime is that of the certificate. hb.KeepAlive(recipients); unsafe { CMSG_ENVELOPED_ENCODE_INFO* pEnvelopedEncodeInfo = CreateCmsEnvelopedEncodeInfo(recipients, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes, hb); SafeCryptMsgHandle hCryptMsg = Interop.Crypt32.CryptMsgOpenToEncode(MsgEncodingType.All, 0, CryptMsgType.CMSG_ENVELOPED, pEnvelopedEncodeInfo, innerContentType.Value, IntPtr.Zero); if (hCryptMsg == null || hCryptMsg.IsInvalid) throw Marshal.GetLastWin32Error().ToCryptographicException(); return hCryptMsg; } } }
RealCmsRecipientCollection GetRealCmsRecipients(CmsRecipientCollection recipients) { var collection = new RealCmsRecipientCollection(); foreach (var recipient in recipients) { var certificate = new X509Certificate2(recipient.Certificate.GetEncoded()); RealSubjectIdentifierType type; if (recipient.RecipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber) { type = RealSubjectIdentifierType.IssuerAndSerialNumber; } else { type = RealSubjectIdentifierType.SubjectKeyIdentifier; } collection.Add(new RealCmsRecipient(type, certificate)); } return(collection); }
public static void Nullary() { CmsRecipientCollection c = new CmsRecipientCollection(); AssertEquals(c, Array.Empty<CmsRecipient>()); }
internal CmsRecipientEnumerator(CmsRecipientCollection recipients) { _recipients = recipients; _current = -1; }
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); }
/// <summary> /// Encrypt and encode a CMS. Return value is the RFC-compliant representation of the CMS that can be transmitted "on the wire." /// </summary> public abstract byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes);
public void Encrypt(CmsRecipientCollection recipients) { if (recipients == null) throw new ArgumentNullException(nameof(recipients)); // Desktop compat note: Unlike the desktop, we don't provide a free UI to select the recipient. The app must give it to us programmatically. if (recipients.Count == 0) throw new PlatformNotSupportedException(SR.Cryptography_Cms_NoRecipients); if (_decryptorPal != null) { _decryptorPal.Dispose(); _decryptorPal = null; } _encodedMessage = PkcsPal.Instance.Encrypt(recipients, ContentInfo, ContentEncryptionAlgorithm, Certificates, UnprotectedAttributes); _lastCall = LastCall.Encrypt; }
public static void Oneary() { CmsRecipient a0 = s_cr0; CmsRecipientCollection c = new CmsRecipientCollection(a0); AssertEquals(c, new CmsRecipient[] { a0 }); }
private static unsafe void SetCmsRecipientParams(CmsRecipientCollection recipients, X509Certificate2Collection certificates, CryptographicAttributeObjectCollection unprotectedAttributes, AlgorithmIdentifier contentEncryptionAlgorithm, ref CMSG_ENCRYPT_PARAM encryptParam) { int index = 0; uint[] numArray = new uint[recipients.Count]; int num2 = 0; int num3 = recipients.Count * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCODE_INFO)); int num4 = num3; for (index = 0; index < recipients.Count; index++) { numArray[index] = (uint) PkcsUtils.GetRecipientInfoType(recipients[index].Certificate); if (numArray[index] == 1) { num4 += Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO)); } else { if (numArray[index] != 2) { throw new CryptographicException(-2146889726); } num2++; num4 += Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO)); } } encryptParam.rgpRecipients = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(num4)); encryptParam.rgCertEncoded = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle; encryptParam.rgUnprotectedAttr = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle; encryptParam.rgSubjectKeyIdentifier = new System.Security.Cryptography.SafeLocalAllocHandle[recipients.Count]; encryptParam.rgszObjId = new System.Security.Cryptography.SafeLocalAllocHandle[recipients.Count]; if (num2 > 0) { encryptParam.rgszKeyWrapObjId = new System.Security.Cryptography.SafeLocalAllocHandle[num2]; encryptParam.rgKeyWrapAuxInfo = new System.Security.Cryptography.SafeLocalAllocHandle[num2]; encryptParam.rgEphemeralIdentifier = new System.Security.Cryptography.SafeLocalAllocHandle[num2]; encryptParam.rgszEphemeralObjId = new System.Security.Cryptography.SafeLocalAllocHandle[num2]; encryptParam.rgUserKeyingMaterial = new System.Security.Cryptography.SafeLocalAllocHandle[num2]; encryptParam.prgpEncryptedKey = new System.Security.Cryptography.SafeLocalAllocHandle[num2]; encryptParam.rgpEncryptedKey = new System.Security.Cryptography.SafeLocalAllocHandle[num2]; } if (certificates.Count > 0) { encryptParam.rgCertEncoded = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(certificates.Count * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB)))); for (index = 0; index < certificates.Count; index++) { System.Security.Cryptography.CAPI.CERT_CONTEXT cert_context = (System.Security.Cryptography.CAPI.CERT_CONTEXT) Marshal.PtrToStructure(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificates[index]).DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_CONTEXT)); System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB* cryptoapi_blobPtr = (System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB*) new IntPtr(((long) encryptParam.rgCertEncoded.DangerousGetHandle()) + (index * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB)))); cryptoapi_blobPtr->cbData = cert_context.cbCertEncoded; cryptoapi_blobPtr->pbData = cert_context.pbCertEncoded; } } if (unprotectedAttributes.Count > 0) { encryptParam.rgUnprotectedAttr = new System.Security.Cryptography.SafeLocalAllocHandle(PkcsUtils.CreateCryptAttributes(unprotectedAttributes)); } num2 = 0; IntPtr ptr = new IntPtr(((long) encryptParam.rgpRecipients.DangerousGetHandle()) + num3); for (index = 0; index < recipients.Count; index++) { CmsRecipient recipient = recipients[index]; X509Certificate2 certificate = recipient.Certificate; System.Security.Cryptography.CAPI.CERT_CONTEXT cert_context2 = (System.Security.Cryptography.CAPI.CERT_CONTEXT) Marshal.PtrToStructure(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate).DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_CONTEXT)); System.Security.Cryptography.CAPI.CERT_INFO cert_info = (System.Security.Cryptography.CAPI.CERT_INFO) Marshal.PtrToStructure(cert_context2.pCertInfo, typeof(System.Security.Cryptography.CAPI.CERT_INFO)); System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCODE_INFO* cmsg_recipient_encode_infoPtr = (System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCODE_INFO*) new IntPtr(((long) encryptParam.rgpRecipients.DangerousGetHandle()) + (index * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCODE_INFO)))); cmsg_recipient_encode_infoPtr->dwRecipientChoice = numArray[index]; cmsg_recipient_encode_infoPtr->pRecipientInfo = ptr; if (numArray[index] == 1) { IntPtr ptr2 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "cbSize"))); Marshal.WriteInt32(ptr2, Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO))); IntPtr ptr3 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm"))); byte[] bytes = Encoding.ASCII.GetBytes(cert_info.SubjectPublicKeyInfo.Algorithm.pszObjId); encryptParam.rgszObjId[index] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(bytes.Length + 1)); Marshal.Copy(bytes, 0, encryptParam.rgszObjId[index].DangerousGetHandle(), bytes.Length); IntPtr ptr4 = new IntPtr(((long) ptr3) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"))); Marshal.WriteIntPtr(ptr4, encryptParam.rgszObjId[index].DangerousGetHandle()); IntPtr ptr5 = new IntPtr(((long) ptr3) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters"))); IntPtr ptr6 = new IntPtr(((long) ptr5) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData"))); Marshal.WriteInt32(ptr6, (int) cert_info.SubjectPublicKeyInfo.Algorithm.Parameters.cbData); IntPtr ptr7 = new IntPtr(((long) ptr5) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData"))); Marshal.WriteIntPtr(ptr7, cert_info.SubjectPublicKeyInfo.Algorithm.Parameters.pbData); IntPtr ptr8 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientPublicKey"))); ptr6 = new IntPtr(((long) ptr8) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "cbData"))); Marshal.WriteInt32(ptr6, (int) cert_info.SubjectPublicKeyInfo.PublicKey.cbData); ptr7 = new IntPtr(((long) ptr8) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "pbData"))); Marshal.WriteIntPtr(ptr7, cert_info.SubjectPublicKeyInfo.PublicKey.pbData); IntPtr ptr9 = new IntPtr(((long) ptr8) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "cUnusedBits"))); Marshal.WriteInt32(ptr9, (int) cert_info.SubjectPublicKeyInfo.PublicKey.cUnusedBits); IntPtr ptr10 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientId"))); if (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier) { uint pcbData = 0; System.Security.Cryptography.SafeLocalAllocHandle invalidHandle = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle; if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate), 20, invalidHandle, ref pcbData)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } invalidHandle = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long) pcbData)); if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate), 20, invalidHandle, ref pcbData)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } encryptParam.rgSubjectKeyIdentifier[index] = invalidHandle; IntPtr ptr11 = new IntPtr(((long) ptr10) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "dwIdChoice"))); Marshal.WriteInt32(ptr11, 2); IntPtr ptr12 = new IntPtr(((long) ptr10) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "Value"))); ptr6 = new IntPtr(((long) ptr12) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData"))); Marshal.WriteInt32(ptr6, (int) pcbData); ptr7 = new IntPtr(((long) ptr12) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData"))); Marshal.WriteIntPtr(ptr7, invalidHandle.DangerousGetHandle()); } else { IntPtr ptr13 = new IntPtr(((long) ptr10) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "dwIdChoice"))); Marshal.WriteInt32(ptr13, 1); IntPtr ptr14 = new IntPtr(((long) ptr10) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "Value"))); IntPtr ptr15 = new IntPtr(((long) ptr14) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer"))); ptr6 = new IntPtr(((long) ptr15) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData"))); Marshal.WriteInt32(ptr6, (int) cert_info.Issuer.cbData); ptr7 = new IntPtr(((long) ptr15) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData"))); Marshal.WriteIntPtr(ptr7, cert_info.Issuer.pbData); IntPtr ptr16 = new IntPtr(((long) ptr14) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber"))); ptr6 = new IntPtr(((long) ptr16) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData"))); Marshal.WriteInt32(ptr6, (int) cert_info.SerialNumber.cbData); ptr7 = new IntPtr(((long) ptr16) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData"))); Marshal.WriteIntPtr(ptr7, cert_info.SerialNumber.pbData); } ptr = new IntPtr(((long) ptr) + Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO))); } else if (numArray[index] == 2) { IntPtr ptr17 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cbSize"))); Marshal.WriteInt32(ptr17, Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO))); IntPtr ptr18 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm"))); byte[] source = Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.5"); encryptParam.rgszObjId[index] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(source.Length + 1)); Marshal.Copy(source, 0, encryptParam.rgszObjId[index].DangerousGetHandle(), source.Length); IntPtr ptr19 = new IntPtr(((long) ptr18) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"))); Marshal.WriteIntPtr(ptr19, encryptParam.rgszObjId[index].DangerousGetHandle()); IntPtr ptr20 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyWrapAlgorithm"))); uint num6 = System.Security.Cryptography.X509Certificates.X509Utils.OidToAlgId(contentEncryptionAlgorithm.Oid.Value); if (num6 == 0x6602) { source = Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.7"); } else { source = Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.6"); } encryptParam.rgszKeyWrapObjId[num2] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(source.Length + 1)); Marshal.Copy(source, 0, encryptParam.rgszKeyWrapObjId[num2].DangerousGetHandle(), source.Length); ptr19 = new IntPtr(((long) ptr20) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"))); Marshal.WriteIntPtr(ptr19, encryptParam.rgszKeyWrapObjId[num2].DangerousGetHandle()); if (num6 == 0x6602) { IntPtr ptr21 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pvKeyWrapAuxInfo"))); Marshal.WriteIntPtr(ptr21, encryptParam.pvEncryptionAuxInfo.DangerousGetHandle()); } IntPtr ptr22 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "dwKeyChoice"))); Marshal.WriteInt32(ptr22, 1); IntPtr ptr23 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pEphemeralAlgorithmOrSenderId"))); encryptParam.rgEphemeralIdentifier[num2] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER)))); Marshal.WriteIntPtr(ptr23, encryptParam.rgEphemeralIdentifier[num2].DangerousGetHandle()); source = Encoding.ASCII.GetBytes(cert_info.SubjectPublicKeyInfo.Algorithm.pszObjId); encryptParam.rgszEphemeralObjId[num2] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(source.Length + 1)); Marshal.Copy(source, 0, encryptParam.rgszEphemeralObjId[num2].DangerousGetHandle(), source.Length); ptr19 = new IntPtr(((long) encryptParam.rgEphemeralIdentifier[num2].DangerousGetHandle()) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"))); Marshal.WriteIntPtr(ptr19, encryptParam.rgszEphemeralObjId[num2].DangerousGetHandle()); IntPtr ptr24 = new IntPtr(((long) encryptParam.rgEphemeralIdentifier[num2].DangerousGetHandle()) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters"))); IntPtr ptr25 = new IntPtr(((long) ptr24) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData"))); Marshal.WriteInt32(ptr25, (int) cert_info.SubjectPublicKeyInfo.Algorithm.Parameters.cbData); IntPtr ptr26 = new IntPtr(((long) ptr24) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData"))); Marshal.WriteIntPtr(ptr26, cert_info.SubjectPublicKeyInfo.Algorithm.Parameters.pbData); IntPtr ptr27 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cRecipientEncryptedKeys"))); Marshal.WriteInt32(ptr27, 1); encryptParam.prgpEncryptedKey[num2] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(IntPtr)))); IntPtr ptr28 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "rgpRecipientEncryptedKeys"))); Marshal.WriteIntPtr(ptr28, encryptParam.prgpEncryptedKey[num2].DangerousGetHandle()); encryptParam.rgpEncryptedKey[num2] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO)))); Marshal.WriteIntPtr(encryptParam.prgpEncryptedKey[num2].DangerousGetHandle(), encryptParam.rgpEncryptedKey[num2].DangerousGetHandle()); ptr17 = new IntPtr(((long) encryptParam.rgpEncryptedKey[num2].DangerousGetHandle()) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "cbSize"))); Marshal.WriteInt32(ptr17, Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO))); IntPtr ptr29 = new IntPtr(((long) encryptParam.rgpEncryptedKey[num2].DangerousGetHandle()) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientPublicKey"))); ptr25 = new IntPtr(((long) ptr29) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "cbData"))); Marshal.WriteInt32(ptr25, (int) cert_info.SubjectPublicKeyInfo.PublicKey.cbData); ptr26 = new IntPtr(((long) ptr29) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "pbData"))); Marshal.WriteIntPtr(ptr26, cert_info.SubjectPublicKeyInfo.PublicKey.pbData); IntPtr ptr30 = new IntPtr(((long) ptr29) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "cUnusedBits"))); Marshal.WriteInt32(ptr30, (int) cert_info.SubjectPublicKeyInfo.PublicKey.cUnusedBits); IntPtr ptr31 = new IntPtr(((long) encryptParam.rgpEncryptedKey[num2].DangerousGetHandle()) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientId"))); IntPtr ptr32 = new IntPtr(((long) ptr31) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "dwIdChoice"))); if (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier) { Marshal.WriteInt32(ptr32, 2); IntPtr ptr33 = new IntPtr(((long) ptr31) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "Value"))); uint num7 = 0; System.Security.Cryptography.SafeLocalAllocHandle pvData = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle; if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate), 20, pvData, ref num7)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } pvData = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long) num7)); if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate), 20, pvData, ref num7)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } encryptParam.rgSubjectKeyIdentifier[num2] = pvData; ptr25 = new IntPtr(((long) ptr33) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData"))); Marshal.WriteInt32(ptr25, (int) num7); ptr26 = new IntPtr(((long) ptr33) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData"))); Marshal.WriteIntPtr(ptr26, pvData.DangerousGetHandle()); } else { Marshal.WriteInt32(ptr32, 1); IntPtr ptr34 = new IntPtr(((long) ptr31) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "Value"))); IntPtr ptr35 = new IntPtr(((long) ptr34) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer"))); ptr25 = new IntPtr(((long) ptr35) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData"))); Marshal.WriteInt32(ptr25, (int) cert_info.Issuer.cbData); ptr26 = new IntPtr(((long) ptr35) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData"))); Marshal.WriteIntPtr(ptr26, cert_info.Issuer.pbData); IntPtr ptr36 = new IntPtr(((long) ptr34) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber"))); ptr25 = new IntPtr(((long) ptr36) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData"))); Marshal.WriteInt32(ptr25, (int) cert_info.SerialNumber.cbData); ptr26 = new IntPtr(((long) ptr36) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData"))); Marshal.WriteIntPtr(ptr26, cert_info.SerialNumber.pbData); } num2++; ptr = new IntPtr(((long) ptr) + Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO))); } } }
public static void CopyExceptions() { CmsRecipient a0 = s_cr0; CmsRecipient a1 = s_cr1; CmsRecipient a2 = s_cr2; CmsRecipientCollection c = new CmsRecipientCollection(); c.Add(a0); c.Add(a1); c.Add(a2); CmsRecipient[] a = new CmsRecipient[3]; Assert.Throws<ArgumentNullException>(() => c.CopyTo(null, 0)); Assert.Throws<ArgumentOutOfRangeException>(() => c.CopyTo(a, -1)); Assert.Throws<ArgumentOutOfRangeException>(() => c.CopyTo(a, 3)); Assert.Throws<ArgumentException>(() => c.CopyTo(a, 1)); ICollection ic = c; Assert.Throws<ArgumentNullException>(() => ic.CopyTo(null, 0)); Assert.Throws<ArgumentOutOfRangeException>(() => ic.CopyTo(a, -1)); Assert.Throws<ArgumentOutOfRangeException>(() => ic.CopyTo(a, 3)); Assert.Throws<ArgumentException>(() => ic.CopyTo(a, 1)); Assert.Throws<ArgumentException>(() => ic.CopyTo(new CmsRecipient[2, 2], 1)); Assert.Throws<InvalidCastException>(() => ic.CopyTo(new int[10], 1)); // Array has non-zero lower bound Array array = Array.CreateInstance(typeof(object), new int[] { 10 }, new int[] { 10 }); Assert.Throws<IndexOutOfRangeException>(() => ic.CopyTo(array, 0)); }
private static unsafe void SetCmsRecipientParams(CmsRecipientCollection recipients, X509Certificate2Collection certificates, CryptographicAttributeObjectCollection unprotectedAttributes, AlgorithmIdentifier contentEncryptionAlgorithm, ref CMSG_ENCRYPT_PARAM encryptParam) { checked { recipients = recipients.DeepCopy(); certificates = new X509Certificate2Collection(certificates); int index = 0; uint[] recipientInfoTypes = new uint[recipients.Count]; int cKeyAgree = 0; int reiSize = recipients.Count * Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCODE_INFO)); int totalSize = reiSize; for (index = 0; index < recipients.Count; index++) { recipientInfoTypes[index] = (uint) PkcsUtils.GetRecipientInfoType(recipients[index].Certificate); if (recipientInfoTypes[index] == CAPI.CMSG_KEY_TRANS_RECIPIENT) { totalSize += Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO)); } else if (recipientInfoTypes[index] == CAPI.CMSG_KEY_AGREE_RECIPIENT) { cKeyAgree++; totalSize += Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO)); } else { throw new CryptographicException(CAPI.CRYPT_E_UNKNOWN_ALGO); } } encryptParam.rgpRecipients = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(totalSize)); encryptParam.rgCertEncoded = SafeLocalAllocHandle.InvalidHandle; encryptParam.rgUnprotectedAttr = SafeLocalAllocHandle.InvalidHandle; encryptParam.rgSubjectKeyIdentifier = new SafeLocalAllocHandle[recipients.Count]; encryptParam.rgszObjId = new SafeLocalAllocHandle[recipients.Count]; if (cKeyAgree > 0) { encryptParam.rgszKeyWrapObjId = new SafeLocalAllocHandle[cKeyAgree]; encryptParam.rgKeyWrapAuxInfo = new SafeLocalAllocHandle[cKeyAgree]; encryptParam.rgEphemeralIdentifier = new SafeLocalAllocHandle[cKeyAgree]; encryptParam.rgszEphemeralObjId = new SafeLocalAllocHandle[cKeyAgree]; encryptParam.rgUserKeyingMaterial = new SafeLocalAllocHandle[cKeyAgree]; encryptParam.prgpEncryptedKey = new SafeLocalAllocHandle[cKeyAgree]; encryptParam.rgpEncryptedKey = new SafeLocalAllocHandle[cKeyAgree]; } // Create encode certs array. if (certificates.Count > 0) { encryptParam.rgCertEncoded = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(certificates.Count * Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB)))); for (index = 0; index < certificates.Count; index++) { CAPI.CERT_CONTEXT pCertContext = (CAPI.CERT_CONTEXT) Marshal.PtrToStructure(X509Utils.GetCertContext(certificates[index]).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT)); CAPI.CRYPTOAPI_BLOB * pBlob = (CAPI.CRYPTOAPI_BLOB *) new IntPtr((long) encryptParam.rgCertEncoded.DangerousGetHandle() + (index * Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB)))); pBlob->cbData = pCertContext.cbCertEncoded; pBlob->pbData = pCertContext.pbCertEncoded; } } // Create unprotected attributes array. if (unprotectedAttributes.Count > 0) { encryptParam.rgUnprotectedAttr = new SafeLocalAllocHandle(PkcsUtils.CreateCryptAttributes(unprotectedAttributes)); } // pKeyInfo = CMSG_ENVELOPED_ENCODE_INFO.rgCmsRecipients cKeyAgree = 0; IntPtr pKeyInfo = new IntPtr((long) encryptParam.rgpRecipients.DangerousGetHandle() + reiSize); for (index = 0; index < recipients.Count; index++) { CmsRecipient recipient = recipients[index]; X509Certificate2 certificate = recipient.Certificate; CAPI.CERT_CONTEXT pCertContext = (CAPI.CERT_CONTEXT) Marshal.PtrToStructure(X509Utils.GetCertContext(certificate).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT)); CAPI.CERT_INFO certInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO)); CAPI.CMSG_RECIPIENT_ENCODE_INFO * pEncodeInfo = (CAPI.CMSG_RECIPIENT_ENCODE_INFO *) new IntPtr((long) encryptParam.rgpRecipients.DangerousGetHandle() + (index * Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCODE_INFO)))); // CMSG_RECIPIENT_ENCODE_INFO.dwRecipientChoice pEncodeInfo->dwRecipientChoice = (uint) recipientInfoTypes[index]; // CMSG_RECIPIENT_ENCODE_INFO.pRecipientInfo (pKeyTrans or pKeyAgree) pEncodeInfo->pRecipientInfo = pKeyInfo; if (recipientInfoTypes[index] == CAPI.CMSG_KEY_TRANS_RECIPIENT) { // Fill in CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO. // cbSize IntPtr pcbSize = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "cbSize")); Marshal.WriteInt32(pcbSize, Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO))); // KeyEncryptionAlgorithm IntPtr pKeyEncryptionAlgorithm = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm")); byte[] objId = Encoding.ASCII.GetBytes(certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId); encryptParam.rgszObjId[index] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(objId.Length + 1)); Marshal.Copy(objId, 0, encryptParam.rgszObjId[index].DangerousGetHandle(), objId.Length); // KeyEncryptionAlgorithm.pszObjId IntPtr pszObjId = new IntPtr((long) pKeyEncryptionAlgorithm + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")); Marshal.WriteIntPtr(pszObjId, encryptParam.rgszObjId[index].DangerousGetHandle()); // KeyEncryptionAlgorithm.Parameters IntPtr pParameters = new IntPtr((long) pKeyEncryptionAlgorithm + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters")); // KeyEncryptionAlgorithm.Parameters.cbData IntPtr pcbData = new IntPtr((long) pParameters + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(pcbData, (int) certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.cbData); // KeyEncryptionAlgorithm.Parameters.pbData IntPtr ppbData = new IntPtr((long) pParameters + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ppbData, certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.pbData); // Skip pvKeyEncryptionAuxInfo // Skip hCryptProv // RecipientPublicKey IntPtr pRecipientPublicKey = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientPublicKey")); // RecipientPublicKey.cbData pcbData = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cbData")); Marshal.WriteInt32(pcbData, (int) certInfo.SubjectPublicKeyInfo.PublicKey.cbData); // RecipientPublicKey.pbData ppbData = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "pbData")); Marshal.WriteIntPtr(ppbData, certInfo.SubjectPublicKeyInfo.PublicKey.pbData); // RecipientPublicKey.cUnusedBits IntPtr pcUnusedBIts = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cUnusedBits")); Marshal.WriteInt32(pcUnusedBIts, (int) certInfo.SubjectPublicKeyInfo.PublicKey.cUnusedBits); // RecipientId IntPtr pRecipientId = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientId")); if (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier) { uint cbData = 0; SafeLocalAllocHandle pbData = SafeLocalAllocHandle.InvalidHandle; if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), CAPI.CERT_KEY_IDENTIFIER_PROP_ID, pbData, ref cbData)) throw new CryptographicException(Marshal.GetLastWin32Error()); pbData = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(cbData)); if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), CAPI.CERT_KEY_IDENTIFIER_PROP_ID, pbData, ref cbData)) throw new CryptographicException(Marshal.GetLastWin32Error()); encryptParam.rgSubjectKeyIdentifier[index] = pbData; // RecipientId.dwIdChoice IntPtr pdwIdChoice = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice")); Marshal.WriteInt32(pdwIdChoice, (int) CAPI.CERT_ID_KEY_IDENTIFIER); // RecipientId.KeyId IntPtr pKeyId = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value")); // RecipientId.KeyId.cbData pcbData = new IntPtr((long) pKeyId + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(pcbData, (int) cbData); // RecipientId.KeyId.pbData ppbData = new IntPtr((long) pKeyId + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ppbData, pbData.DangerousGetHandle()); } else { // RecipientId.dwIdChoice IntPtr pdwIdChoice = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice")); Marshal.WriteInt32(pdwIdChoice, (int) CAPI.CERT_ID_ISSUER_SERIAL_NUMBER); // RecipientId.IssuerSerialNumber IntPtr pIssuerSerialNumber = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value")); // RecipientId.IssuerSerialNumber.Issuer IntPtr pIssuer = new IntPtr((long) pIssuerSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer")); // RecipientId.IssuerSerialNumber.Issuer.cbData pcbData = new IntPtr((long) pIssuer + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(pcbData, (int) certInfo.Issuer.cbData); // RecipientId.IssuerSerialNumber.Issuer.pbData ppbData = new IntPtr((long) pIssuer + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ppbData, certInfo.Issuer.pbData); // RecipientId.IssuerSerialNumber.SerialNumber IntPtr pSerialNumber = new IntPtr((long) pIssuerSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber")); // RecipientId.IssuerSerialNumber.SerialNumber.cbData pcbData = new IntPtr((long) pSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(pcbData, (int) certInfo.SerialNumber.cbData); // RecipientId.IssuerSerialNumber.SerialNumber.pbData ppbData = new IntPtr((long) pSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ppbData, certInfo.SerialNumber.pbData); } pKeyInfo = new IntPtr((long) pKeyInfo + Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO))); } else if (recipientInfoTypes[index] == CAPI.CMSG_KEY_AGREE_RECIPIENT) { // Fill in CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO. // cbSize IntPtr pcbSize = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cbSize")); Marshal.WriteInt32(pcbSize, Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO))); // KeyEncryptionAlgorithm IntPtr pKeyEncryptionAlgorithm = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm")); byte[] objId = Encoding.ASCII.GetBytes(CAPI.szOID_RSA_SMIMEalgESDH); encryptParam.rgszObjId[index] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(objId.Length + 1)); Marshal.Copy(objId, 0, encryptParam.rgszObjId[index].DangerousGetHandle(), objId.Length); // KeyEncryptionAlgorithm.pszObjId IntPtr pszObjId = new IntPtr((long) pKeyEncryptionAlgorithm + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")); Marshal.WriteIntPtr(pszObjId, encryptParam.rgszObjId[index].DangerousGetHandle()); // Skip KeyEncryptionAlgorithm.Parameters // Skip pvKeyEncryptionAuxInfo // KeyWrapAlgorithm IntPtr pKeyWrapAlgorithm = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyWrapAlgorithm")); uint algId = X509Utils.OidToAlgId(contentEncryptionAlgorithm.Oid.Value); if (algId == CAPI.CALG_RC2) { objId = Encoding.ASCII.GetBytes(CAPI.szOID_RSA_SMIMEalgCMSRC2wrap); } else { objId = Encoding.ASCII.GetBytes(CAPI.szOID_RSA_SMIMEalgCMS3DESwrap); } encryptParam.rgszKeyWrapObjId[cKeyAgree] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(objId.Length + 1)); Marshal.Copy(objId, 0, encryptParam.rgszKeyWrapObjId[cKeyAgree].DangerousGetHandle(), objId.Length); // KeyWrapAlgorithm.pszObjId pszObjId = new IntPtr((long) pKeyWrapAlgorithm + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")); Marshal.WriteIntPtr(pszObjId, encryptParam.rgszKeyWrapObjId[cKeyAgree].DangerousGetHandle()); // Skip KeyWrapAlgorithm.Parameters // Fill in pvKeyWrapAuxInfo for RC2. if (algId == CAPI.CALG_RC2) { IntPtr pKeyWrapAuxInfo = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pvKeyWrapAuxInfo")); Marshal.WriteIntPtr(pKeyWrapAuxInfo, encryptParam.pvEncryptionAuxInfo.DangerousGetHandle()); } // Skip hCryptProv // Skip dwKeySpec // dwKeyChoice IntPtr pdwKeyChoice = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "dwKeyChoice")); Marshal.WriteInt32(pdwKeyChoice, (int) CAPI.CMSG_KEY_AGREE_EPHEMERAL_KEY_CHOICE); // pEphemeralAlgorithm IntPtr pEphemeralAlgorithm = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pEphemeralAlgorithmOrSenderId")); encryptParam.rgEphemeralIdentifier[cKeyAgree] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER)))); Marshal.WriteIntPtr(pEphemeralAlgorithm, encryptParam.rgEphemeralIdentifier[cKeyAgree].DangerousGetHandle()); // pEphemeralAlgorithm.pszObjId objId = Encoding.ASCII.GetBytes(certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId); encryptParam.rgszEphemeralObjId[cKeyAgree] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(objId.Length + 1)); Marshal.Copy(objId, 0, encryptParam.rgszEphemeralObjId[cKeyAgree].DangerousGetHandle(), objId.Length); pszObjId = new IntPtr((long) encryptParam.rgEphemeralIdentifier[cKeyAgree].DangerousGetHandle() + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")); Marshal.WriteIntPtr(pszObjId, encryptParam.rgszEphemeralObjId[cKeyAgree].DangerousGetHandle()); // pEphemeralAlgorithm.Parameters IntPtr pParameters = new IntPtr((long) encryptParam.rgEphemeralIdentifier[cKeyAgree].DangerousGetHandle() + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters")); // pEphemeralAlgorithm.Parameters.cbData IntPtr pcbData = new IntPtr((long) pParameters + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(pcbData, (int) certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.cbData); // pEphemeralAlgorithm.Parameters.pbData IntPtr ppbData = new IntPtr((long) pParameters + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ppbData, certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.pbData); // Skip UserKeyingMaterial // cRecipientEncryptedKeys IntPtr pcRecipientEncryptedKeys = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cRecipientEncryptedKeys")); Marshal.WriteInt32(pcRecipientEncryptedKeys, 1); // rgpRecipientEncryptedKeys encryptParam.prgpEncryptedKey[cKeyAgree] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(IntPtr)))); IntPtr prgpRecipientEncryptedKeys = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "rgpRecipientEncryptedKeys")); Marshal.WriteIntPtr(prgpRecipientEncryptedKeys, encryptParam.prgpEncryptedKey[cKeyAgree].DangerousGetHandle()); encryptParam.rgpEncryptedKey[cKeyAgree] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO)))); Marshal.WriteIntPtr(encryptParam.prgpEncryptedKey[cKeyAgree].DangerousGetHandle(), encryptParam.rgpEncryptedKey[cKeyAgree].DangerousGetHandle()); // rgpRecipientEncryptedKeys.cbSize pcbSize = new IntPtr((long) encryptParam.rgpEncryptedKey[cKeyAgree].DangerousGetHandle() + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "cbSize")); Marshal.WriteInt32(pcbSize, Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO))); // rgpRecipientEncryptedKeys.RecipientPublicKey IntPtr pRecipientPublicKey = new IntPtr((long) encryptParam.rgpEncryptedKey[cKeyAgree].DangerousGetHandle() + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientPublicKey")); // rgpRecipientEncryptedKeys.RecipientPublicKey.cbData pcbData = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cbData")); Marshal.WriteInt32(pcbData, (int) certInfo.SubjectPublicKeyInfo.PublicKey.cbData); // rgpRecipientEncryptedKeys.RecipientPublicKey.pbData ppbData = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "pbData")); Marshal.WriteIntPtr(ppbData, certInfo.SubjectPublicKeyInfo.PublicKey.pbData); // rgpRecipientEncryptedKeys.RecipientPublicKey.cUnusedBits IntPtr pcUnusedBits = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cUnusedBits")); Marshal.WriteInt32(pcUnusedBits, (int) certInfo.SubjectPublicKeyInfo.PublicKey.cUnusedBits); // rgpRecipientEncryptedKeys.RecipientId IntPtr pRecipientId = new IntPtr((long) encryptParam.rgpEncryptedKey[cKeyAgree].DangerousGetHandle() + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientId")); // rgpRecipientEncryptedKeys.RecipientId.dwIdChoice IntPtr pdwIdChoice = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice")); if (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier) { Marshal.WriteInt32(pdwIdChoice, (int) CAPI.CERT_ID_KEY_IDENTIFIER); // rgpRecipientEncryptedKeys.RecipientId.KeyId IntPtr pKeyId = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value")); uint cbKeyId = 0; SafeLocalAllocHandle pbKeyId = SafeLocalAllocHandle.InvalidHandle; if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), CAPI.CERT_KEY_IDENTIFIER_PROP_ID, pbKeyId, ref cbKeyId)) throw new CryptographicException(Marshal.GetLastWin32Error()); pbKeyId = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(cbKeyId)); if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), CAPI.CERT_KEY_IDENTIFIER_PROP_ID, pbKeyId, ref cbKeyId)) throw new CryptographicException(Marshal.GetLastWin32Error()); encryptParam.rgSubjectKeyIdentifier[cKeyAgree] = pbKeyId; // rgpRecipientEncryptedKeys.RecipientId.KeyId.cbData pcbData = new IntPtr((long) pKeyId + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(pcbData, (int) cbKeyId); // rgpRecipientEncryptedKeys.RecipientId.KeyId.pbData ppbData = new IntPtr((long) pKeyId + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ppbData, pbKeyId.DangerousGetHandle()); } else { Marshal.WriteInt32(pdwIdChoice, (int) CAPI.CERT_ID_ISSUER_SERIAL_NUMBER); // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber IntPtr pIssuerSerial = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value")); // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.Issuer IntPtr pIssuer = new IntPtr((long) pIssuerSerial + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer")); // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.Issuer.cbData pcbData = new IntPtr((long) pIssuer + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(pcbData, (int) certInfo.Issuer.cbData); // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.Issuer.pbData ppbData = new IntPtr((long) pIssuer + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ppbData, certInfo.Issuer.pbData); // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.SerialNumber IntPtr pSerialNumber = new IntPtr((long) pIssuerSerial + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber")); // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.SerialNumber.cbData pcbData = new IntPtr((long) pSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(pcbData, (int) certInfo.SerialNumber.cbData); // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.SerialNumber.pbData ppbData = new IntPtr((long) pSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ppbData, certInfo.SerialNumber.pbData); } // Bump key agree count. cKeyAgree++; pKeyInfo = new IntPtr((long) pKeyInfo + Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO))); } else { // Should never get here! Debug.Assert(false); } } } }
private unsafe void EncryptContent (CmsRecipientCollection recipients) { CMSG_ENCRYPT_PARAM encryptParam = new CMSG_ENCRYPT_PARAM(); if (recipients.Count < 1) throw new CryptographicException(CAPI.CRYPT_E_RECIPIENT_NOT_FOUND); foreach (CmsRecipient recipient in recipients) { if (recipient.Certificate == null) throw new ArgumentNullException(SecurityResources.GetResourceString("Cryptography_Cms_RecipientCertificateNotFound")); if ((PkcsUtils.GetRecipientInfoType(recipient.Certificate) == RecipientInfoType.KeyAgreement) || (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)) encryptParam.useCms = true; } if (!encryptParam.useCms) { if (this.Certificates.Count > 0 || this.UnprotectedAttributes.Count > 0) { encryptParam.useCms = true; } } if (encryptParam.useCms && !PkcsUtils.CmsSupported()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported")); } CAPI.CMSG_ENVELOPED_ENCODE_INFO encodeInfo = new CAPI.CMSG_ENVELOPED_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO))); SafeLocalAllocHandle ceei = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO)))); SetCspParams(this.ContentEncryptionAlgorithm, ref encryptParam); encodeInfo.ContentEncryptionAlgorithm.pszObjId = this.ContentEncryptionAlgorithm.Oid.Value; //encodeInfo.hCryptProv = encryptParam.safeCryptProvHandle.DangerousGetHandle(); if (encryptParam.pvEncryptionAuxInfo != null && !encryptParam.pvEncryptionAuxInfo.IsInvalid) { encodeInfo.pvEncryptionAuxInfo = encryptParam.pvEncryptionAuxInfo.DangerousGetHandle(); } encodeInfo.cRecipients = (uint) recipients.Count; List<SafeCertContextHandle> certContexts = null; if (encryptParam.useCms) { SetCmsRecipientParams(recipients, this.Certificates, this.UnprotectedAttributes, this.ContentEncryptionAlgorithm, ref encryptParam); encodeInfo.rgCmsRecipients = encryptParam.rgpRecipients.DangerousGetHandle(); if (encryptParam.rgCertEncoded != null && !encryptParam.rgCertEncoded.IsInvalid) { encodeInfo.cCertEncoded = (uint) this.Certificates.Count; encodeInfo.rgCertEncoded = encryptParam.rgCertEncoded.DangerousGetHandle(); } if (encryptParam.rgUnprotectedAttr != null && !encryptParam.rgUnprotectedAttr.IsInvalid) { encodeInfo.cUnprotectedAttr = (uint) this.UnprotectedAttributes.Count; encodeInfo.rgUnprotectedAttr = encryptParam.rgUnprotectedAttr.DangerousGetHandle(); } } else { SetPkcs7RecipientParams(recipients, ref encryptParam, out certContexts); encodeInfo.rgpRecipients = encryptParam.rgpRecipients.DangerousGetHandle(); } Marshal.StructureToPtr(encodeInfo, ceei.DangerousGetHandle(), false); try { SafeCryptMsgHandle safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, 0, CAPI.CMSG_ENVELOPED, ceei.DangerousGetHandle(), this.ContentInfo.ContentType.Value, IntPtr.Zero); if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid) throw new CryptographicException(Marshal.GetLastWin32Error()); if (m_safeCryptMsgHandle != null && !m_safeCryptMsgHandle.IsInvalid) { m_safeCryptMsgHandle.Dispose(); } m_safeCryptMsgHandle = safeCryptMsgHandle; } finally { Marshal.DestroyStructure(ceei.DangerousGetHandle(), typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO)); ceei.Dispose(); } byte[] encodedContent = new byte[0]; if (String.Compare(this.ContentInfo.ContentType.Value, CAPI.szOID_RSA_data, StringComparison.OrdinalIgnoreCase) == 0) { byte[] content = this.ContentInfo.Content; fixed (byte * pbContent = content) { CAPI.CRYPTOAPI_BLOB dataBlob = new CAPI.CRYPTOAPI_BLOB(); dataBlob.cbData = (uint) content.Length; dataBlob.pbData = new IntPtr(pbContent); if (!CAPI.EncodeObject(new IntPtr(CAPI.X509_OCTET_STRING), new IntPtr(&dataBlob), out encodedContent)) throw new CryptographicException(Marshal.GetLastWin32Error()); } } else { encodedContent = this.ContentInfo.Content; } if (encodedContent.Length > 0) { if (!CAPI.CAPISafe.CryptMsgUpdate(m_safeCryptMsgHandle, encodedContent, (uint) encodedContent.Length, true)) throw new CryptographicException(Marshal.GetLastWin32Error()); } // Keep alive GC.KeepAlive(encryptParam); GC.KeepAlive(recipients); GC.KeepAlive(certContexts); }
private static unsafe void SetPkcs7RecipientParams (CmsRecipientCollection recipients, ref CMSG_ENCRYPT_PARAM encryptParam, out List<SafeCertContextHandle> certContexts) { int index = 0; // Must read recipients.Count only once to avoid a security issue where another thread // could add objects to recipients after we allocate the native buffer, but while we're // iterating. That could lead to a buffer overflow int numRecipients = recipients.Count; certContexts = new List<SafeCertContextHandle>(); checked { uint totalSize = (uint)numRecipients * (uint)Marshal.SizeOf(typeof(IntPtr)); encryptParam.rgpRecipients = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(totalSize)); IntPtr pCertInfo = encryptParam.rgpRecipients.DangerousGetHandle(); for (index = 0; index < numRecipients; index++) { SafeCertContextHandle certContext = X509Utils.GetCertContext(recipients[index].Certificate); certContexts.Add(certContext); IntPtr dangerousCertContextHandle = certContext.DangerousGetHandle(); CAPI.CERT_CONTEXT pCertContext = (CAPI.CERT_CONTEXT) Marshal.PtrToStructure(dangerousCertContextHandle, typeof(CAPI.CERT_CONTEXT)); Marshal.WriteIntPtr(pCertInfo, pCertContext.pCertInfo); pCertInfo = new IntPtr((long) pCertInfo + Marshal.SizeOf(typeof(IntPtr))); } Debug.Assert(index == totalSize / (uint)Marshal.SizeOf(typeof(IntPtr))); } }
internal CmsRecipientEnumerator(CmsRecipientCollection recipients) { m_recipients = recipients; m_current = -1; }
private static void AssertEquals(CmsRecipientCollection c, IList<CmsRecipient> expected) { Assert.Equal(expected.Count, c.Count); for (int i = 0; i < c.Count; i++) { Assert.Equal(expected[i], c[i]); } int index = 0; foreach (CmsRecipient a in c) { Assert.Equal(expected[index++], a); } Assert.Equal(c.Count, index); ValidateEnumerator(c.GetEnumerator(), expected); ValidateEnumerator(((ICollection)c).GetEnumerator(), expected); { CmsRecipient[] dumped = new CmsRecipient[c.Count + 3]; c.CopyTo(dumped, 2); Assert.Equal(null, dumped[0]); Assert.Equal(null, dumped[1]); Assert.Equal(null, dumped[dumped.Length - 1]); Assert.Equal<CmsRecipient>(expected, dumped.Skip(2).Take(c.Count)); } { CmsRecipient[] dumped = new CmsRecipient[c.Count + 3]; ((ICollection)c).CopyTo(dumped, 2); Assert.Equal(null, dumped[0]); Assert.Equal(null, dumped[1]); Assert.Equal(null, dumped[dumped.Length - 1]); Assert.Equal<CmsRecipient>(expected, dumped.Skip(2).Take(c.Count)); } }
Stream Envelope(RealCmsRecipientCollection recipients, Stream content) { var algorithm = GetPreferredEncryptionAlgorithm(recipients); return(Envelope(recipients, content, algorithm)); }
public static void Twoary_Negative() { object ignore; Assert.Throws<NullReferenceException>(() => ignore = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, null)); }
public void Encrypt (CmsRecipientCollection recipients) { if (recipients == null) throw new ArgumentNullException ("recipients"); // ? foreach on Encrypt CmsRecipient ? }
private static void SetPkcs7RecipientParams(CmsRecipientCollection recipients, ref CMSG_ENCRYPT_PARAM encryptParam, out List<System.Security.Cryptography.SafeCertContextHandle> certContexts) { int num = 0; int count = recipients.Count; certContexts = new List<System.Security.Cryptography.SafeCertContextHandle>(); uint num3 = (uint) (count * Marshal.SizeOf(typeof(IntPtr))); encryptParam.rgpRecipients = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long) num3)); IntPtr ptr = encryptParam.rgpRecipients.DangerousGetHandle(); for (num = 0; num < count; num++) { System.Security.Cryptography.SafeCertContextHandle certContext = System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(recipients[num].Certificate); certContexts.Add(certContext); System.Security.Cryptography.CAPI.CERT_CONTEXT cert_context = (System.Security.Cryptography.CAPI.CERT_CONTEXT) Marshal.PtrToStructure(certContext.DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_CONTEXT)); Marshal.WriteIntPtr(ptr, cert_context.pCertInfo); ptr = new IntPtr(((long) ptr) + Marshal.SizeOf(typeof(IntPtr))); } }
// // This returns an allocated native memory block. Its lifetime (and that of any allocated subblocks it may point to) is that of "hb". // private static unsafe CMSG_ENVELOPED_ENCODE_INFO* CreateCmsEnvelopedEncodeInfo(CmsRecipientCollection recipients, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes, HeapBlockRetainer hb) { CMSG_ENVELOPED_ENCODE_INFO* pEnvelopedEncodeInfo = (CMSG_ENVELOPED_ENCODE_INFO*)(hb.Alloc(sizeof(CMSG_ENVELOPED_ENCODE_INFO))); pEnvelopedEncodeInfo->cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO); pEnvelopedEncodeInfo->hCryptProv = IntPtr.Zero; string algorithmOidValue = contentEncryptionAlgorithm.Oid.Value; pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(algorithmOidValue); // Desktop compat: Though it seems like we could copy over the contents of contentEncryptionAlgorithm.Parameters, that property is for retrieving information from decoded Cms's only, and it // massages the raw data so it wouldn't be usable here anyway. To hammer home that fact, the EncryptedCms constructer rather rudely forces contentEncryptionAlgorithm.Parameters to be the empty array. pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.Parameters.cbData = 0; pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.Parameters.pbData = IntPtr.Zero; pEnvelopedEncodeInfo->pvEncryptionAuxInfo = GenerateEncryptionAuxInfoIfNeeded(contentEncryptionAlgorithm, hb); int numRecipients = recipients.Count; pEnvelopedEncodeInfo->cRecipients = numRecipients; pEnvelopedEncodeInfo->rgpRecipients = IntPtr.Zero; CMSG_RECIPIENT_ENCODE_INFO* rgCmsRecipients = (CMSG_RECIPIENT_ENCODE_INFO*)(hb.Alloc(numRecipients, sizeof(CMSG_RECIPIENT_ENCODE_INFO))); for (int index = 0; index < numRecipients; index++) { rgCmsRecipients[index] = EncodeRecipientInfo(recipients[index], contentEncryptionAlgorithm, hb); } pEnvelopedEncodeInfo->rgCmsRecipients = rgCmsRecipients; int numCertificates = originatorCerts.Count; pEnvelopedEncodeInfo->cCertEncoded = numCertificates; pEnvelopedEncodeInfo->rgCertEncoded = null; if (numCertificates != 0) { DATA_BLOB* pCertEncoded = (DATA_BLOB*)(hb.Alloc(numCertificates, sizeof(DATA_BLOB))); for (int i = 0; i < numCertificates; i++) { byte[] certEncoded = originatorCerts[i].Export(X509ContentType.Cert); pCertEncoded[i].cbData = (uint)(certEncoded.Length); pCertEncoded[i].pbData = hb.AllocBytes(certEncoded); } pEnvelopedEncodeInfo->rgCertEncoded = pCertEncoded; } pEnvelopedEncodeInfo->cCrlEncoded = 0; pEnvelopedEncodeInfo->rgCrlEncoded = null; pEnvelopedEncodeInfo->cAttrCertEncoded = 0; pEnvelopedEncodeInfo->rgAttrCertEncoded = null; int numUnprotectedAttributes = unprotectedAttributes.Count; pEnvelopedEncodeInfo->cUnprotectedAttr = numUnprotectedAttributes; pEnvelopedEncodeInfo->rgUnprotectedAttr = null; if (numUnprotectedAttributes != 0) { CRYPT_ATTRIBUTE* pCryptAttribute = (CRYPT_ATTRIBUTE*)(hb.Alloc(numUnprotectedAttributes, sizeof(CRYPT_ATTRIBUTE))); for (int i = 0; i < numUnprotectedAttributes; i++) { CryptographicAttributeObject attribute = unprotectedAttributes[i]; pCryptAttribute[i].pszObjId = hb.AllocAsciiString(attribute.Oid.Value); AsnEncodedDataCollection values = attribute.Values; int numValues = values.Count; pCryptAttribute[i].cValue = numValues; DATA_BLOB* pValues = (DATA_BLOB*)(hb.Alloc(numValues, sizeof(DATA_BLOB))); for (int j = 0; j < numValues; j++) { byte[] rawData = values[j].RawData; pValues[j].cbData = (uint)(rawData.Length); pValues[j].pbData = hb.AllocBytes(rawData); } pCryptAttribute[i].rgValue = pValues; } pEnvelopedEncodeInfo->rgUnprotectedAttr = pCryptAttribute; } return pEnvelopedEncodeInfo; }
public void Encrypt(CmsRecipientCollection recipients) { if (recipients == null) { throw new ArgumentNullException("recipients"); } if (this.ContentInfo.Content.Length == 0) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Envelope_Empty_Content")); } if (recipients.Count == 0) { recipients = PkcsUtils.SelectRecipients(this.m_recipientIdentifierType); } this.EncryptContent(recipients); }
internal static string Encrypt(byte[] contentBytes, CmsMessageRecipient[] recipients, SessionState sessionState, out ErrorRecord error) { error = null; if ((contentBytes == null) || (contentBytes.Length == 0)) { return String.Empty; } // After review with the crypto board, NIST_AES256_CBC is more appropriate // than .NET's default 3DES. Also, when specified, uses szOID_RSAES_OAEP for key // encryption to prevent padding attacks. const string szOID_NIST_AES256_CBC = "2.16.840.1.101.3.4.1.42"; ContentInfo content = new ContentInfo(contentBytes); EnvelopedCms cms = new EnvelopedCms(content, new AlgorithmIdentifier( Oid.FromOidValue(szOID_NIST_AES256_CBC, OidGroup.EncryptionAlgorithm))); CmsRecipientCollection recipientCollection = new CmsRecipientCollection(); foreach (CmsMessageRecipient recipient in recipients) { // Resolve the recipient, if it hasn't been done yet. if ((recipient.Certificates != null) && (recipient.Certificates.Count == 0)) { recipient.Resolve(sessionState, ResolutionPurpose.Encryption, out error); } if (error != null) { return null; } foreach (X509Certificate2 certificate in recipient.Certificates) { recipientCollection.Add(new CmsRecipient(certificate)); } } cms.Encrypt(recipientCollection); byte[] encodedBytes = cms.Encode(); string encodedContent = CmsUtils.GetAsciiArmor(encodedBytes); return encodedContent; }
/// <summary> /// Encrypts the message and envelopes it for multiple recipients. /// </summary> /// <param name="recipients">An object containing the recipients' certificates with public keys.</param> /// <example> /// <code> /// [C#] /// /// CmsRecipientCollection recipients = new CmsRecipientCollection(); /// /// recipients.Add(new CmsRecipient(new X509Certificate2("C:\\recipient1.cer"))); /// recipients.Add(new CmsRecipient(new X509Certificate2("C:\\recipient2.cer"))); /// /// message.SmimeEnvelopeAndEncryptFor(recipients); /// </code> /// </example> public void SmimeEnvelopeAndEncryptFor(CmsRecipientCollection recipients) { string mimeString = this.ToMimeString(); byte[] toencrypt = Encoding.ASCII.GetBytes(mimeString); EnvelopedCms cms = new EnvelopedCms(new ContentInfo(toencrypt)); cms.Encrypt(recipients); MimePart envelope = new MimePart(); envelope.ContentType.MimeType = "application/pkcs7-mime"; envelope.ContentType.Parameters.Add("smime-type", "encrypted-data"); envelope.ContentType.Parameters.Add("name", "smime.p7m"); envelope.ContentDisposition.Disposition = "attachment"; envelope.ContentDisposition.FileName = "smime.p7m"; envelope.ContentTransferEncoding = ContentTransferEncoding.Base64; envelope.BinaryContent = cms.Encode(); this.PartTreeRoot = envelope; this.ContentType = this.PartTreeRoot.ContentType; this.ContentDisposition = this.PartTreeRoot.ContentDisposition; this.ContentTransferEncoding = this.PartTreeRoot.ContentTransferEncoding; }
private unsafe void EncryptContent(CmsRecipientCollection recipients) { CMSG_ENCRYPT_PARAM encryptParam = new CMSG_ENCRYPT_PARAM(); if (recipients.Count < 1) { throw new CryptographicException(-2146889717); } CmsRecipientEnumerator enumerator = recipients.GetEnumerator(); while (enumerator.MoveNext()) { CmsRecipient current = enumerator.Current; if (current.Certificate == null) { throw new ArgumentNullException(SecurityResources.GetResourceString("Cryptography_Cms_RecipientCertificateNotFound")); } if ((PkcsUtils.GetRecipientInfoType(current.Certificate) == RecipientInfoType.KeyAgreement) || (current.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)) { encryptParam.useCms = true; } } if (!encryptParam.useCms && ((this.Certificates.Count > 0) || (this.UnprotectedAttributes.Count > 0))) { encryptParam.useCms = true; } if (encryptParam.useCms && !PkcsUtils.CmsSupported()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported")); } System.Security.Cryptography.CAPI.CMSG_ENVELOPED_ENCODE_INFO structure = new System.Security.Cryptography.CAPI.CMSG_ENVELOPED_ENCODE_INFO(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_ENVELOPED_ENCODE_INFO))); System.Security.Cryptography.SafeLocalAllocHandle handle = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_ENVELOPED_ENCODE_INFO)))); SetCspParams(this.ContentEncryptionAlgorithm, ref encryptParam); structure.ContentEncryptionAlgorithm.pszObjId = this.ContentEncryptionAlgorithm.Oid.Value; if ((encryptParam.pvEncryptionAuxInfo != null) && !encryptParam.pvEncryptionAuxInfo.IsInvalid) { structure.pvEncryptionAuxInfo = encryptParam.pvEncryptionAuxInfo.DangerousGetHandle(); } structure.cRecipients = (uint) recipients.Count; List<System.Security.Cryptography.SafeCertContextHandle> certContexts = null; if (encryptParam.useCms) { SetCmsRecipientParams(recipients, this.Certificates, this.UnprotectedAttributes, this.ContentEncryptionAlgorithm, ref encryptParam); structure.rgCmsRecipients = encryptParam.rgpRecipients.DangerousGetHandle(); if ((encryptParam.rgCertEncoded != null) && !encryptParam.rgCertEncoded.IsInvalid) { structure.cCertEncoded = (uint) this.Certificates.Count; structure.rgCertEncoded = encryptParam.rgCertEncoded.DangerousGetHandle(); } if ((encryptParam.rgUnprotectedAttr != null) && !encryptParam.rgUnprotectedAttr.IsInvalid) { structure.cUnprotectedAttr = (uint) this.UnprotectedAttributes.Count; structure.rgUnprotectedAttr = encryptParam.rgUnprotectedAttr.DangerousGetHandle(); } } else { SetPkcs7RecipientParams(recipients, ref encryptParam, out certContexts); structure.rgpRecipients = encryptParam.rgpRecipients.DangerousGetHandle(); } Marshal.StructureToPtr(structure, handle.DangerousGetHandle(), false); try { System.Security.Cryptography.SafeCryptMsgHandle handle2 = System.Security.Cryptography.CAPI.CryptMsgOpenToEncode(0x10001, 0, 3, handle.DangerousGetHandle(), this.ContentInfo.ContentType.Value, IntPtr.Zero); if ((handle2 == null) || handle2.IsInvalid) { throw new CryptographicException(Marshal.GetLastWin32Error()); } if ((this.m_safeCryptMsgHandle != null) && !this.m_safeCryptMsgHandle.IsInvalid) { this.m_safeCryptMsgHandle.Dispose(); } this.m_safeCryptMsgHandle = handle2; } finally { Marshal.DestroyStructure(handle.DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CMSG_ENVELOPED_ENCODE_INFO)); handle.Dispose(); } byte[] encodedData = new byte[0]; if (string.Compare(this.ContentInfo.ContentType.Value, "1.2.840.113549.1.7.1", StringComparison.OrdinalIgnoreCase) == 0) { byte[] content = this.ContentInfo.Content; fixed (byte* numRef = content) { System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB cryptoapi_blob = new System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB { cbData = (uint) content.Length, pbData = new IntPtr((void*) numRef) }; if (!System.Security.Cryptography.CAPI.EncodeObject(new IntPtr(0x19L), new IntPtr((void*) &cryptoapi_blob), out encodedData)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } } else { encodedData = this.ContentInfo.Content; } if ((encodedData.Length > 0) && !System.Security.Cryptography.CAPI.CAPISafe.CryptMsgUpdate(this.m_safeCryptMsgHandle, encodedData, (uint) encodedData.Length, true)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } GC.KeepAlive(encryptParam); GC.KeepAlive(recipients); GC.KeepAlive(certContexts); }
/// <summary> /// /// </summary> /// <param name="message"></param> /// <param name="encryptionCertificates"></param> /// <returns></returns> internal static byte[] EncryptMessage(Byte[] message, X509Certificate2Collection encryptionCertificates) { EnvelopedCms envelopedCms = new EnvelopedCms(new ContentInfo(message)); CmsRecipientCollection recipients = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, encryptionCertificates); envelopedCms.Encrypt(recipients); return envelopedCms.Encode(); }