X509AttrCertParser.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  7. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
  8. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  9. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
  10. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
  11. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.X509
  12. {
  13. public class X509AttrCertParser
  14. {
  15. private static readonly PemParser PemAttrCertParser = new PemParser("ATTRIBUTE CERTIFICATE");
  16. private Asn1Set sData;
  17. private int sDataObjectCount;
  18. private Stream currentStream;
  19. private X509V2AttributeCertificate ReadDerCertificate(
  20. Asn1InputStream dIn)
  21. {
  22. Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject();
  23. if (seq.Count > 1 && seq[0] is DerObjectIdentifier)
  24. {
  25. if (seq[0].Equals(PkcsObjectIdentifiers.SignedData))
  26. {
  27. sData = SignedData.GetInstance(
  28. Asn1Sequence.GetInstance((Asn1TaggedObject) seq[1], true)).Certificates;
  29. return GetCertificate();
  30. }
  31. }
  32. return new X509V2AttributeCertificate(AttributeCertificate.GetInstance(seq));
  33. }
  34. private X509V2AttributeCertificate GetCertificate()
  35. {
  36. if (sData != null)
  37. {
  38. while (sDataObjectCount < sData.Count)
  39. {
  40. Asn1Encodable ae = sData[sDataObjectCount++];
  41. if (ae.ToAsn1Object() is Asn1TaggedObject t && t.TagNo == 2)
  42. {
  43. return new X509V2AttributeCertificate(
  44. AttributeCertificate.GetInstance(Asn1Sequence.GetInstance(t, false)));
  45. }
  46. }
  47. }
  48. return null;
  49. }
  50. private X509V2AttributeCertificate ReadPemCertificate(
  51. Stream inStream)
  52. {
  53. Asn1Sequence seq = PemAttrCertParser.ReadPemObject(inStream);
  54. return seq == null
  55. ? null
  56. : new X509V2AttributeCertificate(AttributeCertificate.GetInstance(seq));
  57. }
  58. /// <summary>
  59. /// Create loading data from byte array.
  60. /// </summary>
  61. /// <param name="input"></param>
  62. public X509V2AttributeCertificate ReadAttrCert(byte[] input)
  63. {
  64. return ReadAttrCert(new MemoryStream(input, false));
  65. }
  66. /// <summary>
  67. /// Create loading data from byte array.
  68. /// </summary>
  69. /// <param name="input"></param>
  70. public IList<X509V2AttributeCertificate> ReadAttrCerts(byte[] input)
  71. {
  72. return ReadAttrCerts(new MemoryStream(input, false));
  73. }
  74. /**
  75. * Generates a certificate object and initializes it with the data
  76. * read from the input stream inStream.
  77. */
  78. public X509V2AttributeCertificate ReadAttrCert(
  79. Stream inStream)
  80. {
  81. if (inStream == null)
  82. throw new ArgumentNullException("inStream");
  83. if (!inStream.CanRead)
  84. throw new ArgumentException("inStream must be read-able", "inStream");
  85. if (currentStream == null)
  86. {
  87. currentStream = inStream;
  88. sData = null;
  89. sDataObjectCount = 0;
  90. }
  91. else if (currentStream != inStream) // reset if input stream has changed
  92. {
  93. currentStream = inStream;
  94. sData = null;
  95. sDataObjectCount = 0;
  96. }
  97. try
  98. {
  99. if (sData != null)
  100. {
  101. if (sDataObjectCount != sData.Count)
  102. {
  103. return GetCertificate();
  104. }
  105. sData = null;
  106. sDataObjectCount = 0;
  107. return null;
  108. }
  109. int tag = inStream.ReadByte();
  110. if (tag < 0)
  111. return null;
  112. if (inStream.CanSeek)
  113. {
  114. inStream.Seek(-1L, SeekOrigin.Current);
  115. }
  116. else
  117. {
  118. PushbackStream pis = new PushbackStream(inStream);
  119. pis.Unread(tag);
  120. inStream = pis;
  121. }
  122. if (tag != 0x30) // assume ascii PEM encoded.
  123. {
  124. return ReadPemCertificate(inStream);
  125. }
  126. return ReadDerCertificate(new Asn1InputStream(inStream));
  127. }
  128. catch (Exception e)
  129. {
  130. throw new CertificateException(e.ToString());
  131. }
  132. }
  133. /**
  134. * Returns a (possibly empty) collection view of the certificates
  135. * read from the given input stream inStream.
  136. */
  137. public IList<X509V2AttributeCertificate> ReadAttrCerts(Stream inStream)
  138. {
  139. var attrCerts = new List<X509V2AttributeCertificate>();
  140. X509V2AttributeCertificate attrCert;
  141. while ((attrCert = ReadAttrCert(inStream)) != null)
  142. {
  143. attrCerts.Add(attrCert);
  144. }
  145. return attrCerts;
  146. }
  147. }
  148. }
  149. #pragma warning restore
  150. #endif