CMSEnvelopedDataParser.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cms;
  7. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  8. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Cms
  9. {
  10. /**
  11. * Parsing class for an CMS Enveloped Data object from an input stream.
  12. * <p>
  13. * Note: that because we are in a streaming mode only one recipient can be tried and it is important
  14. * that the methods on the parser are called in the appropriate order.
  15. * </p>
  16. * <p>
  17. * Example of use - assuming the first recipient matches the private key we have.
  18. * <pre>
  19. * CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(inputStream);
  20. *
  21. * RecipientInformationStore recipients = ep.GetRecipientInfos();
  22. *
  23. * Collection c = recipients.getRecipients();
  24. * Iterator it = c.iterator();
  25. *
  26. * if (it.hasNext())
  27. * {
  28. * RecipientInformation recipient = (RecipientInformation)it.next();
  29. *
  30. * CMSTypedStream recData = recipient.getContentStream(privateKey);
  31. *
  32. * processDataStream(recData.getContentStream());
  33. * }
  34. * </pre>
  35. * Note: this class does not introduce buffering - if you are processing large files you should create
  36. * the parser with:
  37. * <pre>
  38. * CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(new BufferedInputStream(inputStream, bufSize));
  39. * </pre>
  40. * where bufSize is a suitably large buffer size.
  41. * </p>
  42. */
  43. public class CmsEnvelopedDataParser
  44. : CmsContentInfoParser
  45. {
  46. internal RecipientInformationStore recipientInfoStore;
  47. internal EnvelopedDataParser envelopedData;
  48. private AlgorithmIdentifier _encAlg;
  49. private Asn1.Cms.AttributeTable _unprotectedAttributes;
  50. private bool _attrNotRead;
  51. public CmsEnvelopedDataParser(
  52. byte[] envelopedData)
  53. : this(new MemoryStream(envelopedData, false))
  54. {
  55. }
  56. public CmsEnvelopedDataParser(
  57. Stream envelopedData)
  58. : base(envelopedData)
  59. {
  60. this._attrNotRead = true;
  61. this.envelopedData = new EnvelopedDataParser(
  62. (Asn1SequenceParser)this.contentInfo.GetContent(Asn1Tags.Sequence));
  63. // TODO Validate version?
  64. //DerInteger version = this.envelopedData.Version;
  65. //
  66. // read the recipients
  67. //
  68. Asn1Set recipientInfos = Asn1Set.GetInstance(this.envelopedData.GetRecipientInfos().ToAsn1Object());
  69. //
  70. // read the encrypted content info
  71. //
  72. EncryptedContentInfoParser encInfo = this.envelopedData.GetEncryptedContentInfo();
  73. this._encAlg = encInfo.ContentEncryptionAlgorithm;
  74. CmsReadable readable = new CmsProcessableInputStream(
  75. ((Asn1OctetStringParser)encInfo.GetEncryptedContent(Asn1Tags.OctetString)).GetOctetStream());
  76. CmsSecureReadable secureReadable = new CmsEnvelopedHelper.CmsEnvelopedSecureReadable(
  77. this._encAlg, readable);
  78. //
  79. // build the RecipientInformationStore
  80. //
  81. this.recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore(
  82. recipientInfos, secureReadable);
  83. }
  84. public AlgorithmIdentifier EncryptionAlgorithmID
  85. {
  86. get { return _encAlg; }
  87. }
  88. /**
  89. * return the object identifier for the content encryption algorithm.
  90. */
  91. public string EncryptionAlgOid
  92. {
  93. get { return _encAlg.Algorithm.Id; }
  94. }
  95. /**
  96. * return the ASN.1 encoded encryption algorithm parameters, or null if
  97. * there aren't any.
  98. */
  99. public Asn1Object EncryptionAlgParams
  100. {
  101. get
  102. {
  103. Asn1Encodable ae = _encAlg.Parameters;
  104. return ae == null ? null : ae.ToAsn1Object();
  105. }
  106. }
  107. /**
  108. * return a store of the intended recipients for this message
  109. */
  110. public RecipientInformationStore GetRecipientInfos()
  111. {
  112. return this.recipientInfoStore;
  113. }
  114. /**
  115. * return a table of the unprotected attributes indexed by
  116. * the OID of the attribute.
  117. * @throws IOException
  118. */
  119. public Asn1.Cms.AttributeTable GetUnprotectedAttributes()
  120. {
  121. if (_unprotectedAttributes == null && _attrNotRead)
  122. {
  123. Asn1SetParser asn1Set = this.envelopedData.GetUnprotectedAttrs();
  124. _attrNotRead = false;
  125. if (asn1Set != null)
  126. {
  127. Asn1EncodableVector v = new Asn1EncodableVector();
  128. IAsn1Convertible o;
  129. while ((o = asn1Set.ReadObject()) != null)
  130. {
  131. Asn1SequenceParser seq = (Asn1SequenceParser)o;
  132. v.Add(seq.ToAsn1Object());
  133. }
  134. _unprotectedAttributes = new Asn1.Cms.AttributeTable(new DerSet(v));
  135. }
  136. }
  137. return _unprotectedAttributes;
  138. }
  139. }
  140. }
  141. #pragma warning restore
  142. #endif