/// <inheritdoc /> public byte[] Decrypt(byte[] data) { foreach (var pkcsStore in _allSenderCertificates) { var certAlias = pkcsStore.Aliases.Cast<string>().First(x => pkcsStore.IsKeyEntry(x)); var certEntry = pkcsStore.GetCertificate(certAlias); var cert = certEntry.Certificate; var envelopedData = new CmsEnvelopedData(data); var recepientInfos = envelopedData.GetRecipientInfos(); var recepientId = new RecipientID() { Issuer = cert.IssuerDN, SerialNumber = cert.SerialNumber }; var recepient = recepientInfos[recepientId]; if (recepient == null) continue; var privKeyEntry = pkcsStore.GetKey(certAlias); var privKey = privKeyEntry.Key; var decryptedData = recepient.GetContent(privKey); var sig = new CmsSignedData(decryptedData); var sigInfos = sig.GetSignerInfos(); var signerId = new SignerID() { Issuer = _receiverCertificate.IssuerDN, SerialNumber = _receiverCertificate.SerialNumber }; var signer = sigInfos.GetFirstSigner(signerId); if (!signer.Verify(_receiverCertificate)) throw new ExtraEncryptionException("Failed to verify the signature."); var verifiedData = new MemoryStream(); sig.SignedContent.Write(verifiedData); return verifiedData.ToArray(); } throw new ExtraEncryptionException("No certificate for decryption found."); }
internal KeyAgreeRecipientInformation(KeyAgreeRecipientInfo info, RecipientID rid, Asn1OctetString encryptedKey, CmsSecureReadable secureReadable) : base(info.KeyEncryptionAlgorithm, secureReadable) { this.info = info; base.rid = rid; this.encryptedKey = encryptedKey; }
public RecipientInformationStore(global::System.Collections.ICollection recipientInfos) { global::System.Collections.IEnumerator enumerator = ((global::System.Collections.IEnumerable)recipientInfos).GetEnumerator(); try { while (enumerator.MoveNext()) { RecipientInformation recipientInformation = (RecipientInformation)enumerator.get_Current(); RecipientID recipientID = recipientInformation.RecipientID; global::System.Collections.IList list = (global::System.Collections.IList)table.get_Item((object)recipientID); if (list == null) { table.set_Item((object)recipientID, (object)(list = Platform.CreateArrayList(1))); } list.Add((object)recipientInformation); } } finally { global::System.IDisposable disposable = enumerator as global::System.IDisposable; if (disposable != null) { disposable.Dispose(); } } all = Platform.CreateArrayList(recipientInfos); }
/** * Return possible empty collection with recipients matching the passed in RecipientID * * @param selector a recipient id to select against. * @return a collection of RecipientInformation objects. */ public ICollection GetRecipients( RecipientID selector) { ArrayList list = (ArrayList)table[selector]; return(list == null ? new ArrayList() : new ArrayList(list)); }
/** * Return possible empty collection with recipients matching the passed in RecipientID * * @param selector a recipient id to select against. * @return a collection of RecipientInformation objects. */ public ICollection GetRecipients( RecipientID selector) { IList list = (IList)table[selector]; return list == null ? Platform.CreateArrayList() : Platform.CreateArrayList(list); }
/** * Return the first RecipientInformation object that matches the * passed in selector. Null if there are no matches. * * @param selector to identify a recipient * @return a single RecipientInformation object. Null if none matches. */ public RecipientInformation GetFirstRecipient( RecipientID selector) { ArrayList list = (ArrayList) table[selector]; return list == null ? null : (RecipientInformation) list[0]; }
internal KeyTransRecipientInformation(KeyTransRecipientInfo info, CmsSecureReadable secureReadable) : base(info.KeyEncryptionAlgorithm, secureReadable) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) this.info = info; rid = new RecipientID(); RecipientIdentifier recipientIdentifier = info.RecipientIdentifier; try { if (recipientIdentifier.IsTagged) { Asn1OctetString instance = Asn1OctetString.GetInstance(recipientIdentifier.ID); rid.SubjectKeyIdentifier = instance.GetOctets(); } else { Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber instance2 = Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber.GetInstance(recipientIdentifier.ID); rid.Issuer = instance2.Name; rid.SerialNumber = instance2.SerialNumber.Value; } } catch (IOException) { throw new ArgumentException("invalid rid in KeyTransRecipientInformation"); } }
/** * Return possible empty collection with recipients matching the passed in RecipientID * * @param selector a recipient id to select against. * @return a collection of RecipientInformation objects. */ public ICollection GetRecipients( RecipientID selector) { ArrayList list = (ArrayList) table[selector]; return list == null ? new ArrayList() : new ArrayList(list); }
public KeyAgreeRecipientInformation( KeyAgreeRecipientInfo info, AlgorithmIdentifier encAlg, Stream data) : base(encAlg, AlgorithmIdentifier.GetInstance(info.KeyEncryptionAlgorithm), data) { _info = info; // _encAlg = encAlg; try { Asn1Sequence s = _info.RecipientEncryptedKeys; RecipientEncryptedKey id = RecipientEncryptedKey.GetInstance(s[0]); Asn1.Cms.IssuerAndSerialNumber iAnds = id.Identifier.IssuerAndSerialNumber; // byte[] issuerBytes = iAnds.Name.GetEncoded(); _rid = new RecipientID(); // _rid.SetIssuer(issuerBytes); _rid.Issuer = iAnds.Name; _rid.SerialNumber = iAnds.SerialNumber.Value; _encryptedKey = id.EncryptedKey; } catch (IOException e) { throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", e); } }
/** * Return the first RecipientInformation object that matches the * passed in selector. Null if there are no matches. * * @param selector to identify a recipient * @return a single RecipientInformation object. Null if none matches. */ public RecipientInformation GetFirstRecipient( RecipientID selector) { IList list = (IList)table[selector]; return(list == null ? null : (RecipientInformation)list[0]); }
public RecipientInformation this[RecipientID selector] { get { return(this.GetFirstRecipient(selector)); } }
internal static void ReadRecipientInfo(IList infos, KeyAgreeRecipientInfo info, CmsSecureReadable secureReadable) { try { foreach (Asn1Encodable asn1Encodable in info.RecipientEncryptedKeys) { RecipientEncryptedKey instance = RecipientEncryptedKey.GetInstance(asn1Encodable.ToAsn1Object()); RecipientID recipientID = new RecipientID(); KeyAgreeRecipientIdentifier identifier = instance.Identifier; Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber issuerAndSerialNumber = identifier.IssuerAndSerialNumber; if (issuerAndSerialNumber != null) { recipientID.Issuer = issuerAndSerialNumber.Name; recipientID.SerialNumber = issuerAndSerialNumber.SerialNumber.Value; } else { RecipientKeyIdentifier rKeyID = identifier.RKeyID; recipientID.SubjectKeyIdentifier = rKeyID.SubjectKeyIdentifier.GetOctets(); } infos.Add(new KeyAgreeRecipientInformation(info, recipientID, instance.EncryptedKey, secureReadable)); } } catch (IOException innerException) { throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", innerException); } }
/** * Return possible empty collection with recipients matching the passed in RecipientID * * @param selector a recipient id to select against. * @return a collection of RecipientInformation objects. */ public ICollection GetRecipients( RecipientID selector) { IList list = (IList)table[selector]; return(list == null?Platform.CreateArrayList() : Platform.CreateArrayList(list)); }
public global::System.Collections.ICollection GetRecipients(RecipientID selector) { global::System.Collections.IList list = (global::System.Collections.IList)table.get_Item((object)selector); if (list != null) { return((global::System.Collections.ICollection)Platform.CreateArrayList((global::System.Collections.ICollection)list)); } return((global::System.Collections.ICollection)Platform.CreateArrayList()); }
public RecipientInformation GetFirstRecipient(RecipientID selector) { global::System.Collections.IList list = (global::System.Collections.IList)table.get_Item((object)selector); if (list != null) { return((RecipientInformation)list.get_Item(0)); } return(null); }
internal KekRecipientInformation(KekRecipientInfo info, CmsSecureReadable secureReadable) : base(info.KeyEncryptionAlgorithm, secureReadable) { this.info = info; rid = new RecipientID(); KekIdentifier kekID = info.KekID; rid.KeyIdentifier = kekID.KeyIdentifier.GetOctets(); }
public RecipientInformation GetFirstRecipient(RecipientID selector) { IList list = (IList)this.table[selector]; if (list != null) { return((RecipientInformation)list[0]); } return(null); }
public override bool Equals(object obj) { if (obj == this) { return(true); } RecipientID recipientID = obj as RecipientID; return(recipientID != null && (Arrays.AreEqual(this.keyIdentifier, recipientID.keyIdentifier) && Arrays.AreEqual(base.SubjectKeyIdentifier, recipientID.SubjectKeyIdentifier) && object.Equals(base.SerialNumber, recipientID.SerialNumber)) && X509CertStoreSelector.IssuersMatch(base.Issuer, recipientID.Issuer)); }
public ICollection GetRecipients(RecipientID selector) { IList list = (IList)this.table[selector]; if (list != null) { return(Platform.CreateArrayList(list)); } return(Platform.CreateArrayList()); }
internal KeyAgreeRecipientInformation( KeyAgreeRecipientInfo info, RecipientID rid, Asn1OctetString encryptedKey, CmsSecureReadable secureReadable) : base(info.KeyEncryptionAlgorithm, secureReadable) { this.info = info; this.rid = rid; this.encryptedKey = encryptedKey; }
public KeyAgreeRecipientInformation( KeyAgreeRecipientInfo info, RecipientID rid, Asn1OctetString encryptedKey, AlgorithmIdentifier encAlg, AlgorithmIdentifier macAlg, AlgorithmIdentifier authEncAlg, Stream data) : base(encAlg, macAlg, authEncAlg, info.KeyEncryptionAlgorithm, data) { this.info = info; this.rid = rid; this.encryptedKey = encryptedKey; }
public RecipientInformationStore(ICollection recipientInfos) { foreach (RecipientInformation recipientInformation in recipientInfos) { RecipientID recipientID = recipientInformation.RecipientID; IList list = (IList)this.table[recipientID]; if (list == null) { list = (this.table[recipientID] = Platform.CreateArrayList(1)); } list.Add(recipientInformation); } this.all = Platform.CreateArrayList(recipientInfos); }
public override bool Equals(object obj) { if (obj == this) { return(true); } RecipientID recipientID = obj as RecipientID; if (recipientID == null) { return(false); } if (Arrays.AreEqual(keyIdentifier, recipientID.keyIdentifier) && Arrays.AreEqual(base.SubjectKeyIdentifier, recipientID.SubjectKeyIdentifier) && object.Equals((object)base.SerialNumber, (object)recipientID.SerialNumber)) { return(X509CertStoreSelector.IssuersMatch(base.Issuer, recipientID.Issuer)); } return(false); }
private readonly Hashtable table = new Hashtable(); // Hashtable[RecipientID, ArrayList[RecipientInformation]] public RecipientInformationStore( ICollection recipientInfos) { foreach (RecipientInformation recipientInformation in recipientInfos) { RecipientID rid = recipientInformation.RecipientID; ArrayList list = (ArrayList)table[rid]; if (list == null) { table[rid] = list = new ArrayList(1); } list.Add(recipientInformation); } this.all = new ArrayList(recipientInfos); }
internal static void ReadRecipientInfo(global::System.Collections.IList infos, KeyAgreeRecipientInfo info, CmsSecureReadable secureReadable) { //IL_00bb: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) try { global::System.Collections.IEnumerator enumerator = info.RecipientEncryptedKeys.GetEnumerator(); try { while (enumerator.MoveNext()) { Asn1Encodable asn1Encodable = (Asn1Encodable)enumerator.get_Current(); RecipientEncryptedKey instance = RecipientEncryptedKey.GetInstance(asn1Encodable.ToAsn1Object()); RecipientID recipientID = new RecipientID(); KeyAgreeRecipientIdentifier identifier = instance.Identifier; Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber issuerAndSerialNumber = identifier.IssuerAndSerialNumber; if (issuerAndSerialNumber != null) { recipientID.Issuer = issuerAndSerialNumber.Name; recipientID.SerialNumber = issuerAndSerialNumber.SerialNumber.Value; } else { RecipientKeyIdentifier rKeyID = identifier.RKeyID; recipientID.SubjectKeyIdentifier = rKeyID.SubjectKeyIdentifier.GetOctets(); } infos.Add((object)new KeyAgreeRecipientInformation(info, recipientID, instance.EncryptedKey, secureReadable)); } } finally { global::System.IDisposable disposable = enumerator as global::System.IDisposable; if (disposable != null) { disposable.Dispose(); } } } catch (IOException val) { IOException val2 = val; throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", (global::System.Exception)(object) val2); } }
public override bool Equals( object obj) { if (obj == this) { return(true); } RecipientID id = obj as RecipientID; if (id == null) { return(false); } return(Arrays.AreEqual(keyIdentifier, id.keyIdentifier) && Arrays.AreEqual(SubjectKeyIdentifier, id.SubjectKeyIdentifier) && Platform.Equals(SerialNumber, id.SerialNumber) && IssuersMatch(Issuer, id.Issuer)); }
public override bool Equals( object obj) { if (obj == this) { return(true); } RecipientID id = obj as RecipientID; if (id == null) { return(false); } return(Arrays.AreSame(keyIdentifier, id.keyIdentifier) && Arrays.AreSame(SubjectKeyIdentifier, id.SubjectKeyIdentifier) && object.Equals(SerialNumber, id.SerialNumber) && object.Equals(IssuerAsString, id.IssuerAsString)); }
internal static void ReadRecipientInfo(IList infos, KeyAgreeRecipientInfo info, AlgorithmIdentifier encAlg, AlgorithmIdentifier macAlg, AlgorithmIdentifier authEncAlg, Stream data) { try { foreach (Asn1Encodable rek in info.RecipientEncryptedKeys) { RecipientEncryptedKey id = RecipientEncryptedKey.GetInstance(rek.ToAsn1Object()); RecipientID rid = new RecipientID(); Asn1.Cms.KeyAgreeRecipientIdentifier karid = id.Identifier; Asn1.Cms.IssuerAndSerialNumber iAndSN = karid.IssuerAndSerialNumber; if (iAndSN != null) { rid.Issuer = iAndSN.Name; rid.SerialNumber = iAndSN.SerialNumber.Value; } else { Asn1.Cms.RecipientKeyIdentifier rKeyID = karid.RKeyID; // Note: 'date' and 'other' fields of RecipientKeyIdentifier appear to be only informational rid.SubjectKeyIdentifier = rKeyID.SubjectKeyIdentifier.GetOctets(); } infos.Add(new KeyAgreeRecipientInformation(info, rid, id.EncryptedKey, encAlg, macAlg, authEncAlg, data)); } } catch (IOException e) { throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", e); } }
internal static void ReadRecipientInfo(IList infos, KeyAgreeRecipientInfo info, CmsSecureReadable secureReadable) { try { foreach (Asn1Encodable rek in info.RecipientEncryptedKeys) { RecipientEncryptedKey id = RecipientEncryptedKey.GetInstance(rek.ToAsn1Object()); RecipientID rid = new RecipientID(); Asn1.Cms.KeyAgreeRecipientIdentifier karid = id.Identifier; Asn1.Cms.IssuerAndSerialNumber iAndSN = karid.IssuerAndSerialNumber; if (iAndSN != null) { rid.Issuer = iAndSN.Name; rid.SerialNumber = iAndSN.SerialNumber.Value; } else { Asn1.Cms.RecipientKeyIdentifier rKeyID = karid.RKeyID; // Note: 'date' and 'other' fields of RecipientKeyIdentifier appear to be only informational rid.SubjectKeyIdentifier = rKeyID.SubjectKeyIdentifier.GetOctets(); } infos.Add(new KeyAgreeRecipientInformation(info, rid, id.EncryptedKey, secureReadable)); } } catch (IOException e) { throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", e); } }
public RecipientInformation this[RecipientID selector] => GetFirstRecipient(selector);
/** * Return possible empty collection with recipients matching the passed in RecipientID * * @param selector a recipient id to select against. * @return a collection of RecipientInformation objects. */ public ICollection GetRecipients( RecipientID selector) { ArrayList list = (ArrayList) table[selector]; return list == null ? new ArrayList() : // MASC 20070307. CF compatibility patch #if !NETCF ArrayList.ReadOnly(list); #else list; #endif }
public void TestTwoAesKek() { byte[] data = Encoding.Default.GetBytes("WallaWallaWashington"); KeyParameter kek1 = CmsTestUtil.MakeAes192Key(); KeyParameter kek2 = CmsTestUtil.MakeAes192Key(); CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator(); byte[] kekId1 = new byte[] { 1, 2, 3, 4, 5 }; byte[] kekId2 = new byte[] { 5, 4, 3, 2, 1 }; edGen.AddKekRecipient("AES192", kek1, kekId1); edGen.AddKekRecipient("AES192", kek2, kekId2); MemoryStream bOut = new MemoryStream(); Stream outStream = edGen.Open( bOut, CmsEnvelopedDataGenerator.DesEde3Cbc); outStream.Write(data, 0, data.Length); outStream.Close(); CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(bOut.ToArray()); RecipientInformationStore recipients = ep.GetRecipientInfos(); Assert.AreEqual(ep.EncryptionAlgOid, CmsEnvelopedDataGenerator.DesEde3Cbc); RecipientID recSel = new RecipientID(); recSel.KeyIdentifier = kekId2; RecipientInformation recipient = recipients.GetFirstRecipient(recSel); Assert.AreEqual(recipient.KeyEncryptionAlgOid, "2.16.840.1.101.3.4.1.25"); CmsTypedStream recData = recipient.GetContentStream(kek2); Assert.IsTrue(Arrays.AreEqual(data, CmsTestUtil.StreamToByteArray(recData.ContentStream))); ep.Close(); }
public void TestECKeyAgree() { byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator(); edGen.AddKeyAgreementRecipient( CmsEnvelopedDataGenerator.ECDHSha1Kdf, OrigECKP.Private, OrigECKP.Public, ReciECCert, CmsEnvelopedDataGenerator.Aes128Wrap); MemoryStream bOut = new MemoryStream(); Stream outStr = edGen.Open(bOut, CmsEnvelopedDataGenerator.Aes128Cbc); outStr.Write(data, 0, data.Length); outStr.Close(); CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(bOut.ToArray()); RecipientInformationStore recipients = ep.GetRecipientInfos(); Assert.AreEqual(ep.EncryptionAlgOid, CmsEnvelopedDataGenerator.Aes128Cbc); RecipientID recSel = new RecipientID(); // recSel.SetIssuer(PrincipalUtilities.GetIssuerX509Principal(ReciECCert).GetEncoded()); recSel.Issuer = PrincipalUtilities.GetIssuerX509Principal(ReciECCert); recSel.SerialNumber = ReciECCert.SerialNumber; RecipientInformation recipient = recipients.GetFirstRecipient(recSel); CmsTypedStream recData = recipient.GetContentStream(ReciECKP.Private); Assert.IsTrue(Arrays.AreEqual(data, CmsTestUtil.StreamToByteArray(recData.ContentStream))); ep.Close(); }
public RecipientInformation this[RecipientID selector] { get { return GetFirstRecipient(selector); } }
private static void ConfirmDataReceived(RecipientInformationStore recipients, byte[] expectedData, X509Certificate reciCert, AsymmetricKeyParameter reciPrivKey) { RecipientID rid = new RecipientID(); rid.Issuer = PrincipalUtilities.GetIssuerX509Principal(reciCert); rid.SerialNumber = reciCert.SerialNumber; RecipientInformation recipient = recipients[rid]; Assert.IsNotNull(recipient); byte[] actualData = recipient.GetContent(reciPrivKey); Assert.IsTrue(Arrays.AreEqual(expectedData, actualData)); }
internal PasswordRecipientInformation(PasswordRecipientInfo info, CmsSecureReadable secureReadable) : base(info.KeyEncryptionAlgorithm, secureReadable) { this.info = info; rid = new RecipientID(); }
private SecurityInformation Decrypt(Stream clear, Stream cypher, SecretKey key, DateTime? sealedOn) { int i; bool found; StringBuilder algos; DateTime date = sealedOn == null ? DateTime.UtcNow : sealedOn.Value; trace.TraceEvent(TraceEventType.Information, 0, "Decrypting message for {0} recipient", key == null ? "known" : "unknown"); try { SecurityInformation result = new SecurityInformation(); CmsEnvelopedDataParser cypherData; try { cypherData = new CmsEnvelopedDataParser(cypher); trace.TraceEvent(TraceEventType.Verbose, 0, "Read the cms header"); } catch (Exception e) { trace.TraceEvent(TraceEventType.Error, 0, "The messages isn't encrypted"); throw new InvalidMessageException("The message isn't a triple wrapped message", e); } RecipientInformationStore recipientInfos = cypherData.GetRecipientInfos(); trace.TraceEvent(TraceEventType.Verbose, 0, "Got the recipient info of the encrypted message"); i = 0; found = false; algos = new StringBuilder(); string encryptionAlgOid = cypherData.EncryptionAlgOid; while (!found && i < EteeActiveConfig.Unseal.EncryptionAlgorithms.Count) { Oid algo = EteeActiveConfig.Unseal.EncryptionAlgorithms[i++]; algos.Append(algo.Value + " (" + algo.FriendlyName + ") "); found = algo.Value == encryptionAlgOid; } if (!found) { result.securityViolations.Add(SecurityViolation.NotAllowedEncryptionAlgorithm); trace.TraceEvent(TraceEventType.Warning, 0, "The encryption algorithm {0} isn't allowed, only {1} are", encryptionAlgOid, algos); } trace.TraceEvent(TraceEventType.Verbose, 0, "The encryption algorithm is verified: {0}", encryptionAlgOid); //Key size of the message should not be checked, size is determined by the algorithm //Get recipient, should be receiver. RecipientInformation recipientInfo; ICipherParameters recipientKey; if (key == null) { if (encCertStore != null) { //Find find a matching receiver ICollection recipients = recipientInfos.GetRecipients(); //recipients in the message IList<KeyValuePair<RecipientInformation, IList>> allMatches = new List<KeyValuePair<RecipientInformation, IList>>(); foreach (RecipientInformation recipient in recipients) { trace.TraceEvent(TraceEventType.Verbose, 0, "The message is addressed to {0} ({1})", recipient.RecipientID.SerialNumber, recipient.RecipientID.Issuer); if (recipient is KeyTransRecipientInformation) { IList matches = (IList) encCertStore.GetMatches(recipient.RecipientID); if (matches.Count > 0) { allMatches.Add(new KeyValuePair<RecipientInformation, IList>(recipient, matches)); } } } //Did we find a receiver? if (allMatches.Count == 0) { trace.TraceEvent(TraceEventType.Error, 0, "The recipients doe not contain any of your your encryption certificates"); throw new InvalidMessageException("The message isn't a message that is addressed to you. Or it is an unaddressed message or it is addressed to somebody else"); } //check with encryption cert matches where valid at creation time IList<KeyValuePair<RecipientInformation, IList>> validMatches = new List<KeyValuePair<RecipientInformation, IList>>(); foreach (KeyValuePair<RecipientInformation, IList> match in allMatches) { IList validCertificate = new List<X509Certificate2>(); foreach (X509Certificate2 cert in match.Value) { //Validate the description cert, providing minimal info to force minimal validation. CertificateSecurityInformation certVerRes = CertVerifier.VerifyEnc(DotNetUtilities.FromX509Certificate(cert), null, date, null, false); trace.TraceEvent(TraceEventType.Verbose, 0, "Validated potential decryption certificate ({0}) : Validation Status = {1}, Trust Status = {2}", cert.Subject, certVerRes.ValidationStatus, certVerRes.TrustStatus); if (certVerRes.SecurityViolations.Count == 0) { validCertificate.Add(cert); } } if (validCertificate.Count > 0) { validMatches.Add(new KeyValuePair<RecipientInformation, IList>(match.Key, validCertificate)); } } //If we have a valid encCert use that one, otherwise use an invalid one (at least we can read it, but should not use it) X509Certificate2 selectedCert; if (validMatches.Count > 0) { selectedCert = (X509Certificate2)validMatches[0].Value[0]; recipientInfo = validMatches[0].Key; trace.TraceEvent(TraceEventType.Information, 0, "Found valid decryption certificate ({0}) that matches one the the recipients", selectedCert.Subject); } else { selectedCert = (X509Certificate2)allMatches[0].Value[0]; recipientInfo = allMatches[0].Key; trace.TraceEvent(TraceEventType.Warning, 0, "Found *invalid* decryption certificate ({0}) that matches one the the recipients", selectedCert.Subject); } recipientKey = DotNetUtilities.GetKeyPair(selectedCert.PrivateKey).Private; //we validate the selected certificate again to inform the caller result.Subject = CertVerifier.VerifyEnc(DotNetUtilities.FromX509Certificate(selectedCert), null, date, null, false); } else { trace.TraceEvent(TraceEventType.Error, 0, "The unsealer does not have an decryption certificate and no symmetric key was provided"); throw new InvalidOperationException("There should be an receiver (=yourself) and/or a key provided"); } } else { trace.TraceEvent(TraceEventType.Verbose, 0, "Found symmetric key: {0}", key.IdString); RecipientID recipientId = new RecipientID(); recipientId.KeyIdentifier = key.Id; recipientInfo = recipientInfos.GetFirstRecipient(recipientId); if (recipientInfo == null) { trace.TraceEvent(TraceEventType.Error, 0, "The symmetric key was not found in this cms message"); throw new InvalidMessageException("The key isn't for this unaddressed message"); } trace.TraceEvent(TraceEventType.Verbose, 0, "Found symmetric key in recipients of the cms message"); //Get receivers key recipientKey = key.BCKey; //Validate the unaddressed key if ((((KeyParameter)recipientKey).GetKey().Length * 8) < EteeActiveConfig.Unseal.MinimumEncryptionKeySize.SymmetricRecipientKey) { result.securityViolations.Add(SecurityViolation.NotAllowedEncryptionKeySize); trace.TraceEvent(TraceEventType.Warning, 0, "The symmetric key was only {0} bits while it should be at least {0}", ((KeyParameter)recipientKey).GetKey().Length * 8, EteeActiveConfig.Unseal.MinimumEncryptionKeySize.SymmetricRecipientKey); } } //check if key encryption algorithm is allowed i = 0; found = false; algos = new StringBuilder(); while (!found && i < EteeActiveConfig.Unseal.KeyEncryptionAlgorithms.Count) { Oid algo = EteeActiveConfig.Unseal.KeyEncryptionAlgorithms[i++]; algos.Append(algo.Value + " (" + algo.FriendlyName + ") "); found = algo.Value == recipientInfo.KeyEncryptionAlgOid; } if (!found) { result.securityViolations.Add(SecurityViolation.NotAllowedKeyEncryptionAlgorithm); trace.TraceEvent(TraceEventType.Warning, 0, "Encryption algorithm is {0} while it should be one of the following {1}", recipientInfo.KeyEncryptionAlgOid, algos); } trace.TraceEvent(TraceEventType.Verbose, 0, "Finished verifying the encryption algorithm: {0}", recipientInfo.KeyEncryptionAlgOid); //Decrypt! CmsTypedStream clearStream = recipientInfo.GetContentStream(recipientKey); trace.TraceEvent(TraceEventType.Verbose, 0, "Accessed the encrypted content"); try { clearStream.ContentStream.CopyTo(clear); trace.TraceEvent(TraceEventType.Verbose, 0, "Decrypted the content"); } finally { clearStream.ContentStream.Close(); } return result; } catch (CmsException cmse) { trace.TraceEvent(TraceEventType.Error, 0, "The message isn't a CMS message"); throw new InvalidMessageException("The message isn't a triple wrapped message", cmse); } }