Back to OIM Explorer

MimeKit/MimeKit.Cryptography/BouncyCastleSecureMimeContext.cs

Decompiler Source FileMimeKit.BouncyCastleSecureMimeContextDecompiled Source

4 extracted method/event/call references in BouncyCastleSecureMimeContext.

Source: F:\Claude\.tmp\oim-decompiled-full\0897_One_Identity_Manager_MimeKit.dll\MimeKit.Cryptography\BouncyCastleSecureMimeContext.cs

Source size: 46.497 characters

Interpretation

  • Decompiled source file. Use method/event registrations and call-site extraction to connect back to DialogMethod, QBMEvent, and API layers.

Relations

  • Generate: 1.2.840.113533.7.66.10 at line 965
  • UnitOfWork.Generate: 1.2.840.113533.7.66.10 at line 965
  • Generate: 1.3.6.1.4.1.188.7.1.1.2 at line 967
  • UnitOfWork.Generate: 1.3.6.1.4.1.188.7.1.1.2 at line 967

Typed Edges

  • No typed edges extracted for this source.

References

  • No direct source references extracted.

Referenced By

  • No direct source references extracted.

C# source-derived context

Generated by pattern extraction from the decompiled C# source and decompile index. This is factual source evidence, not inferred behavior.

None extracted.

Summary: classes BouncyCastleSecureMimeContext, RsaOaepAwareRecipientInfoGenerator; methods CreateWrapper, GenerateWrappedKey, Generate, CanSign, CanEncrypt, GetCertificate

Complete Source

