Certificate.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using System.Collections;
  4. using System.IO;
  5. using Org.BouncyCastle.Asn1;
  6. using Org.BouncyCastle.Asn1.X509;
  7. using Org.BouncyCastle.Utilities;
  8. namespace Org.BouncyCastle.Crypto.Tls
  9. {
  10. /**
  11. * Parsing and encoding of a <i>Certificate</i> struct from RFC 4346.
  12. * <p/>
  13. * <pre>
  14. * opaque ASN.1Cert&lt;2^24-1&gt;;
  15. *
  16. * struct {
  17. * ASN.1Cert certificate_list&lt;0..2^24-1&gt;;
  18. * } Certificate;
  19. * </pre>
  20. *
  21. * @see Org.BouncyCastle.Asn1.X509.X509CertificateStructure
  22. */
  23. public class Certificate
  24. {
  25. public static readonly Certificate EmptyChain = new Certificate(new X509CertificateStructure[0]);
  26. /**
  27. * The certificates.
  28. */
  29. protected readonly X509CertificateStructure[] mCertificateList;
  30. public Certificate(X509CertificateStructure[] certificateList)
  31. {
  32. if (certificateList == null)
  33. throw new ArgumentNullException("certificateList");
  34. this.mCertificateList = certificateList;
  35. }
  36. /**
  37. * @return an array of {@link org.bouncycastle.asn1.x509.Certificate} representing a certificate
  38. * chain.
  39. */
  40. public virtual X509CertificateStructure[] GetCertificateList()
  41. {
  42. return CloneCertificateList();
  43. }
  44. public virtual X509CertificateStructure GetCertificateAt(int index)
  45. {
  46. return mCertificateList[index];
  47. }
  48. public virtual int Length
  49. {
  50. get { return mCertificateList.Length; }
  51. }
  52. /**
  53. * @return <code>true</code> if this certificate chain contains no certificates, or
  54. * <code>false</code> otherwise.
  55. */
  56. public virtual bool IsEmpty
  57. {
  58. get { return mCertificateList.Length == 0; }
  59. }
  60. /**
  61. * Encode this {@link Certificate} to a {@link Stream}.
  62. *
  63. * @param output the {@link Stream} to encode to.
  64. * @throws IOException
  65. */
  66. public virtual void Encode(Stream output)
  67. {
  68. IList derEncodings = Org.BouncyCastle.Utilities.Platform.CreateArrayList(mCertificateList.Length);
  69. int totalLength = 0;
  70. foreach (Asn1Encodable asn1Cert in mCertificateList)
  71. {
  72. byte[] derEncoding = asn1Cert.GetEncoded(Asn1Encodable.Der);
  73. derEncodings.Add(derEncoding);
  74. totalLength += derEncoding.Length + 3;
  75. }
  76. TlsUtilities.CheckUint24(totalLength);
  77. TlsUtilities.WriteUint24(totalLength, output);
  78. foreach (byte[] derEncoding in derEncodings)
  79. {
  80. TlsUtilities.WriteOpaque24(derEncoding, output);
  81. }
  82. }
  83. /**
  84. * Parse a {@link Certificate} from a {@link Stream}.
  85. *
  86. * @param input the {@link Stream} to parse from.
  87. * @return a {@link Certificate} object.
  88. * @throws IOException
  89. */
  90. public static Certificate Parse(Stream input)
  91. {
  92. int totalLength = TlsUtilities.ReadUint24(input);
  93. if (totalLength == 0)
  94. {
  95. return EmptyChain;
  96. }
  97. byte[] certListData = TlsUtilities.ReadFully(totalLength, input);
  98. MemoryStream buf = new MemoryStream(certListData, false);
  99. IList certificate_list = Org.BouncyCastle.Utilities.Platform.CreateArrayList();
  100. while (buf.Position < buf.Length)
  101. {
  102. byte[] derEncoding = TlsUtilities.ReadOpaque24(buf);
  103. Asn1Object asn1Cert = TlsUtilities.ReadDerObject(derEncoding);
  104. certificate_list.Add(X509CertificateStructure.GetInstance(asn1Cert));
  105. }
  106. X509CertificateStructure[] certificateList = new X509CertificateStructure[certificate_list.Count];
  107. for (int i = 0; i < certificate_list.Count; ++i)
  108. {
  109. certificateList[i] = (X509CertificateStructure)certificate_list[i];
  110. }
  111. return new Certificate(certificateList);
  112. }
  113. protected virtual X509CertificateStructure[] CloneCertificateList()
  114. {
  115. return (X509CertificateStructure[])mCertificateList.Clone();
  116. }
  117. }
  118. }
  119. #endif