public virtual void TestSecureMimeEncryption() { var certificate = new X509Certificate2(Path.Combine("..", "..", "TestData", "smime", "smime.p12"), "no.secret"); var body = new TextPart("plain") { Text = "This is some cleartext that we'll end up encrypting..." }; var recipients = new CmsRecipientCollection(); recipients.Add(new CmsRecipient(certificate, SubjectIdentifierType.SubjectKeyIdentifier)); using (var ctx = CreateContext()) { var encrypted = ApplicationPkcs7Mime.Encrypt(ctx, recipients, body); Assert.AreEqual(SecureMimeType.EnvelopedData, encrypted.SecureMimeType, "S/MIME type did not match."); using (var stream = new MemoryStream()) { ctx.DecryptTo(encrypted.ContentObject.Open(), stream); stream.Position = 0; var decrypted = MimeEntity.Load(stream); Assert.IsInstanceOf <TextPart> (decrypted, "Decrypted part is not the expected type."); Assert.AreEqual(body.Text, ((TextPart)decrypted).Text, "Decrypted content is not the same as the original."); } } }
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)); AssertExtensions.Throws <ArgumentException>(null, () => 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)); AssertExtensions.Throws <ArgumentException>(null, () => ic.CopyTo(a, 1)); AssertExtensions.Throws <ArgumentException>(null, () => ic.CopyTo(new CmsRecipient[2, 2], 1)); Assert.Throws <InvalidCastException>(() => ic.CopyTo(new int[10], 1)); if (PlatformDetection.IsNonZeroLowerBoundArraySupported) { // 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)); } }
/// <summary> /// Encrypt data for the specified set of certificates. /// Adapted from http://msdn.microsoft.com/en-us/library/bb924547.aspx /// </summary> /// <param name="msg">Data to encrypt</param> /// <param name="recipientCerts">Certificates to encrypt for</param> /// <returns>Encrypted blob</returns> static public byte[] EncryptMsg( Byte[] msg, X509Certificate2Collection recipientCerts) { // Place the message in a ContentInfo object. // This is required to build an EnvelopedCms object. ContentInfo contentInfo = new ContentInfo(msg); // Instantiate an EnvelopedCms object with the ContentInfo // above. // Has default SubjectIdentifierType IssuerAndSerialNumber. // Has default ContentEncryptionAlgorithm property value // RSA_DES_EDE3_CBC. EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo); // Formulate a CmsRecipient object collection that // represent information about the recipients // to encrypt the message for. CmsRecipientCollection recips = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, recipientCerts); // Encrypt the message for the recipient. envelopedCms.Encrypt(recips); // The encoded EnvelopedCms message contains the message // ciphertext and the information about each recipient // that the message was enveloped for. return(envelopedCms.Encode()); }
public static void Oneary() { CmsRecipient a0 = s_cr0; CmsRecipientCollection c = new CmsRecipientCollection(a0); AssertEquals(c, new CmsRecipient[] { a0 }); }
public static void RemoveNonExistent() { CmsRecipientCollection c = new CmsRecipientCollection(); CmsRecipient a0 = s_cr0; c.Remove(a0); // You can "remove" items that aren't in the collection - this is defined as a NOP. }
public static void MultipleRecipientIdentifiers_RoundTrip() { ContentInfo contentInfo = new ContentInfo(new byte[] { 1, 2, 3 }); EnvelopedCms ecms = new EnvelopedCms(contentInfo); CmsRecipientCollection recipients = new CmsRecipientCollection(); using (X509Certificate2 issuerSerialCert = Certificates.RSAKeyTransfer1.GetCertificate()) using (X509Certificate2 explicitSkiCert = Certificates.RSAKeyTransfer_ExplicitSki.GetCertificate()) { // CmsRecipients have different identifiers to test multiple identifier encryption. recipients.Add(new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerialCert)); recipients.Add(new CmsRecipient(SubjectIdentifierType.SubjectKeyIdentifier, explicitSkiCert)); ecms.Encrypt(recipients); } byte[] encodedMessage = ecms.Encode(); ecms = new EnvelopedCms(); ecms.Decode(encodedMessage); // Try decoding it, doesn't really matter with which cert you want to do it as it's not what this // test aims for. using (X509Certificate2 privateCert = Certificates.RSAKeyTransfer_ExplicitSki.TryGetCertificateWithPrivateKey()) { if (privateCert == null) { return; // CertLoader can't load the private certificate. } ecms.Decrypt(new X509Certificate2Collection(privateCert)); } Assert.Equal(contentInfo.ContentType.Value, ecms.ContentInfo.ContentType.Value); Assert.Equal <byte>(contentInfo.Content, ecms.ContentInfo.Content); }
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 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)); }
public void EnvelopedCmsRecipientCollectionNull() { EnvelopedCms ep = new EnvelopedCms(); CmsRecipientCollection p7rc = null; // do not confuse compiler ep.Encrypt(p7rc); }
static void Main (string[] args) { // Select a binary file var dialog = new OpenFileDialog { Filter = "All files (*.*)|*.*", InitialDirectory = "./", Title = "Select a text file" }; var filename = (dialog.ShowDialog () == DialogResult.OK) ? dialog.FileName : null; var certificate2 = new X509Certificate2 ("c:/temp1/cert.pfx", "password"); MimeEntity body; using (var content = new MemoryStream (File.ReadAllBytes (filename))) var part = new MimePart (MimeTypes.GetMimeType (filename)) { ContentDisposition = new ContentDisposition (ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Binary, FileName = Path.GetFileName (filename), Content = new MimeContent (content) }; var recipient = new CmsRecipient (certificate2) { EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes } }; var recipients = new CmsRecipientCollection (); recipients.Add (recipient); var signer = new CmsSigner (certificate2) { DigestAlgorithm = DigestAlgorithm.Sha256 }; using (var ctx = new TemporarySecureMimeContext ()) body = ApplicationPkcs7Mime.SignAndEncrypt (ctx, signer, recipients, part); }
public override unsafe byte[] Encrypt( CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes) { byte[] encryptedContent = EncryptContent( contentInfo, contentEncryptionAlgorithm, out byte[] cek, out byte[] parameterBytes); // Pin the CEK to prevent it from getting copied during heap compaction. fixed(byte *pinnedCek = cek) { try { return(Encrypt( recipients, contentInfo, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes, encryptedContent, cek, parameterBytes)); } finally { Array.Clear(cek, 0, cek.Length); } } }
public override byte[] Encrypt( CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyPkcs); }
public sealed unsafe 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)) { encodedContent = PkcsHelpers.EncodeOctetString(contentInfo.Content); }
/// <summary> /// Шифрует сообщение /// </summary> /// <param name="msg">Сообщение</param> /// <param name="recipientCerts">Сертификат</param> /// <returns>Результат шифровки</returns> public static byte[] EncryptMsg(Byte[] msg, X509Certificate2Collection recipientCerts) { ContentInfo contentInfo = new ContentInfo(msg); EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo); CmsRecipientCollection recips = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, recipientCerts); envelopedCms.Encrypt(recips); return(envelopedCms.Encode()); }
public sealed unsafe 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) { // Windows will throw if it encounters indefinite length encoding. // Let's reencode if that is the case ReencodeIfUsingIndefiniteLengthEncodingOnOuterStructure(ref encodedContent); } } if (encodedContent.Length > 0) { // Pin to avoid copy during heap compaction fixed(byte *pinnedContent = encodedContent) { try { if (!Interop.Crypt32.CryptMsgUpdate(hCryptMsg, encodedContent, encodedContent.Length, fFinal: true)) { throw Marshal.GetLastWin32Error().ToCryptographicException(); } } finally { if (!object.ReferenceEquals(encodedContent, contentInfo.Content)) { Array.Clear(encodedContent, 0, encodedContent.Length); } } } } byte[] encodedMessage = hCryptMsg.GetMsgParamAsByteArray(CryptMsgParamType.CMSG_CONTENT_PARAM); return(encodedMessage); } }
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> /// /// </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()); }
/// <summary> /// CMS encryption of a data /// </summary> /// <param name="data">Data to encrypt</param> /// <param name="encryptionCertificates">A list of certificates to encrypt the data with</param> /// <returns>The encrypted data</returns> internal static byte[] Encrypt(string data, X509Certificate2Collection encryptionCertificates) { byte[] messageBytes = Encoding.ASCII.GetBytes(data); var envelopedCms = new EnvelopedCms(new ContentInfo(messageBytes)); var recipients = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, encryptionCertificates); envelopedCms.Encrypt(recipients); return(envelopedCms.Encode()); }
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); }
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 void TestArgumentExceptions() { var stream = new MemoryStream(); Assert.Throws <ArgumentNullException> (() => new ApplicationPkcs7Signature((MimeEntityConstructorArgs)null)); Assert.Throws <ArgumentNullException> (() => new ApplicationPkcs7Mime((MimeEntityConstructorArgs)null)); Assert.Throws <ArgumentNullException> (() => new ApplicationPkcs7Signature((Stream)null)); // Accept Assert.Throws <ArgumentNullException> (() => new ApplicationPkcs7Mime(SecureMimeType.SignedData, stream).Accept(null)); Assert.Throws <ArgumentNullException> (() => new ApplicationPkcs7Signature(stream).Accept(null)); using (var ctx = CreateContext()) { var signer = new CmsSigner(Path.Combine("..", "..", "TestData", "smime", "smime.p12"), "no.secret"); var mailbox = new MailboxAddress("Unit Tests", "*****@*****.**"); var recipients = new CmsRecipientCollection(); DigitalSignatureCollection signatures; MimeEntity entity; Assert.Throws <ArgumentNullException> (() => ctx.CanSign(null)); Assert.Throws <ArgumentNullException> (() => ctx.CanEncrypt(null)); Assert.Throws <ArgumentNullException> (() => ctx.Compress(null)); Assert.Throws <ArgumentNullException> (() => ctx.Decompress(null)); Assert.Throws <ArgumentNullException> (() => ctx.DecompressTo(null, stream)); Assert.Throws <ArgumentNullException> (() => ctx.DecompressTo(stream, null)); Assert.Throws <ArgumentNullException> (() => ctx.Decrypt(null)); Assert.Throws <ArgumentNullException> (() => ctx.DecryptTo(null, stream)); Assert.Throws <ArgumentNullException> (() => ctx.DecryptTo(stream, null)); Assert.Throws <ArgumentNullException> (() => ctx.EncapsulatedSign(null, stream)); Assert.Throws <ArgumentNullException> (() => ctx.EncapsulatedSign(signer, null)); Assert.Throws <ArgumentNullException> (() => ctx.EncapsulatedSign(null, DigestAlgorithm.Sha256, stream)); Assert.Throws <ArgumentNullException> (() => ctx.EncapsulatedSign(mailbox, DigestAlgorithm.Sha256, null)); Assert.Throws <ArgumentNullException> (() => ctx.Encrypt((CmsRecipientCollection)null, stream)); Assert.Throws <ArgumentNullException> (() => ctx.Encrypt(recipients, null)); Assert.Throws <ArgumentNullException> (() => ctx.Encrypt((IEnumerable <MailboxAddress>)null, stream)); Assert.Throws <ArgumentNullException> (() => ctx.Encrypt(new MailboxAddress[0], null)); Assert.Throws <ArgumentNullException> (() => ctx.Export(null)); Assert.Throws <ArgumentNullException> (() => ctx.GetDigestAlgorithm(null)); Assert.Throws <ArgumentNullException> (() => ctx.Import((Stream)null)); Assert.Throws <ArgumentNullException> (() => ctx.Import(stream, null)); Assert.Throws <ArgumentNullException> (() => ctx.Import((X509Crl)null)); Assert.Throws <ArgumentNullException> (() => ctx.Import((X509Certificate)null)); Assert.Throws <ArgumentNullException> (() => ctx.Sign(null, stream)); Assert.Throws <ArgumentNullException> (() => ctx.Sign(signer, null)); Assert.Throws <ArgumentNullException> (() => ctx.Sign(null, DigestAlgorithm.Sha256, stream)); Assert.Throws <ArgumentNullException> (() => ctx.Sign(mailbox, DigestAlgorithm.Sha256, null)); Assert.Throws <ArgumentNullException> (() => ctx.Verify(null, stream)); Assert.Throws <ArgumentNullException> (() => ctx.Verify(stream, null)); Assert.Throws <ArgumentNullException> (() => ctx.Verify(null, out signatures)); Assert.Throws <ArgumentNullException> (() => ctx.Verify(null, out entity)); } }
public static CmsRecipientCollection DeepCopy(this CmsRecipientCollection recipients) { CmsRecipientCollection recipientsCopy = new CmsRecipientCollection(); foreach (CmsRecipient recipient in recipients) { X509Certificate2 originalCert = recipient.Certificate; X509Certificate2 certCopy = new X509Certificate2(originalCert.Handle); CmsRecipient recipientCopy = new CmsRecipient(recipient.RecipientIdentifierType, certCopy); recipientsCopy.Add(recipientCopy); GC.KeepAlive(originalCert); } return(recipientsCopy); }
public static void DecodeRecipients3_RoundTrip() { ContentInfo contentInfo = new ContentInfo(new byte[] { 1, 2, 3 }); EnvelopedCms ecms = new EnvelopedCms(contentInfo, KeyAgreeRecipientInfoTests.TripleDesAlgId); CmsRecipientCollection recipients = new CmsRecipientCollection(); foreach (X509Certificate2 cert in s_certs) { recipients.Add(new CmsRecipient(cert)); } ecms.Encrypt(recipients); byte[] encodedMessage = ecms.Encode(); VerifyRecipients3(encodedMessage); }
public static void IndexOutOfBounds() { 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); object ignore = null; Assert.Throws <ArgumentOutOfRangeException>(() => ignore = c[-1]); Assert.Throws <ArgumentOutOfRangeException>(() => ignore = c[3]); }
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 }); }
/// <summary> /// Encrypts raw data and returns a <see cref="EnvelopedCms"/> instance with the encrypted data. /// </summary> /// <param name="content">The content to encrypt</param> /// <param name="encryptingCertificates">The collection of certificate used for encrytion</param> /// <returns>The encrypted <see cref="EnvelopedCms"/> instance.</returns> public EnvelopedCms CreateEncryptedEnvelope(byte[] content, X509Certificate2Collection encryptingCertificates) { if (content == null) { throw new EncryptionException(EncryptionError.NullContent); } if (encryptingCertificates == null || encryptingCertificates.Count == 0) { throw new EncryptionException(EncryptionError.NoCertificates); } CmsRecipientCollection recipients = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, encryptingCertificates); EnvelopedCms dataEnvelope = new EnvelopedCms(CreateDataContainer(content), ToAlgorithmID(m_encryptionAlgorithm)); dataEnvelope.Encrypt(recipients); return(dataEnvelope); }
public void TestArgumentExceptions() { Assert.Throws <ArgumentNullException> (() => new CmsRecipient((X509Certificate2)null)); Assert.Throws <ArgumentNullException> (() => new CmsRecipient((X509Certificate)null)); Assert.Throws <ArgumentNullException> (() => new CmsRecipient((Stream)null)); Assert.Throws <ArgumentNullException> (() => new CmsRecipient((string)null)); var recipients = new CmsRecipientCollection(); Assert.AreEqual(0, recipients.Count); Assert.IsFalse(recipients.IsReadOnly); Assert.Throws <ArgumentNullException> (() => recipients.Add(null)); Assert.Throws <ArgumentNullException> (() => recipients.Contains(null)); Assert.Throws <ArgumentNullException> (() => recipients.CopyTo(null, 0)); Assert.Throws <ArgumentOutOfRangeException> (() => recipients.CopyTo(new CmsRecipient[1], -1)); Assert.Throws <ArgumentOutOfRangeException> (() => recipients.CopyTo(new CmsRecipient[1], 2)); Assert.Throws <ArgumentNullException> (() => recipients.Remove(null)); }
private byte[] Encrypt( CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes, byte[] encryptedContent, byte[] cek, byte[] parameterBytes) { EnvelopedDataAsn envelopedData = new EnvelopedDataAsn { EncryptedContentInfo = { ContentType = contentInfo.ContentType.Value !, ContentEncryptionAlgorithm = { Algorithm = contentEncryptionAlgorithm.Oid, Parameters = parameterBytes, },
public static byte[] Encrypt(byte[] data, params X509Certificate2[] certs) { var envelopedCms = new EnvelopedCms(new ContentInfo(data)); if (envelopedCms.ContentEncryptionAlgorithm.Oid.FriendlyName != "aes256") { // After .NET Core 3 aes256 is the standard ContentEncryptionAlgorithm, before it was 3des. throw new Exception("Only aes256 is allowed."); } var cmsRecipientCollection = new CmsRecipientCollection(); foreach (var x509Certificate2 in certs) { cmsRecipientCollection.Add(new CmsRecipient(x509Certificate2, RSAEncryptionPadding.OaepSHA512)); } envelopedCms.Encrypt(cmsRecipientCollection); return(envelopedCms.Encode()); }
public static void MultipleRecipientIdentifiers_RoundTrip_DifferingRsaPaddingModes() { ContentInfo contentInfo = new ContentInfo(new byte[] { 1, 2, 3 }); EnvelopedCms ecms = new EnvelopedCms(contentInfo); CmsRecipientCollection recipients = new CmsRecipientCollection(); using (X509Certificate2 issuerSerialCert = Certificates.RSAKeyTransfer1.GetCertificate()) using (X509Certificate2 explicitSkiCert = Certificates.RSAKeyTransfer_ExplicitSki.GetCertificate()) { // CmsRecipients have different identifiers to test multiple identifier encryption. recipients.Add(new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerialCert, RSAEncryptionPadding.OaepSHA1)); recipients.Add(new CmsRecipient(SubjectIdentifierType.SubjectKeyIdentifier, explicitSkiCert, RSAEncryptionPadding.OaepSHA256)); ecms.Encrypt(recipients); } byte[] encodedMessage = ecms.Encode(); ecms = new EnvelopedCms(); ecms.Decode(encodedMessage); using (X509Certificate2 privateIssuerSerialCert = Certificates.RSAKeyTransfer1.TryGetCertificateWithPrivateKey()) { if (privateIssuerSerialCert != null) { return; // CertLoader can't load the private certificate. } ecms.Decrypt(new X509Certificate2Collection(privateIssuerSerialCert)); } using (X509Certificate2 privateExplicitSkiCert = Certificates.RSAKeyTransfer_ExplicitSki.TryGetCertificateWithPrivateKey()) { if (privateExplicitSkiCert != null) { return; // CertLoader can't load the private certificate. } ecms.Decrypt(new X509Certificate2Collection(privateExplicitSkiCert)); } }
/// <summary> /// Encrypts the specified entity. /// </summary> /// <remarks> /// Encrypts the entity to the specified recipients using the default <see cref="SecureMimeContext"/>. /// </remarks> /// <returns>The encrypted entity.</returns> /// <param name="recipients">The recipients.</param> /// <param name="entity">The entity.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="recipients"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime Encrypt (CmsRecipientCollection recipients, MimeEntity entity) { if (recipients == null) throw new ArgumentNullException (nameof (recipients)); if (entity == null) throw new ArgumentNullException (nameof (entity)); using (var ctx = (SecureMimeContext) CryptographyContext.Create ("application/pkcs7-mime")) { return Encrypt (ctx, recipients, entity); } }
Stream Envelope(CmsRecipientCollection recipients, Stream content) { var cms = new CmsEnvelopedDataGenerator (); int count = 0; foreach (var recipient in recipients) { cms.AddKeyTransRecipient (recipient.Certificate); count++; } if (count == 0) throw new ArgumentException ("No recipients specified.", "recipients"); // FIXME: how to decide which algorithm to use? var input = new CmsProcessableInputStream (content); var envelopedData = cms.Generate (input, CmsEnvelopedGenerator.DesEde3Cbc); return new MemoryStream (envelopedData.GetEncoded (), false); }
/// <summary> /// Gets the <see cref="CmsRecipient"/>s for the specified <see cref="MimeKit.MailboxAddress"/>es. /// </summary> /// <returns>The <see cref="CmsRecipient"/>s.</returns> /// <param name="mailboxes">The mailboxes.</param> /// <exception cref="CertificateNotFoundException"> /// A certificate for one or more of the specified <paramref name="mailboxes"/> could not be found. /// </exception> protected CmsRecipientCollection GetCmsRecipients(IEnumerable<MailboxAddress> mailboxes) { var recipients = new CmsRecipientCollection (); foreach (var mailbox in mailboxes) recipients.Add (GetCmsRecipient (mailbox)); return recipients; }
/// <summary> /// Encrypt the specified content for the specified recipients. /// </summary> /// <returns>A new <see cref="MimeKit.Cryptography.ApplicationPkcs7Mime"/> instance /// containing the encrypted content.</returns> /// <param name="recipients">The recipients.</param> /// <param name="content">The content.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="recipients"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="content"/> is <c>null</c>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public ApplicationPkcs7Mime Encrypt(CmsRecipientCollection recipients, Stream content) { if (recipients == null) throw new ArgumentNullException ("recipients"); if (content == null) throw new ArgumentNullException ("content"); return new ApplicationPkcs7Mime (SecureMimeType.EnvelopedData, Envelope (recipients, content)); }
public void Encrypt(CmsRecipientCollection recipients) {}
/// <summary> /// The <see cref="M:System.Security.Cryptography.Pkcs.EnvelopedCms.Encrypt(System.Security.Cryptography.Pkcs.CmsRecipientCollection)"/> method encrypts the contents of the CMS/PKCS #7 message by using the information for the specified list of recipients. The message is encrypted by using a message encryption key with a symmetric encryption algorithm such as triple DES. The message encryption key is then encrypted with the public key of each recipient. /// </summary> /// <param name="recipients">A <see cref="T:System.Security.Cryptography.Pkcs.CmsRecipientCollection"/> collection that represents the information for the list of recipients.</param><exception cref="T:System.ArgumentNullException">A null reference was passed to a method that does not accept it as a valid argument. </exception><exception cref="T:System.Security.Cryptography.CryptographicException">A cryptographic operation could not be completed.</exception> 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); }
private static unsafe void SetCmsRecipientParams(CmsRecipientCollection recipients, X509Certificate2Collection certificates, CryptographicAttributeObjectCollection unprotectedAttributes, AlgorithmIdentifier contentEncryptionAlgorithm, ref EnvelopedCms.CMSG_ENCRYPT_PARAM encryptParam) { uint[] numArray = new uint[recipients.Count]; int length = 0; int num1 = recipients.Count * Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCODE_INFO)); int num2 = num1; for (int index = 0; index < recipients.Count; ++index) { numArray[index] = (uint)PkcsUtils.GetRecipientInfoType(recipients[index].Certificate); if ((int)numArray[index] == 1) { num2 += Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO)); } else { if ((int)numArray[index] != 2) throw new CryptographicException(-2146889726); ++length; num2 += Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO)); } } encryptParam.rgpRecipients = CAPI.LocalAlloc(64U, new IntPtr(num2)); encryptParam.rgCertEncoded = SafeLocalAllocHandle.InvalidHandle; encryptParam.rgUnprotectedAttr = SafeLocalAllocHandle.InvalidHandle; encryptParam.rgSubjectKeyIdentifier = new SafeLocalAllocHandle[recipients.Count]; encryptParam.rgszObjId = new SafeLocalAllocHandle[recipients.Count]; if (length > 0) { encryptParam.rgszKeyWrapObjId = new SafeLocalAllocHandle[length]; encryptParam.rgKeyWrapAuxInfo = new SafeLocalAllocHandle[length]; encryptParam.rgEphemeralIdentifier = new SafeLocalAllocHandle[length]; encryptParam.rgszEphemeralObjId = new SafeLocalAllocHandle[length]; encryptParam.rgUserKeyingMaterial = new SafeLocalAllocHandle[length]; encryptParam.prgpEncryptedKey = new SafeLocalAllocHandle[length]; encryptParam.rgpEncryptedKey = new SafeLocalAllocHandle[length]; } if (certificates.Count > 0) { encryptParam.rgCertEncoded = CAPI.LocalAlloc(64U, new IntPtr(certificates.Count * Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB)))); for (int index = 0; index < certificates.Count; ++index) { CAPI.CERT_CONTEXT certContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(X509Utils.GetCertContext(certificates[index]).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT)); CAPI.CRYPTOAPI_BLOB* cryptoapiBlobPtr = (CAPI.CRYPTOAPI_BLOB*)(void*)new IntPtr((long)encryptParam.rgCertEncoded.DangerousGetHandle() + (long)(index * Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB)))); cryptoapiBlobPtr->cbData = certContext.cbCertEncoded; cryptoapiBlobPtr->pbData = certContext.pbCertEncoded; } } if (unprotectedAttributes.Count > 0) encryptParam.rgUnprotectedAttr = new SafeLocalAllocHandle(PkcsUtils.CreateCryptAttributes(unprotectedAttributes)); int index1 = 0; IntPtr num3 = new IntPtr((long)encryptParam.rgpRecipients.DangerousGetHandle() + (long)num1); for (int index2 = 0; index2 < recipients.Count; ++index2) { CmsRecipient cmsRecipient = recipients[index2]; X509Certificate2 certificate = cmsRecipient.Certificate; CAPI.CERT_INFO certInfo = (CAPI.CERT_INFO)Marshal.PtrToStructure(((CAPI.CERT_CONTEXT)Marshal.PtrToStructure(X509Utils.GetCertContext(certificate).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT))).pCertInfo, typeof(CAPI.CERT_INFO)); CAPI.CMSG_RECIPIENT_ENCODE_INFO* recipientEncodeInfoPtr = (CAPI.CMSG_RECIPIENT_ENCODE_INFO*)(void*)new IntPtr((long)encryptParam.rgpRecipients.DangerousGetHandle() + (long)(index2 * Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCODE_INFO)))); recipientEncodeInfoPtr->dwRecipientChoice = numArray[index2]; recipientEncodeInfoPtr->pRecipientInfo = num3; if ((int)numArray[index2] == 1) { Marshal.WriteInt32(new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "cbSize")), Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO))); IntPtr num4 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm")); byte[] bytes = Encoding.ASCII.GetBytes(certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId); encryptParam.rgszObjId[index2] = CAPI.LocalAlloc(64U, new IntPtr(bytes.Length + 1)); Marshal.Copy(bytes, 0, encryptParam.rgszObjId[index2].DangerousGetHandle(), bytes.Length); Marshal.WriteIntPtr(new IntPtr((long)num4 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")), encryptParam.rgszObjId[index2].DangerousGetHandle()); IntPtr num5 = new IntPtr((long)num4 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters")); IntPtr ptr1 = new IntPtr((long)num5 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(ptr1, (int)certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.cbData); IntPtr ptr2 = new IntPtr((long)num5 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ptr2, certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.pbData); IntPtr num6 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientPublicKey")); ptr1 = new IntPtr((long)num6 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cbData")); Marshal.WriteInt32(ptr1, (int)certInfo.SubjectPublicKeyInfo.PublicKey.cbData); ptr2 = new IntPtr((long)num6 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "pbData")); Marshal.WriteIntPtr(ptr2, certInfo.SubjectPublicKeyInfo.PublicKey.pbData); Marshal.WriteInt32(new IntPtr((long)num6 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cUnusedBits")), (int)certInfo.SubjectPublicKeyInfo.PublicKey.cUnusedBits); IntPtr num7 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientId")); if (cmsRecipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier) { uint pcbData = 0U; SafeLocalAllocHandle invalidHandle = SafeLocalAllocHandle.InvalidHandle; if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), 20U, invalidHandle, out pcbData)) throw new CryptographicException(Marshal.GetLastWin32Error()); SafeLocalAllocHandle pvData = CAPI.LocalAlloc(64U, new IntPtr((long)pcbData)); if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), 20U, pvData, out pcbData)) throw new CryptographicException(Marshal.GetLastWin32Error()); encryptParam.rgSubjectKeyIdentifier[index2] = pvData; Marshal.WriteInt32(new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice")), 2); IntPtr num8 = new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value")); ptr1 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(ptr1, (int)pcbData); ptr2 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ptr2, pvData.DangerousGetHandle()); } else { Marshal.WriteInt32(new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice")), 1); IntPtr num8 = new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value")); IntPtr num9 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer")); ptr1 = new IntPtr((long)num9 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(ptr1, (int)certInfo.Issuer.cbData); ptr2 = new IntPtr((long)num9 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ptr2, certInfo.Issuer.pbData); IntPtr num10 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber")); ptr1 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(ptr1, (int)certInfo.SerialNumber.cbData); ptr2 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ptr2, certInfo.SerialNumber.pbData); } num3 = new IntPtr((long)num3 + (long)Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO))); } else if ((int)numArray[index2] == 2) { IntPtr ptr1 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cbSize")); Marshal.WriteInt32(ptr1, Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO))); IntPtr num4 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm")); byte[] bytes1 = Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.5"); encryptParam.rgszObjId[index2] = CAPI.LocalAlloc(64U, new IntPtr(bytes1.Length + 1)); Marshal.Copy(bytes1, 0, encryptParam.rgszObjId[index2].DangerousGetHandle(), bytes1.Length); IntPtr ptr2 = new IntPtr((long)num4 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")); Marshal.WriteIntPtr(ptr2, encryptParam.rgszObjId[index2].DangerousGetHandle()); IntPtr num5 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyWrapAlgorithm")); uint num6 = X509Utils.OidToAlgId(contentEncryptionAlgorithm.Oid.Value); byte[] source = (int)num6 != 26114 ? Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.6") : Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.7"); encryptParam.rgszKeyWrapObjId[index1] = CAPI.LocalAlloc(64U, new IntPtr(source.Length + 1)); Marshal.Copy(source, 0, encryptParam.rgszKeyWrapObjId[index1].DangerousGetHandle(), source.Length); ptr2 = new IntPtr((long)num5 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")); Marshal.WriteIntPtr(ptr2, encryptParam.rgszKeyWrapObjId[index1].DangerousGetHandle()); if ((int)num6 == 26114) Marshal.WriteIntPtr(new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pvKeyWrapAuxInfo")), encryptParam.pvEncryptionAuxInfo.DangerousGetHandle()); Marshal.WriteInt32(new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "dwKeyChoice")), 1); IntPtr ptr3 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pEphemeralAlgorithmOrSenderId")); encryptParam.rgEphemeralIdentifier[index1] = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER)))); Marshal.WriteIntPtr(ptr3, encryptParam.rgEphemeralIdentifier[index1].DangerousGetHandle()); byte[] bytes2 = Encoding.ASCII.GetBytes(certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId); encryptParam.rgszEphemeralObjId[index1] = CAPI.LocalAlloc(64U, new IntPtr(bytes2.Length + 1)); Marshal.Copy(bytes2, 0, encryptParam.rgszEphemeralObjId[index1].DangerousGetHandle(), bytes2.Length); ptr2 = new IntPtr((long)encryptParam.rgEphemeralIdentifier[index1].DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")); Marshal.WriteIntPtr(ptr2, encryptParam.rgszEphemeralObjId[index1].DangerousGetHandle()); IntPtr num7 = new IntPtr((long)encryptParam.rgEphemeralIdentifier[index1].DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters")); IntPtr ptr4 = new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(ptr4, (int)certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.cbData); IntPtr ptr5 = new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ptr5, certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.pbData); Marshal.WriteInt32(new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cRecipientEncryptedKeys")), 1); encryptParam.prgpEncryptedKey[index1] = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(IntPtr)))); Marshal.WriteIntPtr(new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "rgpRecipientEncryptedKeys")), encryptParam.prgpEncryptedKey[index1].DangerousGetHandle()); encryptParam.rgpEncryptedKey[index1] = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO)))); Marshal.WriteIntPtr(encryptParam.prgpEncryptedKey[index1].DangerousGetHandle(), encryptParam.rgpEncryptedKey[index1].DangerousGetHandle()); ptr1 = new IntPtr((long)encryptParam.rgpEncryptedKey[index1].DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "cbSize")); Marshal.WriteInt32(ptr1, Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO))); IntPtr num8 = new IntPtr((long)encryptParam.rgpEncryptedKey[index1].DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientPublicKey")); ptr4 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cbData")); Marshal.WriteInt32(ptr4, (int)certInfo.SubjectPublicKeyInfo.PublicKey.cbData); ptr5 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "pbData")); Marshal.WriteIntPtr(ptr5, certInfo.SubjectPublicKeyInfo.PublicKey.pbData); Marshal.WriteInt32(new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cUnusedBits")), (int)certInfo.SubjectPublicKeyInfo.PublicKey.cUnusedBits); IntPtr num9 = new IntPtr((long)encryptParam.rgpEncryptedKey[index1].DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientId")); IntPtr ptr6 = new IntPtr((long)num9 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice")); if (cmsRecipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier) { Marshal.WriteInt32(ptr6, 2); IntPtr num10 = new IntPtr((long)num9 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value")); uint pcbData = 0U; SafeLocalAllocHandle invalidHandle = SafeLocalAllocHandle.InvalidHandle; if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), 20U, invalidHandle, out pcbData)) throw new CryptographicException(Marshal.GetLastWin32Error()); SafeLocalAllocHandle pvData = CAPI.LocalAlloc(64U, new IntPtr((long)pcbData)); if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), 20U, pvData, out pcbData)) throw new CryptographicException(Marshal.GetLastWin32Error()); encryptParam.rgSubjectKeyIdentifier[index1] = pvData; ptr4 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(ptr4, (int)pcbData); ptr5 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ptr5, pvData.DangerousGetHandle()); } else { Marshal.WriteInt32(ptr6, 1); IntPtr num10 = new IntPtr((long)num9 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value")); IntPtr num11 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer")); ptr4 = new IntPtr((long)num11 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(ptr4, (int)certInfo.Issuer.cbData); ptr5 = new IntPtr((long)num11 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ptr5, certInfo.Issuer.pbData); IntPtr num12 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber")); ptr4 = new IntPtr((long)num12 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData")); Marshal.WriteInt32(ptr4, (int)certInfo.SerialNumber.cbData); ptr5 = new IntPtr((long)num12 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData")); Marshal.WriteIntPtr(ptr5, certInfo.SerialNumber.pbData); } ++index1; num3 = new IntPtr((long)num3 + (long)Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO))); } } }
private static void SetPkcs7RecipientParams(CmsRecipientCollection recipients, ref EnvelopedCms.CMSG_ENCRYPT_PARAM encryptParam) { uint num = (uint)(recipients.Count * Marshal.SizeOf(typeof(IntPtr))); encryptParam.rgpRecipients = CAPI.LocalAlloc(64U, new IntPtr((long)num)); IntPtr ptr = encryptParam.rgpRecipients.DangerousGetHandle(); for (int index = 0; index < recipients.Count; ++index) { CAPI.CERT_CONTEXT certContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(X509Utils.GetCertContext(recipients[index].Certificate).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT)); Marshal.WriteIntPtr(ptr, certContext.pCertInfo); ptr = new IntPtr((long)ptr + (long)Marshal.SizeOf(typeof(IntPtr))); } }
/// <summary> /// Encrypts the specified entity. /// </summary> /// <remarks> /// Encrypts the entity to the specified recipients using the supplied <see cref="SecureMimeContext"/>. /// </remarks> /// <returns>The encrypted entity.</returns> /// <param name="ctx">The S/MIME context to use for encrypting.</param> /// <param name="recipients">The recipients.</param> /// <param name="entity">The entity.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="ctx"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="recipients"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime Encrypt (SecureMimeContext ctx, CmsRecipientCollection recipients, MimeEntity entity) { if (ctx == null) throw new ArgumentNullException ("ctx"); if (recipients == null) throw new ArgumentNullException ("recipients"); if (entity == null) throw new ArgumentNullException ("entity"); using (var memory = new MemoryBlockStream ()) { var options = FormatOptions.CloneDefault (); options.NewLineFormat = NewLineFormat.Dos; entity.WriteTo (options, memory); memory.Position = 0; return ctx.Encrypt (recipients, memory); } }
private unsafe void EncryptContent(CmsRecipientCollection recipients) { EnvelopedCms.CMSG_ENCRYPT_PARAM encryptParam = new EnvelopedCms.CMSG_ENCRYPT_PARAM(); if (recipients.Count < 1) throw new CryptographicException(-2146889717); foreach (CmsRecipient cmsRecipient in recipients) { if (cmsRecipient.Certificate == null) throw new ArgumentNullException(SecurityResources.GetResourceString("Cryptography_Cms_RecipientCertificateNotFound")); if (PkcsUtils.GetRecipientInfoType(cmsRecipient.Certificate) == RecipientInfoType.KeyAgreement || cmsRecipient.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")); CAPI.CMSG_ENVELOPED_ENCODE_INFO envelopedEncodeInfo = new CAPI.CMSG_ENVELOPED_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO))); SafeLocalAllocHandle localAllocHandle = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO)))); EnvelopedCms.SetCspParams(this.ContentEncryptionAlgorithm, ref encryptParam); envelopedEncodeInfo.ContentEncryptionAlgorithm.pszObjId = this.ContentEncryptionAlgorithm.Oid.Value; if (encryptParam.pvEncryptionAuxInfo != null && !encryptParam.pvEncryptionAuxInfo.IsInvalid) envelopedEncodeInfo.pvEncryptionAuxInfo = encryptParam.pvEncryptionAuxInfo.DangerousGetHandle(); envelopedEncodeInfo.cRecipients = (uint)recipients.Count; if (encryptParam.useCms) { EnvelopedCms.SetCmsRecipientParams(recipients, this.Certificates, this.UnprotectedAttributes, this.ContentEncryptionAlgorithm, ref encryptParam); envelopedEncodeInfo.rgCmsRecipients = encryptParam.rgpRecipients.DangerousGetHandle(); if (encryptParam.rgCertEncoded != null && !encryptParam.rgCertEncoded.IsInvalid) { envelopedEncodeInfo.cCertEncoded = (uint)this.Certificates.Count; envelopedEncodeInfo.rgCertEncoded = encryptParam.rgCertEncoded.DangerousGetHandle(); } if (encryptParam.rgUnprotectedAttr != null && !encryptParam.rgUnprotectedAttr.IsInvalid) { envelopedEncodeInfo.cUnprotectedAttr = (uint)this.UnprotectedAttributes.Count; envelopedEncodeInfo.rgUnprotectedAttr = encryptParam.rgUnprotectedAttr.DangerousGetHandle(); } } else { EnvelopedCms.SetPkcs7RecipientParams(recipients, ref encryptParam); envelopedEncodeInfo.rgpRecipients = encryptParam.rgpRecipients.DangerousGetHandle(); } Marshal.StructureToPtr((object)envelopedEncodeInfo, localAllocHandle.DangerousGetHandle(), false); try { SafeCryptMsgHandle safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(65537U, 0U, 3U, localAllocHandle.DangerousGetHandle(), this.ContentInfo.ContentType.Value, IntPtr.Zero); if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid) throw new CryptographicException(Marshal.GetLastWin32Error()); if (this.m_safeCryptMsgHandle != null && !this.m_safeCryptMsgHandle.IsInvalid) this.m_safeCryptMsgHandle.Dispose(); this.m_safeCryptMsgHandle = safeCryptMsgHandle; } finally { Marshal.DestroyStructure(localAllocHandle.DangerousGetHandle(), typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO)); localAllocHandle.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* numPtr = content) { if (!CAPI.EncodeObject(new IntPtr(25L), new IntPtr((void*)&new CAPI.CRYPTOAPI_BLOB() { cbData = (uint)content.Length, pbData = new IntPtr((void*)numPtr) }), out encodedData)) throw new CryptographicException(Marshal.GetLastWin32Error()); } } else encodedData = this.ContentInfo.Content; if (encodedData.Length > 0 && !CAPI.CAPISafe.CryptMsgUpdate(this.m_safeCryptMsgHandle, encodedData, (uint)encodedData.Length, true)) throw new CryptographicException(Marshal.GetLastWin32Error()); GC.KeepAlive((object)encryptParam); GC.KeepAlive((object)recipients); }
public void TestArgumentExceptions () { var path = Path.Combine ("..", "..", "TestData", "smime", "smime.p12"); var entity = new TextPart ("plain") { Text = "This is some text..." }; var mailbox = new MailboxAddress ("MimeKit UnitTests", "*****@*****.**"); var recipients = new CmsRecipientCollection (); var signer = new CmsSigner (path, "no.secret"); var mailboxes = new [] { mailbox }; recipients.Add (new CmsRecipient (signer.Certificate)); using (var ctx = new TemporarySecureMimeContext ()) { using (var file = File.OpenRead (path)) ctx.Import (file, "no.secret"); // Compress Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Compress (null, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Compress (ctx, null)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Compress (null)); // Encrypt Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt (null, mailboxes, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt (null, recipients, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt (ctx, (IEnumerable<MailboxAddress>) null, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt (ctx, (CmsRecipientCollection) null, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt (ctx, recipients, null)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt (ctx, mailboxes, null)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt ((IEnumerable<MailboxAddress>) null, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt ((CmsRecipientCollection) null, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt (recipients, null)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt (mailboxes, null)); // Sign Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Sign (null, mailbox, DigestAlgorithm.Sha1, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Sign (null, signer, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Sign (ctx, (MailboxAddress) null, DigestAlgorithm.Sha1, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Sign (ctx, (CmsSigner) null, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Sign (ctx, mailbox, DigestAlgorithm.Sha1, null)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Sign (ctx, signer, null)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Sign ((MailboxAddress) null, DigestAlgorithm.Sha1, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Sign ((CmsSigner) null, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Sign (mailbox, DigestAlgorithm.Sha1, null)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.Sign (signer, null)); // SignAndEncrypt Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (null, mailbox, DigestAlgorithm.Sha1, mailboxes, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (ctx, null, DigestAlgorithm.Sha1, mailboxes, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (ctx, mailbox, DigestAlgorithm.Sha1, null, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (ctx, mailbox, DigestAlgorithm.Sha1, mailboxes, null)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (null, DigestAlgorithm.Sha1, mailboxes, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (mailbox, DigestAlgorithm.Sha1, null, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (mailbox, DigestAlgorithm.Sha1, mailboxes, null)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (null, signer, recipients, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (ctx, null, recipients, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (ctx, signer, null, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (ctx, signer, recipients, null)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (null, recipients, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (signer, null, entity)); Assert.Throws<ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt (signer, recipients, null)); var compressed = ApplicationPkcs7Mime.Compress (ctx, entity); var encrypted = ApplicationPkcs7Mime.Encrypt (recipients, entity); var signed = ApplicationPkcs7Mime.Sign (signer, entity); // Decompress Assert.Throws<ArgumentNullException> (() => compressed.Decompress (null)); Assert.Throws<InvalidOperationException> (() => encrypted.Decompress (ctx)); Assert.Throws<InvalidOperationException> (() => signed.Decompress (ctx)); // Decrypt Assert.Throws<ArgumentNullException> (() => encrypted.Decrypt (null)); Assert.Throws<InvalidOperationException> (() => compressed.Decrypt (ctx)); Assert.Throws<InvalidOperationException> (() => signed.Decrypt (ctx)); // Verify Assert.Throws<ArgumentNullException> (() => { MimeEntity mime; signed.Verify (null, out mime); }); Assert.Throws<InvalidOperationException> (() => { MimeEntity mime; compressed.Verify (ctx, out mime); }); Assert.Throws<InvalidOperationException> (() => { MimeEntity mime; encrypted.Verify (ctx, out mime); }); } }
/// <summary> /// Cryptographically signs and encrypts the specified entity. /// </summary> /// <remarks> /// Cryptographically signs entity using the supplied signer and then /// encrypts the result to the specified recipients. /// </remarks> /// <returns>The signed and encrypted entity.</returns> /// <param name="ctx">The S/MIME context to use for signing and encrypting.</param> /// <param name="signer">The signer.</param> /// <param name="recipients">The recipients.</param> /// <param name="entity">The entity.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="ctx"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="signer"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="recipients"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime SignAndEncrypt (SecureMimeContext ctx, CmsSigner signer, CmsRecipientCollection recipients, MimeEntity entity) { if (ctx == null) throw new ArgumentNullException ("ctx"); if (signer == null) throw new ArgumentNullException ("signer"); if (recipients == null) throw new ArgumentNullException ("recipients"); if (entity == null) throw new ArgumentNullException ("entity"); return Encrypt (ctx, recipients, MultipartSigned.Create (ctx, signer, entity)); }
/// <summary> /// Cryptographically signs and encrypts the specified entity. /// </summary> /// <remarks> /// Cryptographically signs entity using the supplied signer and then /// encrypts the result to the specified recipients. /// </remarks> /// <returns>The signed and encrypted entity.</returns> /// <param name="signer">The signer.</param> /// <param name="recipients">The recipients.</param> /// <param name="entity">The entity.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="signer"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="recipients"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime SignAndEncrypt (CmsSigner signer, CmsRecipientCollection recipients, MimeEntity entity) { if (signer == null) throw new ArgumentNullException ("signer"); if (recipients == null) throw new ArgumentNullException ("recipients"); if (entity == null) throw new ArgumentNullException ("entity"); using (var ctx = (SecureMimeContext) CryptographyContext.Create ("application/pkcs7-mime")) { return SignAndEncrypt (ctx, signer, recipients, entity); } }