C#1.235 lines
1using System;2using System.Collections.Generic;3using System.IO;4using System.Net.Http;5using System.Threading;6using System.Threading.Tasks;7using MimeKit.IO;8using Org.BouncyCastle.Asn1;9using Org.BouncyCastle.Asn1.Cms;10using Org.BouncyCastle.Asn1.Pkcs;11using Org.BouncyCastle.Asn1.Smime;12using Org.BouncyCastle.Asn1.X509;13using Org.BouncyCastle.Cms;14using Org.BouncyCastle.Crypto;15using Org.BouncyCastle.Crypto.Generators;16using Org.BouncyCastle.Crypto.Parameters;17using Org.BouncyCastle.Pkix;18using Org.BouncyCastle.Security;19using Org.BouncyCastle.Utilities.Collections;20using Org.BouncyCastle.X509;21using Org.BouncyCastle.X509.Extension;22using Org.BouncyCastle.X509.Store;2324namespace MimeKit.Cryptography;2526public abstract class BouncyCastleSecureMimeContext : SecureMimeContext27{28	private class RsaOaepAwareRecipientInfoGenerator : RecipientInfoGenerator29	{30		private readonly CmsRecipient recipient;3132		public RsaOaepAwareRecipientInfoGenerator(CmsRecipient recipient)33		{34			this.recipient = recipient;35		}3637		private static IWrapper CreateWrapper(AlgorithmIdentifier keyExchangeAlgorithm)38		{39			string algorithm;40			if (!keyExchangeAlgorithm.Algorithm.Id.Equals(PkcsObjectIdentifiers.IdRsaesOaep.Id, StringComparison.Ordinal))41			{42				algorithm = ((!keyExchangeAlgorithm.Algorithm.Id.Equals(PkcsObjectIdentifiers.RsaEncryption.Id, StringComparison.Ordinal)) ? keyExchangeAlgorithm.Algorithm.Id : "RSA//PKCS1Padding");43			}44			else45			{46				RsaesOaepParameters instance = RsaesOaepParameters.GetInstance(keyExchangeAlgorithm.Parameters);47				algorithm = "RSA//OAEPWITH" + DigestUtilities.GetAlgorithmName(instance.HashAlgorithm.Algorithm) + "ANDMGF1Padding";48			}49			return WrapperUtilities.GetWrapper(algorithm);50		}5152		private static byte[] GenerateWrappedKey(KeyParameter contentEncryptionKey, AlgorithmIdentifier keyEncryptionAlgorithm, AsymmetricKeyParameter publicKey, SecureRandom random)53		{54			IWrapper wrapper = CreateWrapper(keyEncryptionAlgorithm);55			byte[] key = contentEncryptionKey.GetKey();56			wrapper.Init(forWrapping: true, new ParametersWithRandom(publicKey, random));57			return wrapper.Wrap(key, 0, key.Length);58		}5960		public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)61		{62			TbsCertificateStructure tbsCertificate = recipient.Certificate.TbsCertificate;63			AsymmetricKeyParameter publicKey = recipient.Certificate.GetPublicKey();64			SubjectPublicKeyInfo subjectPublicKeyInfo = tbsCertificate.SubjectPublicKeyInfo;65			AlgorithmIdentifier keyEncryptionAlgorithm;66			if (publicKey is RsaKeyParameters)67			{68				RsaEncryptionPadding rsaEncryptionPadding = recipient.RsaEncryptionPadding;69				if ((object)rsaEncryptionPadding != null && rsaEncryptionPadding.Scheme == RsaEncryptionPaddingScheme.Oaep)70				{71					keyEncryptionAlgorithm = recipient.RsaEncryptionPadding.GetAlgorithmIdentifier();72					goto IL_0067;73				}74			}75			keyEncryptionAlgorithm = subjectPublicKeyInfo.Algorithm;76			goto IL_0067;77			IL_0067:78			byte[] contents = GenerateWrappedKey(contentEncryptionKey, keyEncryptionAlgorithm, publicKey, random);79			RecipientIdentifier rid;80			if (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)81			{82				SubjectKeyIdentifier subjectKeyIdentifier = X509ExtensionUtilities.GetSubjectKeyIdentifier(recipient.Certificate);83				rid = new RecipientIdentifier(subjectKeyIdentifier);84			}85			else86			{87				Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber id = new Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber(tbsCertificate.Issuer, tbsCertificate.SerialNumber.Value);88				rid = new RecipientIdentifier(id);89			}90			return new RecipientInfo(new KeyTransRecipientInfo(rid, keyEncryptionAlgorithm, new DerOctetString(contents)));91		}92	}9394	private static readonly X509CertStoreSelector MatchAllCertificates = new X509CertStoreSelector();9596	private static readonly string RsassaPssOid = PkcsObjectIdentifiers.IdRsassaPss.Id;9798	private static readonly HttpClient SharedHttpClient = new HttpClient();99100	protected SecureRandom RandomNumberGenerator { get; private set; }101102	public bool CheckCertificateRevocation { get; set; }103104	protected virtual HttpClient HttpClient => SharedHttpClient;105106	protected BouncyCastleSecureMimeContext()107		: this(new SecureRandom())108	{109	}110111	protected BouncyCastleSecureMimeContext(SecureRandom random)112	{113		if (random == null)114		{115			throw new ArgumentNullException("random");116		}117		RandomNumberGenerator = random;118	}119120	internal static bool CanSign(X509KeyUsageFlags keyUsage)121	{122		if (keyUsage != X509KeyUsageFlags.None)123		{124			return (keyUsage & X509KeyUsageFlags.DigitalSignature) != 0;125		}126		return true;127	}128129	internal static bool CanEncrypt(X509KeyUsageFlags keyUsage)130	{131		return true;132	}133134	protected abstract X509Certificate GetCertificate(ISelector<X509Certificate> selector);135136	protected abstract AsymmetricKeyParameter GetPrivateKey(ISelector<X509Certificate> selector);137138	protected abstract ISet<TrustAnchor> GetTrustedAnchors();139140	protected abstract IStore<X509Certificate> GetIntermediateCertificates();141142	protected abstract IStore<X509Crl> GetCertificateRevocationLists();143144	protected abstract DateTime GetNextCertificateRevocationListUpdate(X509Name issuer);145146	protected abstract CmsRecipient GetCmsRecipient(MailboxAddress mailbox);147148	protected CmsRecipientCollection GetCmsRecipients(IEnumerable<MailboxAddress> mailboxes)149	{150		if (mailboxes == null)151		{152			throw new ArgumentNullException("mailboxes");153		}154		CmsRecipientCollection cmsRecipientCollection = new CmsRecipientCollection();155		foreach (MailboxAddress mailbox in mailboxes)156		{157			cmsRecipientCollection.Add(GetCmsRecipient(mailbox));158		}159		return cmsRecipientCollection;160	}161162	protected abstract CmsSigner GetCmsSigner(MailboxAddress mailbox, DigestAlgorithm digestAlgo);163164	protected abstract void UpdateSecureMimeCapabilities(X509Certificate certificate, EncryptionAlgorithm[] algorithms, DateTime timestamp);165166	private CmsAttributeTableGenerator AddSecureMimeCapabilities(Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttributes)167	{168		SmimeCapabilitiesAttribute secureMimeCapabilitiesAttribute = GetSecureMimeCapabilitiesAttribute(includeRsaesOaep: true);169		return new DefaultSignedAttributeTableGenerator(signedAttributes.Add(secureMimeCapabilitiesAttribute.AttrType, secureMimeCapabilitiesAttribute.AttrValues[0]));170	}171172	private CmsSignedDataStreamGenerator CreateSignedDataGenerator(CmsSigner signer)173	{174		SimpleAttributeTableGenerator unsignedAttrGenerator = new SimpleAttributeTableGenerator(signer.UnsignedAttributes);175		CmsAttributeTableGenerator signedAttrGenerator = AddSecureMimeCapabilities(signer.SignedAttributes);176		CmsSignedDataStreamGenerator cmsSignedDataStreamGenerator = new CmsSignedDataStreamGenerator(RandomNumberGenerator);177		string digestOid = SecureMimeContext.GetDigestOid(signer.DigestAlgorithm);178		byte[] array = null;179		if (signer.SignerIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)180		{181			array = X509ExtensionUtilities.GetSubjectKeyIdentifier(signer.Certificate)?.GetKeyIdentifier();182		}183		if (signer.PrivateKey is RsaKeyParameters && signer.RsaSignaturePadding == RsaSignaturePadding.Pss)184		{185			if (array == null)186			{187				cmsSignedDataStreamGenerator.AddSigner(signer.PrivateKey, signer.Certificate, RsassaPssOid, digestOid, signedAttrGenerator, unsignedAttrGenerator);188			}189			else190			{191				cmsSignedDataStreamGenerator.AddSigner(signer.PrivateKey, array, RsassaPssOid, digestOid, signedAttrGenerator, unsignedAttrGenerator);192			}193		}194		else if (array == null)195		{196			cmsSignedDataStreamGenerator.AddSigner(signer.PrivateKey, signer.Certificate, digestOid, signedAttrGenerator, unsignedAttrGenerator);197		}198		else199		{200			cmsSignedDataStreamGenerator.AddSigner(signer.PrivateKey, array, digestOid, signedAttrGenerator, unsignedAttrGenerator);201		}202		cmsSignedDataStreamGenerator.AddCertificates(signer.CertificateChain);203		return cmsSignedDataStreamGenerator;204	}205206	private Stream Sign(CmsSigner signer, Stream content, bool encapsulate, CancellationToken cancellationToken)207	{208		CmsSignedDataStreamGenerator cmsSignedDataStreamGenerator = CreateSignedDataGenerator(signer);209		MemoryBlockStream memoryBlockStream = new MemoryBlockStream();210		using (Stream destination = cmsSignedDataStreamGenerator.Open(memoryBlockStream, encapsulate))211		{212			content.CopyTo(destination, 4096);213		}214		memoryBlockStream.Position = 0L;215		return memoryBlockStream;216	}217218	private async Task<Stream> SignAsync(CmsSigner signer, Stream content, bool encapsulate, CancellationToken cancellationToken)219	{220		CmsSignedDataStreamGenerator cmsSignedDataStreamGenerator = CreateSignedDataGenerator(signer);221		MemoryBlockStream memory = new MemoryBlockStream();222		using (Stream stream = cmsSignedDataStreamGenerator.Open(memory, encapsulate))223		{224			await content.CopyToAsync(stream, 4096, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);225		}226		memory.Position = 0L;227		return memory;228	}229230	public override ApplicationPkcs7Mime EncapsulatedSign(CmsSigner signer, Stream content, CancellationToken cancellationToken = default(CancellationToken))231	{232		if (signer == null)233		{234			throw new ArgumentNullException("signer");235		}236		if (content == null)237		{238			throw new ArgumentNullException("content");239		}240		Stream stream = Sign(signer, content, encapsulate: true, cancellationToken);241		return new ApplicationPkcs7Mime(SecureMimeType.SignedData, stream);242	}243244	public override async Task<ApplicationPkcs7Mime> EncapsulatedSignAsync(CmsSigner signer, Stream content, CancellationToken cancellationToken = default(CancellationToken))245	{246		if (signer == null)247		{248			throw new ArgumentNullException("signer");249		}250		if (content == null)251		{252			throw new ArgumentNullException("content");253		}254		return new ApplicationPkcs7Mime(SecureMimeType.SignedData, await SignAsync(signer, content, encapsulate: true, cancellationToken).ConfigureAwait(continueOnCapturedContext: false));255	}256257	public override ApplicationPkcs7Mime EncapsulatedSign(MailboxAddress signer, DigestAlgorithm digestAlgo, Stream content, CancellationToken cancellationToken = default(CancellationToken))258	{259		if (signer == null)260		{261			throw new ArgumentNullException("signer");262		}263		if (content == null)264		{265			throw new ArgumentNullException("content");266		}267		CmsSigner cmsSigner = GetCmsSigner(signer, digestAlgo);268		return EncapsulatedSign(cmsSigner, content, cancellationToken);269	}270271	public override Task<ApplicationPkcs7Mime> EncapsulatedSignAsync(MailboxAddress signer, DigestAlgorithm digestAlgo, Stream content, CancellationToken cancellationToken = default(CancellationToken))272	{273		if (signer == null)274		{275			throw new ArgumentNullException("signer");276		}277		if (content == null)278		{279			throw new ArgumentNullException("content");280		}281		CmsSigner cmsSigner = GetCmsSigner(signer, digestAlgo);282		return EncapsulatedSignAsync(cmsSigner, content, cancellationToken);283	}284285	public override ApplicationPkcs7Signature Sign(CmsSigner signer, Stream content, CancellationToken cancellationToken = default(CancellationToken))286	{287		if (signer == null)288		{289			throw new ArgumentNullException("signer");290		}291		if (content == null)292		{293			throw new ArgumentNullException("content");294		}295		Stream stream = Sign(signer, content, encapsulate: false, cancellationToken);296		return new ApplicationPkcs7Signature(stream);297	}298299	public override async Task<ApplicationPkcs7Signature> SignAsync(CmsSigner signer, Stream content, CancellationToken cancellationToken = default(CancellationToken))300	{301		if (signer == null)302		{303			throw new ArgumentNullException("signer");304		}305		if (content == null)306		{307			throw new ArgumentNullException("content");308		}309		return new ApplicationPkcs7Signature(await SignAsync(signer, content, encapsulate: false, cancellationToken).ConfigureAwait(continueOnCapturedContext: false));310	}311312	public override MimePart Sign(MailboxAddress signer, DigestAlgorithm digestAlgo, Stream content, CancellationToken cancellationToken = default(CancellationToken))313	{314		if (signer == null)315		{316			throw new ArgumentNullException("signer");317		}318		if (content == null)319		{320			throw new ArgumentNullException("content");321		}322		CmsSigner cmsSigner = GetCmsSigner(signer, digestAlgo);323		return Sign(cmsSigner, content, cancellationToken);324	}325326	public override async Task<MimePart> SignAsync(MailboxAddress signer, DigestAlgorithm digestAlgo, Stream content, CancellationToken cancellationToken = default(CancellationToken))327	{328		if (signer == null)329		{330			throw new ArgumentNullException("signer");331		}332		if (content == null)333		{334			throw new ArgumentNullException("content");335		}336		CmsSigner cmsSigner = GetCmsSigner(signer, digestAlgo);337		return await SignAsync(cmsSigner, content, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);338	}339340	private X509Certificate GetCertificate(IStore<X509Certificate> store, SignerID signer)341	{342		if (signer.Certificate != null)343		{344			return signer.Certificate;345		}346		IEnumerable<X509Certificate> enumerable = store.EnumerateMatches(signer);347		using (IEnumerator<X509Certificate> enumerator = enumerable.GetEnumerator())348		{349			if (enumerator.MoveNext())350			{351				return enumerator.Current;352			}353		}354		return GetCertificate(signer);355	}356357	protected IList<X509Certificate> BuildCertificateChain(X509Certificate certificate)358	{359		X509CertStoreSelector targetConstraintsCert = new X509CertStoreSelector();360		X509CertificateStore x509CertificateStore = new X509CertificateStore();361		x509CertificateStore.Add(certificate);362		ISet<TrustAnchor> trustedAnchors = GetTrustedAnchors();363		X509CertificateStore x509CertificateStore2 = new X509CertificateStore();364		foreach (TrustAnchor item in trustedAnchors)365		{366			x509CertificateStore2.Add(item.TrustedCert);367		}368		PkixBuilderParameters pkixBuilderParameters = new PkixBuilderParameters(trustedAnchors, targetConstraintsCert)369		{370			ValidityModel = 0,371			IsRevocationEnabled = false,372			Date = DateTime.UtcNow373		};374		pkixBuilderParameters.AddStoreCert(x509CertificateStore);375		IStore<X509Certificate> intermediateCertificates = GetIntermediateCertificates();376		foreach (X509Certificate item2 in intermediateCertificates.EnumerateMatches(MatchAllCertificates))377		{378			x509CertificateStore2.Add(item2);379		}380		pkixBuilderParameters.AddStoreCert(x509CertificateStore2);381		PkixCertPathBuilder pkixCertPathBuilder = new PkixCertPathBuilder();382		PkixCertPathBuilderResult pkixCertPathBuilderResult = pkixCertPathBuilder.Build(pkixBuilderParameters);383		X509Certificate[] array = new X509Certificate[pkixCertPathBuilderResult.CertPath.Certificates.Count];384		for (int i = 0; i < array.Length; i++)385		{386			array[i] = pkixCertPathBuilderResult.CertPath.Certificates[i];387		}388		return array;389	}390391	private PkixCertPath BuildCertPath(ISelector<X509Certificate> selector, ISet<TrustAnchor> anchors, IStore<X509Certificate> certificates, IStore<X509Crl> crls, X509Certificate certificate, DateTime signingTime)392	{393		X509CertificateStore x509CertificateStore = new X509CertificateStore();394		if (certificate != null)395		{396			x509CertificateStore.Add(certificate);397		}398		foreach (X509Certificate item in certificates.EnumerateMatches(null))399		{400			x509CertificateStore.Add(item);401		}402		PkixBuilderParameters pkixBuilderParameters = new PkixBuilderParameters(anchors, selector)403		{404			ValidityModel = 0,405			IsRevocationEnabled = CheckCertificateRevocation406		};407		pkixBuilderParameters.AddStoreCert(x509CertificateStore);408		pkixBuilderParameters.AddStoreCrl(crls);409		pkixBuilderParameters.AddStoreCert(GetIntermediateCertificates());410		if (CheckCertificateRevocation)411		{412			pkixBuilderParameters.AddStoreCrl(GetCertificateRevocationLists());413		}414		if (signingTime != default(DateTime))415		{416			pkixBuilderParameters.Date = signingTime;417		}418		PkixCertPathBuilder pkixCertPathBuilder = new PkixCertPathBuilder();419		PkixCertPathBuilderResult pkixCertPathBuilderResult = pkixCertPathBuilder.Build(pkixBuilderParameters);420		return pkixCertPathBuilderResult.CertPath;421	}422423	protected internal static bool TryGetDigestAlgorithm(AlgorithmIdentifier identifier, out DigestAlgorithm algorithm)424	{425		if (identifier == null)426		{427			throw new ArgumentNullException("identifier");428		}429		return SecureMimeContext.TryGetDigestAlgorithm(identifier.Algorithm.Id, out algorithm);430	}431432	protected internal static bool TryGetEncryptionAlgorithm(AlgorithmIdentifier identifier, out EncryptionAlgorithm algorithm)433	{434		if (identifier == null)435		{436			throw new ArgumentNullException("identifier");437		}438		if (identifier.Algorithm.Id == CmsEnvelopedGenerator.Aes256Cbc)439		{440			algorithm = EncryptionAlgorithm.Aes256;441			return true;442		}443		if (identifier.Algorithm.Id == CmsEnvelopedGenerator.Aes192Cbc)444		{445			algorithm = EncryptionAlgorithm.Aes192;446			return true;447		}448		if (identifier.Algorithm.Id == CmsEnvelopedGenerator.Aes128Cbc)449		{450			algorithm = EncryptionAlgorithm.Aes128;451			return true;452		}453		if (identifier.Algorithm.Id == CmsEnvelopedGenerator.Camellia256Cbc)454		{455			algorithm = EncryptionAlgorithm.Camellia256;456			return true;457		}458		if (identifier.Algorithm.Id == CmsEnvelopedGenerator.Camellia192Cbc)459		{460			algorithm = EncryptionAlgorithm.Camellia192;461			return true;462		}463		if (identifier.Algorithm.Id == CmsEnvelopedGenerator.Camellia128Cbc)464		{465			algorithm = EncryptionAlgorithm.Camellia128;466			return true;467		}468		if (identifier.Algorithm.Id == "1.2.840.113533.7.66.10")469		{470			algorithm = EncryptionAlgorithm.Cast5;471			return true;472		}473		if (identifier.Algorithm.Id == CmsEnvelopedGenerator.DesEde3Cbc)474		{475			algorithm = EncryptionAlgorithm.TripleDes;476			return true;477		}478		if (identifier.Algorithm.Id == SecureMimeContext.Blowfish.Id)479		{480			algorithm = EncryptionAlgorithm.Blowfish;481			return true;482		}483		if (identifier.Algorithm.Id == SecureMimeContext.Twofish.Id)484		{485			algorithm = EncryptionAlgorithm.Twofish;486			return true;487		}488		if (identifier.Algorithm.Id == CmsEnvelopedGenerator.SeedCbc)489		{490			algorithm = EncryptionAlgorithm.Seed;491			return true;492		}493		if (identifier.Algorithm.Id == SmimeCapability.DesCbc.Id)494		{495			algorithm = EncryptionAlgorithm.Des;496			return true;497		}498		if (identifier.Algorithm.Id == "1.3.6.1.4.1.188.7.1.1.2")499		{500			algorithm = EncryptionAlgorithm.Idea;501			return true;502		}503		if (identifier.Algorithm.Id == CmsEnvelopedGenerator.RC2Cbc)504		{505			if (identifier.Parameters is DerSequence derSequence)506			{507				DerInteger derInteger = (DerInteger)derSequence[0];508				switch (derInteger.Value.IntValue)509				{510				case 58:511					algorithm = EncryptionAlgorithm.RC2128;512					return true;513				case 120:514					algorithm = EncryptionAlgorithm.RC264;515					return true;516				case 160:517					algorithm = EncryptionAlgorithm.RC240;518					return true;519				}520			}521			else if (identifier.Parameters is DerInteger derInteger2)522			{523				switch (derInteger2.Value.IntValue)524				{525				case 128:526					algorithm = EncryptionAlgorithm.RC2128;527					return true;528				case 64:529					algorithm = EncryptionAlgorithm.RC264;530					return true;531				case 40:532					algorithm = EncryptionAlgorithm.RC240;533					return true;534				}535			}536		}537		algorithm = EncryptionAlgorithm.RC240;538		return false;539	}540541	private bool DownloadCrlOverHttp(string location, Stream stream, CancellationToken cancellationToken)542	{543		try544		{545			using (HttpResponseMessage httpResponseMessage = HttpClient.GetAsync(location, cancellationToken).GetAwaiter().GetResult())546			{547				httpResponseMessage.Content.CopyToAsync(stream, cancellationToken).GetAwaiter().GetResult();548			}549			return true;550		}551		catch552		{553			return false;554		}555	}556557	private async Task<bool> DownloadCrlOverHttpAsync(string location, Stream stream, CancellationToken cancellationToken)558	{559		_ = 1;560		try561		{562			using (HttpResponseMessage response = await HttpClient.GetAsync(location, cancellationToken).ConfigureAwait(continueOnCapturedContext: false))563			{564				await response.Content.CopyToAsync(stream, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);565			}566			return true;567		}568		catch569		{570			return false;571		}572	}573574	private static IEnumerable<string> EnumerateCrlDistributionPointUrls(X509Certificate certificate)575	{576		Asn1OctetString extensionValue = certificate.GetExtensionValue(X509Extensions.CrlDistributionPoints);577		if (extensionValue == null)578		{579			yield break;580		}581		DistributionPoint[] points = CrlDistPoint.GetInstance(extensionValue.GetOctets()).GetDistributionPoints();582		for (int i = 0; i < points.Length; i++)583		{584			GeneralName[] generalNames = GeneralNames.GetInstance(points[i].DistributionPointName.Name).GetNames();585			for (int j = 0; j < generalNames.Length; j++)586			{587				if (generalNames[j].TagNo == 6)588				{589					yield return DerIA5String.GetInstance(generalNames[j].Name).GetString();590				}591			}592		}593	}594595	private void DownloadCrls(X509Certificate certificate, CancellationToken cancellationToken)596	{597		DateTime nextCertificateRevocationListUpdate = GetNextCertificateRevocationListUpdate(certificate.IssuerDN);598		DateTime utcNow = DateTime.UtcNow;599		if (nextCertificateRevocationListUpdate > utcNow)600		{601			return;602		}603		using MemoryBlockStream memoryBlockStream = new MemoryBlockStream();604		bool flag = false;605		foreach (string item in EnumerateCrlDistributionPointUrls(certificate))606		{607			if ((item.StartsWith("https://", StringComparison.OrdinalIgnoreCase) || item.StartsWith("http://", StringComparison.OrdinalIgnoreCase)) && DownloadCrlOverHttp(item, memoryBlockStream, cancellationToken))608			{609				flag = true;610				break;611			}612		}613		if (!flag)614		{615			return;616		}617		memoryBlockStream.Position = 0L;618		X509CrlParser x509CrlParser = new X509CrlParser();619		foreach (X509Crl item2 in x509CrlParser.ReadCrls(memoryBlockStream))620		{621			Import(item2, cancellationToken);622		}623	}624625	private async Task DownloadCrlsAsync(X509Certificate certificate, CancellationToken cancellationToken)626	{627		DateTime nextCertificateRevocationListUpdate = GetNextCertificateRevocationListUpdate(certificate.IssuerDN);628		DateTime utcNow = DateTime.UtcNow;629		if (nextCertificateRevocationListUpdate > utcNow)630		{631			return;632		}633		using MemoryBlockStream stream = new MemoryBlockStream();634		bool downloaded = false;635		foreach (string item in EnumerateCrlDistributionPointUrls(certificate))636		{637			if ((item.StartsWith("https://", StringComparison.OrdinalIgnoreCase) || item.StartsWith("http://", StringComparison.OrdinalIgnoreCase)) && await DownloadCrlOverHttpAsync(item, stream, cancellationToken).ConfigureAwait(continueOnCapturedContext: false))638			{639				downloaded = true;640				break;641			}642		}643		if (!downloaded)644		{645			return;646		}647		stream.Position = 0L;648		X509CrlParser x509CrlParser = new X509CrlParser();649		foreach (X509Crl item2 in x509CrlParser.ReadCrls(stream))650		{651			await ImportAsync(item2, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);652		}653	}654655	private DigitalSignatureCollection GetDigitalSignatures(CmsSignedDataParser parser, CancellationToken cancellationToken)656	{657		IStore<X509Certificate> certificates = parser.GetCertificates();658		List<IDigitalSignature> list = new List<IDigitalSignature>();659		IStore<X509Crl> crls = parser.GetCrls();660		SignerInformationStore signerInfos = parser.GetSignerInfos();661		foreach (SignerInformation signer in signerInfos.GetSigners())662		{663			X509Certificate certificate = GetCertificate(certificates, signer.SignerID);664			SecureMimeDigitalSignature secureMimeDigitalSignature = new SecureMimeDigitalSignature(signer, certificate);665			if (CheckCertificateRevocation)666			{667				foreach (X509Certificate item in certificates.EnumerateMatches(null))668				{669					DownloadCrls(item, cancellationToken);670				}671			}672			if (certificate != null)673			{674				Import(certificate, cancellationToken);675				if (secureMimeDigitalSignature.EncryptionAlgorithms.Length != 0 && secureMimeDigitalSignature.CreationDate != default(DateTime))676				{677					UpdateSecureMimeCapabilities(certificate, secureMimeDigitalSignature.EncryptionAlgorithms, secureMimeDigitalSignature.CreationDate);678				}679			}680			ISet<TrustAnchor> trustedAnchors = GetTrustedAnchors();681			IStore<X509Certificate> intermediateCertificates = GetIntermediateCertificates();682			if (CheckCertificateRevocation)683			{684				foreach (TrustAnchor item2 in trustedAnchors)685				{686					DownloadCrls(item2.TrustedCert, cancellationToken);687				}688				foreach (X509Certificate item3 in intermediateCertificates.EnumerateMatches(MatchAllCertificates))689				{690					DownloadCrls(item3, cancellationToken);691				}692			}693			try694			{695				secureMimeDigitalSignature.Chain = BuildCertPath(signer.SignerID, trustedAnchors, certificates, crls, certificate, secureMimeDigitalSignature.CreationDate);696			}697			catch (Exception chainException)698			{699				secureMimeDigitalSignature.ChainException = chainException;700			}701			list.Add(secureMimeDigitalSignature);702		}703		return new DigitalSignatureCollection(list);704	}705706	private async Task<DigitalSignatureCollection> GetDigitalSignaturesAsync(CmsSignedDataParser parser, CancellationToken cancellationToken)707	{708		IStore<X509Certificate> certificates = parser.GetCertificates();709		List<IDigitalSignature> signatures = new List<IDigitalSignature>();710		IStore<X509Crl> crls = parser.GetCrls();711		SignerInformationStore signerInfos = parser.GetSignerInfos();712		foreach (SignerInformation signerInfo in signerInfos.GetSigners())713		{714			X509Certificate certificate = GetCertificate(certificates, signerInfo.SignerID);715			SecureMimeDigitalSignature signature = new SecureMimeDigitalSignature(signerInfo, certificate);716			if (CheckCertificateRevocation)717			{718				foreach (X509Certificate item in certificates.EnumerateMatches(null))719				{720					await DownloadCrlsAsync(item, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);721				}722			}723			if (certificate != null)724			{725				await ImportAsync(certificate, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);726				if (signature.EncryptionAlgorithms.Length != 0 && signature.CreationDate != default(DateTime))727				{728					UpdateSecureMimeCapabilities(certificate, signature.EncryptionAlgorithms, signature.CreationDate);729				}730			}731			ISet<TrustAnchor> anchors = GetTrustedAnchors();732			IStore<X509Certificate> intermediates = GetIntermediateCertificates();733			if (CheckCertificateRevocation)734			{735				foreach (TrustAnchor item2 in anchors)736				{737					await DownloadCrlsAsync(item2.TrustedCert, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);738				}739				foreach (X509Certificate item3 in intermediates.EnumerateMatches(MatchAllCertificates))740				{741					await DownloadCrlsAsync(item3, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);742				}743			}744			try745			{746				signature.Chain = BuildCertPath(signerInfo.SignerID, anchors, certificates, crls, certificate, signature.CreationDate);747			}748			catch (Exception chainException)749			{750				signature.ChainException = chainException;751			}752			signatures.Add(signature);753		}754		return new DigitalSignatureCollection(signatures);755	}756757	public override DigitalSignatureCollection Verify(Stream content, Stream signatureData, CancellationToken cancellationToken = default(CancellationToken))758	{759		if (content == null)760		{761			throw new ArgumentNullException("content");762		}763		if (signatureData == null)764		{765			throw new ArgumentNullException("signatureData");766		}767		using CmsSignedDataParser cmsSignedDataParser = new CmsSignedDataParser(new CmsTypedStream(content), signatureData);768		CmsTypedStream signedContent = cmsSignedDataParser.GetSignedContent();769		try770		{771			signedContent.ContentStream.CopyTo(Stream.Null, 4096);772		}773		finally774		{775			signedContent.ContentStream.Dispose();776		}777		return GetDigitalSignatures(cmsSignedDataParser, cancellationToken);778	}779780	public override async Task<DigitalSignatureCollection> VerifyAsync(Stream content, Stream signatureData, CancellationToken cancellationToken = default(CancellationToken))781	{782		if (content == null)783		{784			throw new ArgumentNullException("content");785		}786		if (signatureData == null)787		{788			throw new ArgumentNullException("signatureData");789		}790		using CmsSignedDataParser parser = new CmsSignedDataParser(new CmsTypedStream(content), signatureData);791		CmsTypedStream signed = parser.GetSignedContent();792		try793		{794			await signed.ContentStream.CopyToAsync(Stream.Null, 4096, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);795		}796		finally797		{798			signed.ContentStream.Dispose();799		}800		return await GetDigitalSignaturesAsync(parser, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);801	}802803	public override DigitalSignatureCollection Verify(Stream signedData, out MimeEntity entity, CancellationToken cancellationToken = default(CancellationToken))804	{805		if (signedData == null)806		{807			throw new ArgumentNullException("signedData");808		}809		using CmsSignedDataParser cmsSignedDataParser = new CmsSignedDataParser(signedData);810		CmsTypedStream signedContent = cmsSignedDataParser.GetSignedContent();811		try812		{813			entity = MimeEntity.Load(signedContent.ContentStream, cancellationToken);814			signedContent.ContentStream.CopyTo(Stream.Null, 4096);815		}816		finally817		{818			signedContent.ContentStream.Dispose();819		}820		return GetDigitalSignatures(cmsSignedDataParser, cancellationToken);821	}822823	public override Stream Verify(Stream signedData, out DigitalSignatureCollection signatures, CancellationToken cancellationToken = default(CancellationToken))824	{825		if (signedData == null)826		{827			throw new ArgumentNullException("signedData");828		}829		using CmsSignedDataParser cmsSignedDataParser = new CmsSignedDataParser(signedData);830		CmsTypedStream signedContent = cmsSignedDataParser.GetSignedContent();831		MemoryBlockStream memoryBlockStream = new MemoryBlockStream();832		try833		{834			signedContent.ContentStream.CopyTo(memoryBlockStream, 4096);835			memoryBlockStream.Position = 0L;836		}837		catch838		{839			memoryBlockStream.Dispose();840		}841		finally842		{843			signedContent.ContentStream.Dispose();844		}845		signatures = GetDigitalSignatures(cmsSignedDataParser, cancellationToken);846		return memoryBlockStream;847	}848849	private void CmsEnvelopeAddEllipticCurve(CmsEnvelopedGenerator cms, CmsRecipient recipient, X509Certificate certificate, ECKeyParameters publicKey)850	{851		ECKeyPairGenerator eCKeyPairGenerator = new ECKeyPairGenerator();852		eCKeyPairGenerator.Init(new ECKeyGenerationParameters(publicKey.Parameters, RandomNumberGenerator));853		AsymmetricCipherKeyPair asymmetricCipherKeyPair = eCKeyPairGenerator.GenerateKeyPair();854		if (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)855		{856			SubjectKeyIdentifier subjectKeyIdentifier = X509ExtensionUtilities.GetSubjectKeyIdentifier(recipient.Certificate);857			cms.AddKeyAgreementRecipient(CmsEnvelopedGenerator.ECDHSha1Kdf, asymmetricCipherKeyPair.Private, asymmetricCipherKeyPair.Public, subjectKeyIdentifier.GetKeyIdentifier(), publicKey, CmsEnvelopedGenerator.Aes128Wrap);858		}859		else860		{861			cms.AddKeyAgreementRecipient(CmsEnvelopedGenerator.ECDHSha1Kdf, asymmetricCipherKeyPair.Private, asymmetricCipherKeyPair.Public, certificate, CmsEnvelopedGenerator.Aes128Wrap);862		}863	}864865	private void AddRecipient(CmsEnvelopedGenerator cms, CmsRecipient recipient)866	{867		X509Certificate certificate = recipient.Certificate;868		AsymmetricKeyParameter publicKey = certificate.GetPublicKey();869		if (publicKey is RsaKeyParameters)870		{871			cms.AddRecipientInfoGenerator(new RsaOaepAwareRecipientInfoGenerator(recipient));872			return;873		}874		if (publicKey is ECKeyParameters publicKey2)875		{876			CmsEnvelopeAddEllipticCurve(cms, recipient, certificate, publicKey2);877			return;878		}879		string value = certificate.SubjectPublicKeyInfo.Algorithm.Algorithm.ToString();880		throw new NotSupportedException($"Unsupported type of recipient certificate: {publicKey.GetType().Name} (SubjectPublicKeyInfo OID = {value})");881	}882883	private void ValidateRecipientCertificate(X509Certificate certificate, CancellationToken cancellationToken = default(CancellationToken))884	{885		DownloadCrls(certificate, cancellationToken);886		X509CertStoreSelector targetConstraintsCert = new X509CertStoreSelector887		{888			Certificate = certificate889		};890		X509CertificateStore x509CertificateStore = new X509CertificateStore();891		x509CertificateStore.Add(certificate);892		ISet<TrustAnchor> trustedAnchors = GetTrustedAnchors();893		X509CertificateStore x509CertificateStore2 = new X509CertificateStore();894		foreach (TrustAnchor item in trustedAnchors)895		{896			DownloadCrls(item.TrustedCert, cancellationToken);897			x509CertificateStore2.Add(item.TrustedCert);898		}899		IStore<X509Certificate> intermediateCertificates = GetIntermediateCertificates();900		foreach (X509Certificate item2 in intermediateCertificates.EnumerateMatches(MatchAllCertificates))901		{902			DownloadCrls(item2, cancellationToken);903		}904		PkixBuilderParameters pkixBuilderParameters = new PkixBuilderParameters(trustedAnchors, targetConstraintsCert)905		{906			ValidityModel = 0,907			IsRevocationEnabled = true,908			Date = DateTime.UtcNow909		};910		pkixBuilderParameters.AddStoreCert(x509CertificateStore);911		pkixBuilderParameters.AddStoreCert(intermediateCertificates);912		pkixBuilderParameters.AddStoreCert(x509CertificateStore2);913		pkixBuilderParameters.AddStoreCrl(GetCertificateRevocationLists());914		PkixCertPathBuilder pkixCertPathBuilder = new PkixCertPathBuilder();915		pkixCertPathBuilder.Build(pkixBuilderParameters);916	}917918	private async Task ValidateRecipientCertificateAsync(X509Certificate certificate, CancellationToken cancellationToken = default(CancellationToken))919	{920		await DownloadCrlsAsync(certificate, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);921		X509CertStoreSelector selector = new X509CertStoreSelector922		{923			Certificate = certificate924		};925		X509CertificateStore userCertificateStore = new X509CertificateStore();926		userCertificateStore.Add(certificate);927		ISet<TrustAnchor> trustedAnchors = GetTrustedAnchors();928		X509CertificateStore anchorStore = new X509CertificateStore();929		foreach (TrustAnchor anchor in trustedAnchors)930		{931			await DownloadCrlsAsync(anchor.TrustedCert, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);932			anchorStore.Add(anchor.TrustedCert);933		}934		IStore<X509Certificate> intermediateStore = GetIntermediateCertificates();935		foreach (X509Certificate item in intermediateStore.EnumerateMatches(MatchAllCertificates))936		{937			await DownloadCrlsAsync(item, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);938		}939		PkixBuilderParameters pkixBuilderParameters = new PkixBuilderParameters(trustedAnchors, selector)940		{941			ValidityModel = 0,942			IsRevocationEnabled = true,943			Date = DateTime.UtcNow944		};945		pkixBuilderParameters.AddStoreCert(userCertificateStore);946		pkixBuilderParameters.AddStoreCert(intermediateStore);947		pkixBuilderParameters.AddStoreCert(anchorStore);948		pkixBuilderParameters.AddStoreCrl(GetCertificateRevocationLists());949		PkixCertPathBuilder pkixCertPathBuilder = new PkixCertPathBuilder();950		pkixCertPathBuilder.Build(pkixBuilderParameters);951	}952953	private Stream Envelope(CmsEnvelopedDataGenerator cms, EncryptionAlgorithm algorithm, Stream content, CancellationToken cancellationToken)954	{955		CmsProcessableInputStream content2 = new CmsProcessableInputStream(content);956		return new MemoryStream((algorithm switch957		{958			EncryptionAlgorithm.Aes128 => cms.Generate(content2, CmsEnvelopedGenerator.Aes128Cbc), 959			EncryptionAlgorithm.Aes192 => cms.Generate(content2, CmsEnvelopedGenerator.Aes192Cbc), 960			EncryptionAlgorithm.Aes256 => cms.Generate(content2, CmsEnvelopedGenerator.Aes256Cbc), 961			EncryptionAlgorithm.Blowfish => cms.Generate(content2, SecureMimeContext.Blowfish.Id), 962			EncryptionAlgorithm.Camellia128 => cms.Generate(content2, CmsEnvelopedGenerator.Camellia128Cbc), 963			EncryptionAlgorithm.Camellia192 => cms.Generate(content2, CmsEnvelopedGenerator.Camellia192Cbc), 964			EncryptionAlgorithm.Camellia256 => cms.Generate(content2, CmsEnvelopedGenerator.Camellia256Cbc), 965			EncryptionAlgorithm.Cast5 => cms.Generate(content2, "1.2.840.113533.7.66.10"), 966			EncryptionAlgorithm.Des => cms.Generate(content2, SmimeCapability.DesCbc.Id), 967			EncryptionAlgorithm.Idea => cms.Generate(content2, "1.3.6.1.4.1.188.7.1.1.2"), 968			EncryptionAlgorithm.RC240 => cms.Generate(content2, CmsEnvelopedGenerator.RC2Cbc, 40), 969			EncryptionAlgorithm.RC264 => cms.Generate(content2, CmsEnvelopedGenerator.RC2Cbc, 64), 970			EncryptionAlgorithm.RC2128 => cms.Generate(content2, CmsEnvelopedGenerator.RC2Cbc, 128), 971			EncryptionAlgorithm.Seed => cms.Generate(content2, CmsEnvelopedGenerator.SeedCbc), 972			EncryptionAlgorithm.TripleDes => cms.Generate(content2, CmsEnvelopedGenerator.DesEde3Cbc), 973			_ => throw new NotSupportedException($"The {algorithm} encryption algorithm is not supported by the {GetType().Name}."), 974		}).GetEncoded(), writable: false);975	}976977	private void AddCmsRecipients(CmsEnvelopedGenerator cms, CmsRecipientCollection recipients, CancellationToken cancellationToken)978	{979		HashSet<X509Certificate> hashSet = new HashSet<X509Certificate>();980		foreach (CmsRecipient recipient in recipients)981		{982			if (hashSet.Add(recipient.Certificate))983			{984				if (CheckCertificateRevocation)985				{986					ValidateRecipientCertificate(recipient.Certificate, cancellationToken);987				}988				AddRecipient(cms, recipient);989			}990		}991	}992993	private async Task AddCmsRecipientsAsync(CmsEnvelopedGenerator cms, CmsRecipientCollection recipients, CancellationToken cancellationToken)994	{995		HashSet<X509Certificate> unique = new HashSet<X509Certificate>();996		foreach (CmsRecipient recipient in recipients)997		{998			if (unique.Add(recipient.Certificate))999			{1000				if (CheckCertificateRevocation)1001				{1002					await ValidateRecipientCertificateAsync(recipient.Certificate, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);1003				}1004				AddRecipient(cms, recipient);1005			}1006		}1007	}10081009	private ApplicationPkcs7Mime Envelope(CmsRecipientCollection recipients, Stream content, CancellationToken cancellationToken)1010	{1011		EncryptionAlgorithm preferredEncryptionAlgorithm = GetPreferredEncryptionAlgorithm(recipients);1012		CmsEnvelopedDataGenerator cms = new CmsEnvelopedDataGenerator(RandomNumberGenerator);1013		AddCmsRecipients(cms, recipients, cancellationToken);1014		Stream stream = Envelope(cms, preferredEncryptionAlgorithm, content, cancellationToken);1015		return new ApplicationPkcs7Mime(SecureMimeType.EnvelopedData, stream);1016	}10171018	private async Task<ApplicationPkcs7Mime> EnvelopeAsync(CmsRecipientCollection recipients, Stream content, CancellationToken cancellationToken)1019	{1020		EncryptionAlgorithm algorithm = GetPreferredEncryptionAlgorithm(recipients);1021		MemoryBlockStream memory = null;1022		if ((!(content is MemoryBlockStream) && !(content is MemoryStream)) || 1 == 0)1023		{1024			memory = new MemoryBlockStream();1025			try1026			{1027				await content.CopyToAsync(memory, 4096, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);1028				memory.Position = 0L;1029			}1030			catch1031			{1032				memory.Dispose();1033				throw;1034			}1035			content = memory;1036		}1037		try1038		{1039			CmsEnvelopedDataGenerator cms = new CmsEnvelopedDataGenerator(RandomNumberGenerator);1040			await AddCmsRecipientsAsync(cms, recipients, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);1041			Stream stream = Envelope(cms, algorithm, content, cancellationToken);1042			return new ApplicationPkcs7Mime(SecureMimeType.EnvelopedData, stream);1043		}1044		finally1045		{1046			memory?.Dispose();1047		}1048	}10491050	public override ApplicationPkcs7Mime Encrypt(CmsRecipientCollection recipients, Stream content, CancellationToken cancellationToken = default(CancellationToken))1051	{1052		if (recipients == null)1053		{1054			throw new ArgumentNullException("recipients");1055		}1056		if (recipients.Count == 0)1057		{1058			throw new ArgumentException("No recipients specified.", "recipients");1059		}1060		if (content == null)1061		{1062			throw new ArgumentNullException("content");1063		}1064		return Envelope(recipients, content, cancellationToken);1065	}10661067	public override Task<ApplicationPkcs7Mime> EncryptAsync(CmsRecipientCollection recipients, Stream content, CancellationToken cancellationToken = default(CancellationToken))1068	{1069		if (recipients == null)1070		{1071			throw new ArgumentNullException("recipients");1072		}1073		if (recipients.Count == 0)1074		{1075			throw new ArgumentException("No recipients specified.", "recipients");1076		}1077		if (content == null)1078		{1079			throw new ArgumentNullException("content");1080		}1081		return EnvelopeAsync(recipients, content, cancellationToken);1082	}10831084	public override MimePart Encrypt(IEnumerable<MailboxAddress> recipients, Stream content, CancellationToken cancellationToken = default(CancellationToken))1085	{1086		if (recipients == null)1087		{1088			throw new ArgumentNullException("recipients");1089		}1090		if (content == null)1091		{1092			throw new ArgumentNullException("content");1093		}1094		return Encrypt(GetCmsRecipients(recipients), content, cancellationToken);1095	}10961097	public override async Task<MimePart> EncryptAsync(IEnumerable<MailboxAddress> recipients, Stream content, CancellationToken cancellationToken = default(CancellationToken))1098	{1099		if (recipients == null)1100		{1101			throw new ArgumentNullException("recipients");1102		}1103		if (content == null)1104		{1105			throw new ArgumentNullException("content");1106		}1107		return await EncryptAsync(GetCmsRecipients(recipients), content, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);1108	}11091110	private CmsTypedStream GetDecryptedContent(CmsEnvelopedDataParser parser)1111	{1112		RecipientInformationStore recipientInfos = parser.GetRecipientInfos();1113		foreach (RecipientInformation recipient in recipientInfos.GetRecipients())1114		{1115			AsymmetricKeyParameter privateKey;1116			if ((privateKey = GetPrivateKey(recipient.RecipientID)) != null)1117			{1118				return recipient.GetContentStream(privateKey);1119			}1120		}1121		throw new CmsException("A suitable private key could not be found for decrypting.");1122	}11231124	public override MimeEntity Decrypt(Stream encryptedData, CancellationToken cancellationToken = default(CancellationToken))1125	{1126		if (encryptedData == null)1127		{1128			throw new ArgumentNullException("encryptedData");1129		}1130		using CmsEnvelopedDataParser parser = new CmsEnvelopedDataParser(encryptedData);1131		CmsTypedStream decryptedContent = GetDecryptedContent(parser);1132		try1133		{1134			return MimeEntity.Load(decryptedContent.ContentStream, persistent: false, cancellationToken);1135		}1136		finally1137		{1138			decryptedContent.ContentStream.Dispose();1139		}1140	}11411142	public override async Task<MimeEntity> DecryptAsync(Stream encryptedData, CancellationToken cancellationToken = default(CancellationToken))1143	{1144		if (encryptedData == null)1145		{1146			throw new ArgumentNullException("encryptedData");1147		}1148		using CmsEnvelopedDataParser parser = new CmsEnvelopedDataParser(encryptedData);1149		CmsTypedStream decrypted = GetDecryptedContent(parser);1150		try1151		{1152			return await MimeEntity.LoadAsync(decrypted.ContentStream, persistent: false, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);1153		}1154		finally1155		{1156			decrypted.ContentStream.Dispose();1157		}1158	}11591160	public override void DecryptTo(Stream encryptedData, Stream decryptedData, CancellationToken cancellationToken = default(CancellationToken))1161	{1162		if (encryptedData == null)1163		{1164			throw new ArgumentNullException("encryptedData");1165		}1166		if (decryptedData == null)1167		{1168			throw new ArgumentNullException("decryptedData");1169		}1170		using CmsEnvelopedDataParser parser = new CmsEnvelopedDataParser(encryptedData);1171		CmsTypedStream decryptedContent = GetDecryptedContent(parser);1172		try1173		{1174			decryptedContent.ContentStream.CopyTo(decryptedData, 4096);1175		}1176		finally1177		{1178			decryptedContent.ContentStream.Dispose();1179		}1180	}11811182	public override async Task DecryptToAsync(Stream encryptedData, Stream decryptedData, CancellationToken cancellationToken = default(CancellationToken))1183	{1184		if (encryptedData == null)1185		{1186			throw new ArgumentNullException("encryptedData");1187		}1188		if (decryptedData == null)1189		{1190			throw new ArgumentNullException("decryptedData");1191		}1192		using CmsEnvelopedDataParser parser = new CmsEnvelopedDataParser(encryptedData);1193		CmsTypedStream decrypted = GetDecryptedContent(parser);1194		try1195		{1196			await decrypted.ContentStream.CopyToAsync(decryptedData, 4096, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);1197		}1198		finally1199		{1200			decrypted.ContentStream.Dispose();1201		}1202	}12031204	public override MimePart Export(IEnumerable<MailboxAddress> mailboxes, CancellationToken cancellationToken = default(CancellationToken))1205	{1206		if (mailboxes == null)1207		{1208			throw new ArgumentNullException("mailboxes");1209		}1210		X509CertificateStore x509CertificateStore = new X509CertificateStore();1211		int num = 0;1212		foreach (MailboxAddress mailbox in mailboxes)1213		{1214			CmsRecipient cmsRecipient = GetCmsRecipient(mailbox);1215			x509CertificateStore.Add(cmsRecipient.Certificate);1216			num++;1217		}1218		if (num == 0)1219		{1220			throw new ArgumentException("No mailboxes specified.", "mailboxes");1221		}1222		CmsSignedDataStreamGenerator cmsSignedDataStreamGenerator = new CmsSignedDataStreamGenerator(RandomNumberGenerator);1223		cmsSignedDataStreamGenerator.AddCertificates(x509CertificateStore);1224		MemoryBlockStream memoryBlockStream = new MemoryBlockStream();1225		cmsSignedDataStreamGenerator.Open(memoryBlockStream).Dispose();1226		memoryBlockStream.Position = 0L;1227		return new ApplicationPkcs7Mime(SecureMimeType.CertsOnly, memoryBlockStream);1228	}12291230	public override Task<MimePart> ExportAsync(IEnumerable<MailboxAddress> mailboxes, CancellationToken cancellationToken = default(CancellationToken))1231	{1232		return Task.FromResult(Export(mailboxes, cancellationToken));1233	}1234}1235