/// <summary> /// Encrypt the specified entity. /// </summary> /// <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> public static ApplicationPkcs7Mime Encrypt(SecureMimeContext ctx, CmsRecipientCollection recipients, MimeEntity entity) { // FIXME: find out what exceptions BouncyCastle can throw... 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 MemoryStream()) { var options = FormatOptions.Default.Clone(); options.NewLineFormat = NewLineFormat.Dos; PrepareEntityForEncrypting(entity); entity.WriteTo(options, memory); memory.Position = 0; return(ctx.Encrypt(recipients, memory)); } }
/// <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)); } }
/// <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> /// Encrypts the specified content for the specified recipients. /// </summary> /// <remarks> /// Encrypts the specified content for the specified recipients. /// </remarks> /// <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="System.Security.Cryptography.CryptographicException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public override ApplicationPkcs7Mime Encrypt(CmsRecipientCollection recipients, Stream content) { if (recipients == null) { throw new ArgumentNullException(nameof(recipients)); } if (content == null) { throw new ArgumentNullException(nameof(content)); } return(new ApplicationPkcs7Mime(SecureMimeType.EnvelopedData, Envelope(recipients, content))); }
//class VoteComparer : IComparer<int> //{ // public int Compare (int x, int y) // { // return y - x; // } //} /// <summary> /// Get 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="CryptographyContext.EnabledEncryptionAlgorithms"/>, and the /// <see cref="CryptographyContext.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(CmsRecipientCollection recipients) { var votes = new int[EncryptionAlgorithmCount]; int need = recipients.Count; foreach (var recipient in recipients) { int cast = EncryptionAlgorithmCount; foreach (var algorithm in recipient.EncryptionAlgorithms) { votes[(int)algorithm]++; } } // 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; votes[(int)EncryptionAlgorithm.TripleDes] = need; // 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); }
/// <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)); }
/// <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> public ApplicationPkcs7Mime Encrypt(CmsRecipientCollection recipients, Stream content) { // FIXME: find out what exceptions BouncyCastle can throw... if (recipients == null) { throw new ArgumentNullException("recipients"); } if (content == null) { throw new ArgumentNullException("content"); } return(new ApplicationPkcs7Mime(SecureMimeType.EnvelopedData, Envelope(recipients, content))); }
/// <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)); } }
/// <summary> /// Signs and encrypts the specified content for the specified recipients. /// </summary> /// <param name="signer">The signer.</param> /// <param name="recipients">The recipients.</param> /// <param name="content">The content.</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="content"/> is <c>null</c>.</para> /// </exception> public ApplicationPkcs7Mime SignAndEncrypt(CmsSigner signer, CmsRecipientCollection recipients, Stream content) { // FIXME: find out what exceptions BouncyCastle can throw... if (signer == null) { throw new ArgumentNullException("signer"); } if (recipients == null) { throw new ArgumentNullException("recipients"); } if (content == null) { throw new ArgumentNullException("content"); } using (var signed = Sign(signer, content, true)) { return(new ApplicationPkcs7Mime(SecureMimeType.EnvelopedData, Envelope(recipients, signed))); } }
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)); }
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); }
/// <summary> /// Encrypts the specified content for the specified recipients. /// </summary> /// <remarks> /// Encrypts the specified content for the specified recipients. /// </remarks> /// <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> public abstract ApplicationPkcs7Mime Encrypt(CmsRecipientCollection recipients, Stream content);
/// <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))); }
Stream Envelope(CmsRecipientCollection recipients, Stream content) { var algorithm = GetPreferredEncryptionAlgorithm(recipients); return(Envelope(GetRealCmsRecipients(recipients), content, algorithm)); }
public override ApplicationPkcs7Mime Encrypt(CmsRecipientCollection recipients, Stream content) { throw new NotImplementedException(); }