/// <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="System.ArgumentException"> /// Valid certificates could not be found for one or more of the <paramref name="recipients"/>. /// </exception> /// <exception cref="CertificateNotFoundException"> /// A certificate could not be found for one or more of the <paramref name="recipients"/>. /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime Encrypt(SecureMimeContext ctx, IEnumerable <MailboxAddress> recipients, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (recipients == null) { throw new ArgumentNullException(nameof(recipients)); } if (entity == null) { throw new ArgumentNullException(nameof(entity)); } using (var memory = new MemoryBlockStream()) { var options = FormatOptions.CloneDefault(); options.NewLineFormat = NewLineFormat.Dos; entity.WriteTo(options, memory); memory.Position = 0; return((ApplicationPkcs7Mime)ctx.Encrypt(recipients, memory)); } }
/// <summary> /// Cryptographically signs the specified entity. /// </summary> /// <remarks> /// <para>Signs the entity using the supplied signer and <see cref="SecureMimeContext"/>.</para> /// <para>For better interoperability with other mail clients, you should use /// <see cref="MultipartSigned.Create(SecureMimeContext, CmsSigner, MimeEntity)"/> /// instead as the multipart/signed format is supported among a much larger /// subset of mail client software.</para> /// </remarks> /// <returns>The signed entity.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</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="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 Sign(SecureMimeContext ctx, CmsSigner signer, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (signer == null) { throw new ArgumentNullException(nameof(signer)); } if (entity == null) { throw new ArgumentNullException(nameof(entity)); } using (var memory = new MemoryBlockStream()) { var options = FormatOptions.CloneDefault(); options.NewLineFormat = NewLineFormat.Dos; entity.WriteTo(options, memory); memory.Position = 0; return(ctx.EncapsulatedSign(signer, memory)); } }
static EncryptionAlgorithm[] DecodeEncryptionAlgorithms(byte[] rawData) { using (var memory = new MemoryStream(rawData, false)) { using (var asn1 = new Asn1InputStream(memory)) { var algorithms = new List <EncryptionAlgorithm> (); var sequence = asn1.ReadObject() as Asn1Sequence; if (sequence == null) { return(null); } for (int i = 0; i < sequence.Count; i++) { var identifier = AlgorithmIdentifier.GetInstance(sequence[i]); EncryptionAlgorithm algorithm; if (SecureMimeContext.TryGetEncryptionAlgorithm(identifier, out algorithm)) { algorithms.Add(algorithm); } } return(algorithms.ToArray()); } } }
/// <summary> /// Creates a new <see cref="MultipartSigned"/>. /// </summary> /// <remarks> /// Cryptographically signs the entity using the supplied signer in order /// to generate a detached signature and then adds the entity along with /// the detached signature data to a new multipart/signed part. /// </remarks> /// <returns>A new <see cref="MultipartSigned"/> instance.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</param> /// <param name="entity">The entity to sign.</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="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 MultipartSigned Create(SecureMimeContext ctx, CmsSigner signer, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (signer == null) { throw new ArgumentNullException(nameof(signer)); } if (entity == null) { throw new ArgumentNullException(nameof(entity)); } using (var memory = new MemoryBlockStream()) { var prepared = Prepare(entity, memory); memory.Position = 0; // sign the cleartext content var signature = ctx.Sign(signer, memory); return(Create(ctx, signer.DigestAlgorithm, prepared, signature)); } }
/// <summary> /// Cryptographically signs the specified entity. /// </summary> /// <remarks> /// <para>Signs the entity using the supplied signer, digest algorithm and <see cref="SecureMimeContext"/>.</para> /// <para>For better interoperability with other mail clients, you should use /// <see cref="MultipartSigned.Create(SecureMimeContext, CmsSigner, MimeEntity)"/> /// instead as the multipart/signed format is supported among a much larger /// subset of mail client software.</para> /// </remarks> /// <returns>The signed entity.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</param> /// <param name="digestAlgo">The digest algorithm to use for signing.</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="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="CertificateNotFoundException"> /// A signing certificate could not be found for <paramref name="signer"/>. /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime Sign(SecureMimeContext ctx, MailboxAddress signer, DigestAlgorithm digestAlgo, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (signer == null) { throw new ArgumentNullException("signer"); } 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.EncapsulatedSign(signer, digestAlgo, 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> /// Creates a new <see cref="MultipartSigned"/>. /// </summary> /// <remarks> /// Cryptographically signs the entity using the supplied signer in order /// to generate a detached signature and then adds the entity along with /// the detached signature data to a new multipart/signed part. /// </remarks> /// <returns>A new <see cref="MultipartSigned"/> instance.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</param> /// <param name="entity">The entity to sign.</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="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 MultipartSigned Create(SecureMimeContext ctx, CmsSigner signer, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (signer == null) { throw new ArgumentNullException("signer"); } if (entity == null) { throw new ArgumentNullException("entity"); } entity.Prepare(EncodingConstraint.SevenBit, 78); using (var memory = new MemoryBlockStream()) { using (var filtered = new FilteredStream(memory)) { // Note: see rfc3156, section 3 - second note filtered.Add(new ArmoredFromFilter()); // Note: see rfc3156, section 5.4 (this is the main difference between rfc2015 and rfc3156) filtered.Add(new TrailingWhitespaceFilter()); // Note: see rfc2015 or rfc3156, section 5.1 filtered.Add(new Unix2DosFilter()); entity.WriteTo(filtered); filtered.Flush(); } memory.Position = 0; // Note: we need to parse the modified entity structure to preserve any modifications var parser = new MimeParser(memory, MimeFormat.Entity); var parsed = parser.ParseEntity(); memory.Position = 0; // sign the cleartext content var micalg = ctx.GetDigestAlgorithmName(signer.DigestAlgorithm); var signature = ctx.Sign(signer, memory); var signed = new MultipartSigned(); // set the protocol and micalg Content-Type parameters signed.ContentType.Parameters["protocol"] = ctx.SignatureProtocol; signed.ContentType.Parameters["micalg"] = micalg; // add the modified/parsed entity as our first part signed.Add(parsed); // add the detached signature as the second part signed.Add(signature); return(signed); } }
internal RsaesOaepParameters GetRsaesOaepParameters() { if (OaepHashAlgorithm == DigestAlgorithm.Sha1) { return(new RsaesOaepParameters()); } var oid = SecureMimeContext.GetDigestOid(OaepHashAlgorithm); var hashAlgorithm = new AlgorithmIdentifier(new DerObjectIdentifier(oid), DerNull.Instance); var maskGenFunction = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgorithm); return(new RsaesOaepParameters(hashAlgorithm, maskGenFunction, RsaesOaepParameters.DefaultPSourceAlgorithm)); }
/// <summary> /// Imports the certificates contained in the content. /// </summary> /// <remarks> /// Imports the certificates contained in the content. /// </remarks> /// <param name="ctx">The S/MIME context to import certificates into.</param> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header is not "certs-only". /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public void Import(SecureMimeContext ctx) { if (SecureMimeType != SecureMimeType.CertsOnly) { throw new InvalidOperationException(); } using (var memory = new MemoryBlockStream()) { ContentObject.DecodeTo(memory); memory.Position = 0; ctx.Import(memory); } }
/// <summary> /// Import the certificates contained in the content. /// </summary> /// <param name="ctx">The S/MIME context to import certificates into.</param> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header does not support decryption. /// </exception> public void Import(SecureMimeContext ctx) { // FIXME: find out what exceptions BouncyCastle can throw... if (SecureMimeType != SecureMimeType.CertsOnly) { throw new InvalidOperationException(); } using (var memory = new MemoryStream()) { ContentObject.WriteTo(memory); memory.Position = 0; ctx.Import(memory); } }
/// <summary> /// Decrypt using the specified <see cref="CryptographyContext"/>. /// </summary> /// <returns>The decrypted <see cref="MimeKit.MimeEntity"/>.</returns> /// <param name="ctx">The S/MIME context to use for decrypting.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header does not support decryption. /// </exception> public MimeEntity Decrypt(SecureMimeContext ctx) { // FIXME: find out what exceptions BouncyCastle can throw... if (ctx == null) { throw new ArgumentNullException("ctx"); } if (SecureMimeType != SecureMimeType.EnvelopedData) { throw new InvalidOperationException(); } IList <IDigitalSignature> signatures; return(Decrypt(ctx, out signatures)); }
public SystemSecuritySigner(DkimSignatureAlgorithm algorithm, AsymmetricAlgorithm key) { rsa = key as RSACryptoServiceProvider; switch (algorithm) { case DkimSignatureAlgorithm.RsaSha256: oid = SecureMimeContext.GetDigestOid(DigestAlgorithm.Sha256); AlgorithmName = "RSASHA256"; hash = SHA256.Create(); break; default: oid = SecureMimeContext.GetDigestOid(DigestAlgorithm.Sha1); AlgorithmName = "RSASHA1"; hash = SHA1.Create(); break; } }
/// <summary> /// Decrypt the enveloped-data. /// </summary> /// <remarks> /// Decrypts the enveloped-data using the specified <see cref="SecureMimeContext"/>. /// </remarks> /// <returns>The decrypted <see cref="MimeKit.MimeEntity"/>.</returns> /// <param name="ctx">The S/MIME context to use for decrypting.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header is not "enveloped-data". /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was cancelled via the cancellation token. /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public MimeEntity Decrypt(SecureMimeContext ctx, CancellationToken cancellationToken = default(CancellationToken)) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (SecureMimeType != SecureMimeType.EnvelopedData && SecureMimeType != SecureMimeType.Unknown) { throw new InvalidOperationException(); } using (var memory = new MemoryBlockStream()) { Content.DecodeTo(memory); memory.Position = 0; return(ctx.Decrypt(memory, cancellationToken)); } }
/// <summary> /// Import the certificates contained in the application/pkcs7-mime content. /// </summary> /// <remarks> /// Imports the certificates contained in the application/pkcs7-mime content. /// </remarks> /// <param name="ctx">The S/MIME context to import certificates into.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header is not "certs-only". /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public void Import(SecureMimeContext ctx) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (SecureMimeType != SecureMimeType.CertsOnly && SecureMimeType != SecureMimeType.Unknown) { throw new InvalidOperationException(); } using (var memory = new MemoryBlockStream()) { Content.DecodeTo(memory); memory.Position = 0; ctx.Import(memory); } }
/// <summary> /// Verifies the signed-data and returns the unencapsulated <see cref="MimeKit.MimeEntity"/>. /// </summary> /// <remarks> /// Verifies the signed-data and returns the unencapsulated <see cref="MimeKit.MimeEntity"/>. /// </remarks> /// <returns>The list of digital signatures.</returns> /// <param name="ctx">The S/MIME context to use for verifying the signature.</param> /// <param name="entity">The unencapsulated entity.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header is not "signed-data". /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public DigitalSignatureCollection Verify(SecureMimeContext ctx, out MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (SecureMimeType != SecureMimeType.SignedData) { throw new InvalidOperationException(); } using (var memory = new MemoryBlockStream()) { ContentObject.DecodeTo(memory); memory.Position = 0; return(ctx.Verify(memory, out entity)); } }
/// <summary> /// Decrypts the content. /// </summary> /// <remarks> /// Decrypts the content using the specified <see cref="SecureMimeContext"/>. /// </remarks> /// <returns>The decrypted <see cref="MimeKit.MimeEntity"/>.</returns> /// <param name="ctx">The S/MIME context to use for decrypting.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header is not "enveloped-data". /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public MimeEntity Decrypt(SecureMimeContext ctx) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (SecureMimeType != SecureMimeType.EnvelopedData) { throw new InvalidOperationException(); } using (var memory = new MemoryBlockStream()) { ContentObject.DecodeTo(memory); memory.Position = 0; return(ctx.Decrypt(memory)); } }
/// <summary> /// Verify the signed-data and return the unencapsulated <see cref="MimeKit.MimeEntity"/>. /// </summary> /// <remarks> /// Verifies the signed-data and returns the unencapsulated <see cref="MimeKit.MimeEntity"/>. /// </remarks> /// <returns>The list of digital signatures.</returns> /// <param name="ctx">The S/MIME context to use for verifying the signature.</param> /// <param name="entity">The unencapsulated entity.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header is not "signed-data". /// </exception> /// <exception cref="System.FormatException"> /// The extracted content could not be parsed as a MIME entity. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was cancelled via the cancellation token. /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public DigitalSignatureCollection Verify(SecureMimeContext ctx, out MimeEntity entity, CancellationToken cancellationToken = default(CancellationToken)) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (SecureMimeType != SecureMimeType.SignedData && SecureMimeType != SecureMimeType.Unknown) { throw new InvalidOperationException(); } using (var memory = new MemoryBlockStream()) { Content.DecodeTo(memory); memory.Position = 0; return(ctx.Verify(memory, out entity, cancellationToken)); } }
/// <summary> /// Decompress the compressed-data. /// </summary> /// <remarks> /// Decompresses the compressed-data using the specified <see cref="SecureMimeContext"/>. /// </remarks> /// <returns>The decompressed <see cref="MimeKit.MimeEntity"/>.</returns> /// <param name="ctx">The S/MIME context to use for decompressing.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header is not "compressed-data". /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public MimeEntity Decompress(SecureMimeContext ctx) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (SecureMimeType != SecureMimeType.CompressedData && SecureMimeType != SecureMimeType.Unknown) { throw new InvalidOperationException(); } using (var memory = new MemoryBlockStream()) { Content.DecodeTo(memory); memory.Position = 0; return(ctx.Decompress(memory)); } }
/// <summary> /// Decrypt using the specified <see cref="CryptographyContext"/>. /// </summary> /// <returns>The decrypted <see cref="MimeKit.MimeEntity"/>.</returns> /// <param name="ctx">The S/MIME context to use for decrypting.</param> /// <param name="signatures">The list of digital signatures for this application/pkcs7-mime part.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header does not support decryption. /// </exception> public MimeEntity Decrypt(SecureMimeContext ctx, out IList <IDigitalSignature> signatures) { // FIXME: find out what exceptions BouncyCastle can throw... if (ctx == null) { throw new ArgumentNullException("ctx"); } if (SecureMimeType != SecureMimeType.EnvelopedData) { throw new InvalidOperationException(); } using (var memory = new MemoryStream()) { ContentObject.DecodeTo(memory); memory.Position = 0; return(ctx.Decrypt(memory, out signatures)); } }
/// <summary> /// Compresses the specified entity. /// </summary> /// <remarks> /// <para>Compresses the specified entity using the specified <see cref="SecureMimeContext"/>.</para> /// <para>It should be noted that this feature is not supported by most mail clients, /// even among those that support S/MIME.</para> /// </remarks> /// <returns>The compressed entity.</returns> /// <param name="ctx">The S/MIME context to use for compressing.</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="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 Compress(SecureMimeContext ctx, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (entity == null) { throw new ArgumentNullException("entity"); } using (var memory = new MemoryBlockStream()) { var options = FormatOptions.Default.Clone(); options.NewLineFormat = NewLineFormat.Dos; entity.WriteTo(options, memory); memory.Position = 0; return(ctx.Compress(memory)); } }
/// <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="ctx">The S/MIME context to use for signing and encrypting.</param> /// <param name="signer">The signer.</param> /// <param name="digestAlgo">The digest algorithm to use for signing.</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="CertificateNotFoundException"> /// <para>A signing certificate could not be found for <paramref name="signer"/>.</para> /// <para>-or-</para> /// <para>A certificate could not be found for one or more of the <paramref name="recipients"/>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime SignAndEncrypt(SecureMimeContext ctx, MailboxAddress signer, DigestAlgorithm digestAlgo, IEnumerable <MailboxAddress> 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, digestAlgo, entity))); }
/// <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 (nameof (ctx)); if (recipients == null) throw new ArgumentNullException (nameof (recipients)); if (entity == null) throw new ArgumentNullException (nameof (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> /// Compresses the specified entity. /// </summary> /// <remarks> /// <para>Compresses the specified entity using the specified <see cref="SecureMimeContext"/>.</para> /// <para>It should be noted that this feature is not supported by most mail clients, /// even among those that support S/MIME.</para> /// </remarks> /// <returns>The compressed entity.</returns> /// <param name="ctx">The S/MIME context to use for compressing.</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="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 Compress (SecureMimeContext ctx, MimeEntity entity) { if (ctx == null) throw new ArgumentNullException ("ctx"); 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.Compress (memory); } }
/// <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="digestAlgo">The digest algorithm to use for signing.</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="CertificateNotFoundException"> /// <para>A signing certificate could not be found for <paramref name="signer"/>.</para> /// <para>-or-</para> /// <para>A certificate could not be found for one or more of the <paramref name="recipients"/>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime SignAndEncrypt (SecureMimeContext ctx, MailboxAddress signer, DigestAlgorithm digestAlgo, IEnumerable<MailboxAddress> 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, digestAlgo, 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="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 the specified entity. /// </summary> /// <remarks> /// <para>Signs the entity using the supplied signer, digest algorithm and <see cref="SecureMimeContext"/>.</para> /// <para>For better interoperability with other mail clients, you should use /// <see cref="MultipartSigned.Create(SecureMimeContext, CmsSigner, MimeEntity)"/> /// instead as the multipart/signed format is supported among a much larger /// subset of mail client software.</para> /// </remarks> /// <returns>The signed entity.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</param> /// <param name="digestAlgo">The digest algorithm to use for signing.</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="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="CertificateNotFoundException"> /// A signing certificate could not be found for <paramref name="signer"/>. /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime Sign (SecureMimeContext ctx, MailboxAddress signer, DigestAlgorithm digestAlgo, MimeEntity entity) { if (ctx == null) throw new ArgumentNullException ("ctx"); if (signer == null) throw new ArgumentNullException ("signer"); 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.EncapsulatedSign (signer, digestAlgo, memory); } }
/// <summary> /// Cryptographically signs the specified entity. /// </summary> /// <remarks> /// <para>Signs the entity using the supplied signer and <see cref="SecureMimeContext"/>.</para> /// <para>For better interoperability with other mail clients, you should use /// <see cref="MultipartSigned.Create(SecureMimeContext, CmsSigner, MimeEntity)"/> /// instead as the multipart/signed format is supported among a much larger /// subset of mail client software.</para> /// </remarks> /// <returns>The signed entity.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</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="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 Sign (SecureMimeContext ctx, CmsSigner signer, MimeEntity entity) { if (ctx == null) throw new ArgumentNullException (nameof (ctx)); if (signer == null) throw new ArgumentNullException (nameof (signer)); if (entity == null) throw new ArgumentNullException (nameof (entity)); using (var memory = new MemoryBlockStream ()) { var options = FormatOptions.CloneDefault (); options.NewLineFormat = NewLineFormat.Dos; entity.WriteTo (options, memory); memory.Position = 0; return ctx.EncapsulatedSign (signer, memory); } }
/// <summary> /// Imports the certificates contained in the content. /// </summary> /// <remarks> /// Imports the certificates contained in the content. /// </remarks> /// <param name="ctx">The S/MIME context to import certificates into.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header is not "certs-only". /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public void Import (SecureMimeContext ctx) { if (ctx == null) throw new ArgumentNullException ("ctx"); if (SecureMimeType != SecureMimeType.CertsOnly) throw new InvalidOperationException (); using (var memory = new MemoryBlockStream ()) { ContentObject.DecodeTo (memory); memory.Position = 0; ctx.Import (memory); } }
/// <summary> /// Creates a new <see cref="MultipartSigned"/>. /// </summary> /// <remarks> /// Cryptographically signs the entity using the supplied signer in order /// to generate a detached signature and then adds the entity along with /// the detached signature data to a new multipart/signed part. /// </remarks> /// <returns>A new <see cref="MultipartSigned"/> instance.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</param> /// <param name="entity">The entity to sign.</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="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 MultipartSigned Create (SecureMimeContext ctx, CmsSigner signer, MimeEntity entity) { if (ctx == null) throw new ArgumentNullException ("ctx"); if (signer == null) throw new ArgumentNullException ("signer"); if (entity == null) throw new ArgumentNullException ("entity"); PrepareEntityForSigning (entity); using (var memory = new MemoryBlockStream ()) { using (var filtered = new FilteredStream (memory)) { // Note: see rfc3156, section 3 - second note filtered.Add (new ArmoredFromFilter ()); // Note: see rfc3156, section 5.4 (this is the main difference between rfc2015 and rfc3156) filtered.Add (new TrailingWhitespaceFilter ()); // Note: see rfc2015 or rfc3156, section 5.1 filtered.Add (new Unix2DosFilter ()); entity.WriteTo (filtered); filtered.Flush (); } memory.Position = 0; // Note: we need to parse the modified entity structure to preserve any modifications var parser = new MimeParser (memory, MimeFormat.Entity); var parsed = parser.ParseEntity (); memory.Position = 0; // sign the cleartext content var micalg = ctx.GetDigestAlgorithmName (signer.DigestAlgorithm); var signature = ctx.Sign (signer, memory); var signed = new MultipartSigned (); // set the protocol and micalg Content-Type parameters signed.ContentType.Parameters["protocol"] = ctx.SignatureProtocol; signed.ContentType.Parameters["micalg"] = micalg; // add the modified/parsed entity as our first part signed.Add (parsed); // add the detached signature as the second part signed.Add (signature); return signed; } }
/// <summary> /// Verifies the signed-data and returns the unencapsulated <see cref="MimeKit.MimeEntity"/>. /// </summary> /// <remarks> /// Verifies the signed-data and returns the unencapsulated <see cref="MimeKit.MimeEntity"/>. /// </remarks> /// <returns>The list of digital signatures.</returns> /// <param name="ctx">The S/MIME context to use for verifying the signature.</param> /// <param name="entity">The unencapsulated entity.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header is not "signed-data". /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public DigitalSignatureCollection Verify (SecureMimeContext ctx, out MimeEntity entity) { if (ctx == null) throw new ArgumentNullException ("ctx"); if (SecureMimeType != SecureMimeType.SignedData) throw new InvalidOperationException (); using (var memory = new MemoryBlockStream ()) { ContentObject.DecodeTo (memory); memory.Position = 0; return ctx.Verify (memory, out entity); } }
/// <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="System.ArgumentException"> /// Valid certificates could not be found for one or more of the <paramref name="recipients"/>. /// </exception> /// <exception cref="CertificateNotFoundException"> /// A certificate could not be found for one or more of the <paramref name="recipients"/>. /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime Encrypt (SecureMimeContext ctx, IEnumerable<MailboxAddress> 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 (ApplicationPkcs7Mime) ctx.Encrypt (recipients, memory); } }
/// <summary> /// Decrypts the content. /// </summary> /// <remarks> /// Decrypts the content using the specified <see cref="SecureMimeContext"/>. /// </remarks> /// <returns>The decrypted <see cref="MimeKit.MimeEntity"/>.</returns> /// <param name="ctx">The S/MIME context to use for decrypting.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The "smime-type" parameter on the Content-Type header is not "enveloped-data". /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public MimeEntity Decrypt (SecureMimeContext ctx) { if (ctx == null) throw new ArgumentNullException ("ctx"); if (SecureMimeType != SecureMimeType.EnvelopedData) throw new InvalidOperationException (); using (var memory = new MemoryBlockStream ()) { ContentObject.DecodeTo (memory); memory.Position = 0; return ctx.Decrypt (memory); } }