From 176743ab5faec2dd275b5efd3a2dd62c610f237a Mon Sep 17 00:00:00 2001 From: Oren Novotny Date: Wed, 26 Feb 2014 10:08:50 -0500 Subject: Add BouncyCastle PCL files --- Crypto/src/cms/CMSEnvelopedDataParser.cs | 161 +++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 Crypto/src/cms/CMSEnvelopedDataParser.cs (limited to 'Crypto/src/cms/CMSEnvelopedDataParser.cs') diff --git a/Crypto/src/cms/CMSEnvelopedDataParser.cs b/Crypto/src/cms/CMSEnvelopedDataParser.cs new file mode 100644 index 000000000..01a949d47 --- /dev/null +++ b/Crypto/src/cms/CMSEnvelopedDataParser.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Cms +{ + /** + * Parsing class for an CMS Enveloped Data object from an input stream. + *

+ * Note: that because we are in a streaming mode only one recipient can be tried and it is important + * that the methods on the parser are called in the appropriate order. + *

+ *

+ * Example of use - assuming the first recipient matches the private key we have. + *

+	*      CmsEnvelopedDataParser     ep = new CmsEnvelopedDataParser(inputStream);
+	*
+	*      RecipientInformationStore  recipients = ep.GetRecipientInfos();
+	*
+	*      Collection  c = recipients.getRecipients();
+	*      Iterator    it = c.iterator();
+	*
+	*      if (it.hasNext())
+	*      {
+	*          RecipientInformation   recipient = (RecipientInformation)it.next();
+	*
+	*          CMSTypedStream recData = recipient.getContentStream(privateKey);
+	*
+	*          processDataStream(recData.getContentStream());
+	*      }
+	*  
+ * Note: this class does not introduce buffering - if you are processing large files you should create + * the parser with: + *
+	*          CmsEnvelopedDataParser     ep = new CmsEnvelopedDataParser(new BufferedInputStream(inputStream, bufSize));
+	*  
+ * where bufSize is a suitably large buffer size. + *

+ */ + public class CmsEnvelopedDataParser + : CmsContentInfoParser + { + internal RecipientInformationStore recipientInfoStore; + internal EnvelopedDataParser envelopedData; + + private AlgorithmIdentifier _encAlg; + private Asn1.Cms.AttributeTable _unprotectedAttributes; + private bool _attrNotRead; + + public CmsEnvelopedDataParser( + byte[] envelopedData) + : this(new MemoryStream(envelopedData, false)) + { + } + + public CmsEnvelopedDataParser( + Stream envelopedData) + : base(envelopedData) + { + this._attrNotRead = true; + this.envelopedData = new EnvelopedDataParser( + (Asn1SequenceParser)this.contentInfo.GetContent(Asn1Tags.Sequence)); + + // TODO Validate version? + //DerInteger version = this.envelopedData.Version; + + // + // read the recipients + // + Asn1Set recipientInfos = Asn1Set.GetInstance(this.envelopedData.GetRecipientInfos().ToAsn1Object()); + + // + // read the encrypted content info + // + EncryptedContentInfoParser encInfo = this.envelopedData.GetEncryptedContentInfo(); + this._encAlg = encInfo.ContentEncryptionAlgorithm; + CmsReadable readable = new CmsProcessableInputStream( + ((Asn1OctetStringParser)encInfo.GetEncryptedContent(Asn1Tags.OctetString)).GetOctetStream()); + CmsSecureReadable secureReadable = new CmsEnvelopedHelper.CmsEnvelopedSecureReadable( + this._encAlg, readable); + + // + // build the RecipientInformationStore + // + this.recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore( + recipientInfos, secureReadable); + } + + public AlgorithmIdentifier EncryptionAlgorithmID + { + get { return _encAlg; } + } + + /** + * return the object identifier for the content encryption algorithm. + */ + public string EncryptionAlgOid + { + get { return _encAlg.ObjectID.Id; } + } + + /** + * return the ASN.1 encoded encryption algorithm parameters, or null if + * there aren't any. + */ + public Asn1Object EncryptionAlgParams + { + get + { + Asn1Encodable ae = _encAlg.Parameters; + + return ae == null ? null : ae.ToAsn1Object(); + } + } + + /** + * return a store of the intended recipients for this message + */ + public RecipientInformationStore GetRecipientInfos() + { + return this.recipientInfoStore; + } + + /** + * return a table of the unprotected attributes indexed by + * the OID of the attribute. + * @throws IOException + */ + public Asn1.Cms.AttributeTable GetUnprotectedAttributes() + { + if (_unprotectedAttributes == null && _attrNotRead) + { + Asn1SetParser asn1Set = this.envelopedData.GetUnprotectedAttrs(); + + _attrNotRead = false; + + if (asn1Set != null) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + IAsn1Convertible o; + + while ((o = asn1Set.ReadObject()) != null) + { + Asn1SequenceParser seq = (Asn1SequenceParser)o; + + v.Add(seq.ToAsn1Object()); + } + + _unprotectedAttributes = new Asn1.Cms.AttributeTable(new DerSet(v)); + } + } + + return _unprotectedAttributes; + } + } +} -- cgit 1.5.1