CertificateRequest.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using System.IO;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  9. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Tls
  10. {
  11. /**
  12. * Parsing and encoding of a <i>CertificateRequest</i> struct from RFC 4346.
  13. * <p/>
  14. * <pre>
  15. * struct {
  16. * ClientCertificateType certificate_types&lt;1..2^8-1&gt;;
  17. * DistinguishedName certificate_authorities&lt;3..2^16-1&gt;
  18. * } CertificateRequest;
  19. * </pre>
  20. *
  21. * @see ClientCertificateType
  22. * @see X509Name
  23. */
  24. public class CertificateRequest
  25. {
  26. protected readonly byte[] mCertificateTypes;
  27. protected readonly IList mSupportedSignatureAlgorithms;
  28. protected readonly IList mCertificateAuthorities;
  29. /**
  30. * @param certificateTypes see {@link ClientCertificateType} for valid constants.
  31. * @param certificateAuthorities an {@link IList} of {@link X509Name}.
  32. */
  33. public CertificateRequest(byte[] certificateTypes, IList supportedSignatureAlgorithms,
  34. IList certificateAuthorities)
  35. {
  36. this.mCertificateTypes = certificateTypes;
  37. this.mSupportedSignatureAlgorithms = supportedSignatureAlgorithms;
  38. this.mCertificateAuthorities = certificateAuthorities;
  39. }
  40. /**
  41. * @return an array of certificate types
  42. * @see {@link ClientCertificateType}
  43. */
  44. public virtual byte[] CertificateTypes
  45. {
  46. get { return mCertificateTypes; }
  47. }
  48. /**
  49. * @return an {@link IList} of {@link SignatureAndHashAlgorithm} (or null before TLS 1.2).
  50. */
  51. public virtual IList SupportedSignatureAlgorithms
  52. {
  53. get { return mSupportedSignatureAlgorithms; }
  54. }
  55. /**
  56. * @return an {@link IList} of {@link X509Name}
  57. */
  58. public virtual IList CertificateAuthorities
  59. {
  60. get { return mCertificateAuthorities; }
  61. }
  62. /**
  63. * Encode this {@link CertificateRequest} to a {@link Stream}.
  64. *
  65. * @param output the {@link Stream} to encode to.
  66. * @throws IOException
  67. */
  68. public virtual void Encode(Stream output)
  69. {
  70. if (mCertificateTypes == null || mCertificateTypes.Length == 0)
  71. {
  72. TlsUtilities.WriteUint8(0, output);
  73. }
  74. else
  75. {
  76. TlsUtilities.WriteUint8ArrayWithUint8Length(mCertificateTypes, output);
  77. }
  78. if (mSupportedSignatureAlgorithms != null)
  79. {
  80. // TODO Check whether SignatureAlgorithm.anonymous is allowed here
  81. TlsUtilities.EncodeSupportedSignatureAlgorithms(mSupportedSignatureAlgorithms, false, output);
  82. }
  83. if (mCertificateAuthorities == null || mCertificateAuthorities.Count < 1)
  84. {
  85. TlsUtilities.WriteUint16(0, output);
  86. }
  87. else
  88. {
  89. IList derEncodings = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList(mCertificateAuthorities.Count);
  90. int totalLength = 0;
  91. foreach (Asn1Encodable certificateAuthority in mCertificateAuthorities)
  92. {
  93. byte[] derEncoding = certificateAuthority.GetEncoded(Asn1Encodable.Der);
  94. derEncodings.Add(derEncoding);
  95. totalLength += derEncoding.Length + 2;
  96. }
  97. TlsUtilities.CheckUint16(totalLength);
  98. TlsUtilities.WriteUint16(totalLength, output);
  99. foreach (byte[] derEncoding in derEncodings)
  100. {
  101. TlsUtilities.WriteOpaque16(derEncoding, output);
  102. }
  103. }
  104. }
  105. /**
  106. * Parse a {@link CertificateRequest} from a {@link Stream}.
  107. *
  108. * @param context
  109. * the {@link TlsContext} of the current connection.
  110. * @param input
  111. * the {@link Stream} to parse from.
  112. * @return a {@link CertificateRequest} object.
  113. * @throws IOException
  114. */
  115. public static CertificateRequest Parse(TlsContext context, Stream input)
  116. {
  117. int numTypes = TlsUtilities.ReadUint8(input);
  118. byte[] certificateTypes = new byte[numTypes];
  119. for (int i = 0; i < numTypes; ++i)
  120. {
  121. certificateTypes[i] = TlsUtilities.ReadUint8(input);
  122. }
  123. IList supportedSignatureAlgorithms = null;
  124. if (TlsUtilities.IsTlsV12(context))
  125. {
  126. // TODO Check whether SignatureAlgorithm.anonymous is allowed here
  127. supportedSignatureAlgorithms = TlsUtilities.ParseSupportedSignatureAlgorithms(false, input);
  128. }
  129. IList certificateAuthorities = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
  130. byte[] certAuthData = TlsUtilities.ReadOpaque16(input);
  131. MemoryStream bis = new MemoryStream(certAuthData, false);
  132. while (bis.Position < bis.Length)
  133. {
  134. byte[] derEncoding = TlsUtilities.ReadOpaque16(bis);
  135. Asn1Object asn1 = TlsUtilities.ReadDerObject(derEncoding);
  136. // TODO Switch to X500Name when available
  137. certificateAuthorities.Add(X509Name.GetInstance(asn1));
  138. }
  139. return new CertificateRequest(certificateTypes, supportedSignatureAlgorithms, certificateAuthorities);
  140. }
  141. }
  142. }
  143. #pragma warning restore
  144. #endif