<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />

CmsEnvelopedHelper

using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.IO; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities.IO; using System; using System.Collections.Generic; using System.IO; namespace Org.BouncyCastle.Cms { internal class CmsEnvelopedHelper { internal class CmsAuthenticatedSecureReadable : CmsSecureReadable { private AlgorithmIdentifier algorithm; private IMac mac; private CmsReadable readable; public AlgorithmIdentifier Algorithm => algorithm; public object CryptoObject => mac; internal CmsAuthenticatedSecureReadable(AlgorithmIdentifier algorithm, CmsReadable readable) { this.algorithm = algorithm; this.readable = readable; } public CmsReadable GetReadable(KeyParameter sKey) { string id = algorithm.Algorithm.Id; try { mac = MacUtilities.GetMac(id); mac.Init(sKey); } catch (SecurityUtilityException innerException) { throw new CmsException("couldn't create cipher.", innerException); } catch (InvalidKeyException innerException2) { throw new CmsException("key invalid in message.", innerException2); } catch (IOException innerException3) { throw new CmsException("error decoding algorithm parameters.", innerException3); } try { return new CmsProcessableInputStream(new TeeInputStream(readable.GetInputStream(), new MacSink(mac))); } catch (IOException innerException4) { throw new CmsException("error reading content.", innerException4); } } } internal class CmsEnvelopedSecureReadable : CmsSecureReadable { private AlgorithmIdentifier algorithm; private IBufferedCipher cipher; private CmsReadable readable; public AlgorithmIdentifier Algorithm => algorithm; public object CryptoObject => cipher; internal CmsEnvelopedSecureReadable(AlgorithmIdentifier algorithm, CmsReadable readable) { this.algorithm = algorithm; this.readable = readable; } public CmsReadable GetReadable(KeyParameter sKey) { try { cipher = CipherUtilities.GetCipher(algorithm.Algorithm); Asn1Object asn1Object = algorithm.Parameters?.ToAsn1Object(); ICipherParameters cipherParameters = sKey; if (asn1Object != null && !(asn1Object is Asn1Null)) cipherParameters = ParameterUtilities.GetCipherParameters(algorithm.Algorithm, cipherParameters, asn1Object); else { string id = algorithm.Algorithm.Id; if (id.Equals(CmsEnvelopedGenerator.DesEde3Cbc) || id.Equals("1.3.6.1.4.1.188.7.1.1.2") || id.Equals("1.2.840.113533.7.66.10")) cipherParameters = new ParametersWithIV(cipherParameters, new byte[8]); } cipher.Init(false, cipherParameters); } catch (SecurityUtilityException innerException) { throw new CmsException("couldn't create cipher.", innerException); } catch (InvalidKeyException innerException2) { throw new CmsException("key invalid in message.", innerException2); } catch (IOException innerException3) { throw new CmsException("error decoding algorithm parameters.", innerException3); } try { return new CmsProcessableInputStream(new CipherStream(readable.GetInputStream(), cipher, null)); } catch (IOException innerException4) { throw new CmsException("error reading content.", innerException4); } } } private static readonly Dictionary<string, int> KeySizes; private static readonly Dictionary<string, string> Rfc3211WrapperNames; static CmsEnvelopedHelper() { KeySizes = new Dictionary<string, int>(); Rfc3211WrapperNames = new Dictionary<string, string>(); KeySizes.Add(CmsEnvelopedGenerator.Aes128Cbc, 128); KeySizes.Add(CmsEnvelopedGenerator.Aes192Cbc, 192); KeySizes.Add(CmsEnvelopedGenerator.Aes256Cbc, 256); KeySizes.Add(CmsEnvelopedGenerator.Camellia128Cbc, 128); KeySizes.Add(CmsEnvelopedGenerator.Camellia192Cbc, 192); KeySizes.Add(CmsEnvelopedGenerator.Camellia256Cbc, 256); KeySizes.Add(CmsEnvelopedGenerator.DesCbc, 64); KeySizes.Add(CmsEnvelopedGenerator.DesEde3Cbc, 192); Rfc3211WrapperNames.Add(CmsEnvelopedGenerator.Aes128Cbc, "AESRFC3211WRAP"); Rfc3211WrapperNames.Add(CmsEnvelopedGenerator.Aes192Cbc, "AESRFC3211WRAP"); Rfc3211WrapperNames.Add(CmsEnvelopedGenerator.Aes256Cbc, "AESRFC3211WRAP"); Rfc3211WrapperNames.Add(CmsEnvelopedGenerator.Camellia128Cbc, "CAMELLIARFC3211WRAP"); Rfc3211WrapperNames.Add(CmsEnvelopedGenerator.Camellia192Cbc, "CAMELLIARFC3211WRAP"); Rfc3211WrapperNames.Add(CmsEnvelopedGenerator.Camellia256Cbc, "CAMELLIARFC3211WRAP"); Rfc3211WrapperNames.Add(CmsEnvelopedGenerator.DesCbc, "DESRFC3211WRAP"); Rfc3211WrapperNames.Add(CmsEnvelopedGenerator.DesEde3Cbc, "DESEDERFC3211WRAP"); } internal static RecipientInformationStore BuildRecipientInformationStore(Asn1Set recipientInfos, CmsSecureReadable secureReadable) { List<RecipientInformation> list = new List<RecipientInformation>(); for (int i = 0; i != recipientInfos.Count; i++) { RecipientInfo instance = RecipientInfo.GetInstance(recipientInfos[i]); ReadRecipientInfo(list, instance, secureReadable); } return new RecipientInformationStore(list); } internal static int GetKeySize(string oid) { if (oid == null) throw new ArgumentNullException("oid"); if (!KeySizes.TryGetValue(oid, out int value)) throw new ArgumentException("no key size for " + oid, "oid"); return value; } internal static string GetRfc3211WrapperName(string oid) { if (oid == null) throw new ArgumentNullException("oid"); if (!Rfc3211WrapperNames.TryGetValue(oid, out string value)) throw new ArgumentException("no name for " + oid, "oid"); return value; } private static void ReadRecipientInfo(IList<RecipientInformation> infos, RecipientInfo info, CmsSecureReadable secureReadable) { Asn1Encodable info2 = info.Info; KeyTransRecipientInfo keyTransRecipientInfo = info2 as KeyTransRecipientInfo; if (keyTransRecipientInfo != null) infos.Add(new KeyTransRecipientInformation(keyTransRecipientInfo, secureReadable)); else { KekRecipientInfo kekRecipientInfo = info2 as KekRecipientInfo; if (kekRecipientInfo != null) infos.Add(new KekRecipientInformation(kekRecipientInfo, secureReadable)); else { KeyAgreeRecipientInfo keyAgreeRecipientInfo = info2 as KeyAgreeRecipientInfo; if (keyAgreeRecipientInfo != null) KeyAgreeRecipientInformation.ReadRecipientInfo(infos, keyAgreeRecipientInfo, secureReadable); else { PasswordRecipientInfo passwordRecipientInfo = info2 as PasswordRecipientInfo; if (passwordRecipientInfo != null) infos.Add(new PasswordRecipientInformation(passwordRecipientInfo, secureReadable)); } } } } } }