AbstractTlsKeyExchange.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using System.Collections;
  4. using System.IO;
  5. namespace Org.BouncyCastle.Crypto.Tls
  6. {
  7. public abstract class AbstractTlsKeyExchange
  8. : TlsKeyExchange
  9. {
  10. protected readonly int mKeyExchange;
  11. protected IList mSupportedSignatureAlgorithms;
  12. protected TlsContext mContext;
  13. protected AbstractTlsKeyExchange(int keyExchange, IList supportedSignatureAlgorithms)
  14. {
  15. this.mKeyExchange = keyExchange;
  16. this.mSupportedSignatureAlgorithms = supportedSignatureAlgorithms;
  17. }
  18. protected virtual DigitallySigned ParseSignature(Stream input)
  19. {
  20. DigitallySigned signature = DigitallySigned.Parse(mContext, input);
  21. SignatureAndHashAlgorithm signatureAlgorithm = signature.Algorithm;
  22. if (signatureAlgorithm != null)
  23. {
  24. TlsUtilities.VerifySupportedSignatureAlgorithm(mSupportedSignatureAlgorithms, signatureAlgorithm);
  25. }
  26. return signature;
  27. }
  28. public virtual void Init(TlsContext context)
  29. {
  30. this.mContext = context;
  31. ProtocolVersion clientVersion = context.ClientVersion;
  32. if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(clientVersion))
  33. {
  34. /*
  35. * RFC 5264 7.4.1.4.1. If the client does not send the signature_algorithms extension,
  36. * the server MUST do the following:
  37. *
  38. * - If the negotiated key exchange algorithm is one of (RSA, DHE_RSA, DH_RSA, RSA_PSK,
  39. * ECDH_RSA, ECDHE_RSA), behave as if client had sent the value {sha1,rsa}.
  40. *
  41. * - If the negotiated key exchange algorithm is one of (DHE_DSS, DH_DSS), behave as if
  42. * the client had sent the value {sha1,dsa}.
  43. *
  44. * - If the negotiated key exchange algorithm is one of (ECDH_ECDSA, ECDHE_ECDSA),
  45. * behave as if the client had sent value {sha1,ecdsa}.
  46. */
  47. if (this.mSupportedSignatureAlgorithms == null)
  48. {
  49. switch (mKeyExchange)
  50. {
  51. case KeyExchangeAlgorithm.DH_DSS:
  52. case KeyExchangeAlgorithm.DHE_DSS:
  53. case KeyExchangeAlgorithm.SRP_DSS:
  54. {
  55. this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultDssSignatureAlgorithms();
  56. break;
  57. }
  58. case KeyExchangeAlgorithm.ECDH_ECDSA:
  59. case KeyExchangeAlgorithm.ECDHE_ECDSA:
  60. {
  61. this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultECDsaSignatureAlgorithms();
  62. break;
  63. }
  64. case KeyExchangeAlgorithm.DH_RSA:
  65. case KeyExchangeAlgorithm.DHE_RSA:
  66. case KeyExchangeAlgorithm.ECDH_RSA:
  67. case KeyExchangeAlgorithm.ECDHE_RSA:
  68. case KeyExchangeAlgorithm.RSA:
  69. case KeyExchangeAlgorithm.RSA_PSK:
  70. case KeyExchangeAlgorithm.SRP_RSA:
  71. {
  72. this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultRsaSignatureAlgorithms();
  73. break;
  74. }
  75. case KeyExchangeAlgorithm.DHE_PSK:
  76. case KeyExchangeAlgorithm.ECDHE_PSK:
  77. case KeyExchangeAlgorithm.PSK:
  78. case KeyExchangeAlgorithm.SRP:
  79. break;
  80. default:
  81. throw new InvalidOperationException("unsupported key exchange algorithm");
  82. }
  83. }
  84. }
  85. else if (this.mSupportedSignatureAlgorithms != null)
  86. {
  87. throw new InvalidOperationException("supported_signature_algorithms not allowed for " + clientVersion);
  88. }
  89. }
  90. public abstract void SkipServerCredentials();
  91. public virtual void ProcessServerCertificate(Certificate serverCertificate)
  92. {
  93. if (mSupportedSignatureAlgorithms == null)
  94. {
  95. /*
  96. * TODO RFC 2264 7.4.2. Unless otherwise specified, the signing algorithm for the
  97. * certificate must be the same as the algorithm for the certificate key.
  98. */
  99. }
  100. else
  101. {
  102. /*
  103. * TODO RFC 5264 7.4.2. If the client provided a "signature_algorithms" extension, then
  104. * all certificates provided by the server MUST be signed by a hash/signature algorithm
  105. * pair that appears in that extension.
  106. */
  107. }
  108. }
  109. public virtual void ProcessServerCredentials(TlsCredentials serverCredentials)
  110. {
  111. ProcessServerCertificate(serverCredentials.Certificate);
  112. }
  113. public virtual bool RequiresServerKeyExchange
  114. {
  115. get { return false; }
  116. }
  117. public virtual byte[] GenerateServerKeyExchange()
  118. {
  119. if (RequiresServerKeyExchange)
  120. throw new TlsFatalAlert(AlertDescription.internal_error);
  121. return null;
  122. }
  123. public virtual void SkipServerKeyExchange()
  124. {
  125. if (RequiresServerKeyExchange)
  126. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  127. }
  128. public virtual void ProcessServerKeyExchange(Stream input)
  129. {
  130. if (!RequiresServerKeyExchange)
  131. {
  132. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  133. }
  134. }
  135. public abstract void ValidateCertificateRequest(CertificateRequest certificateRequest);
  136. public virtual void SkipClientCredentials()
  137. {
  138. }
  139. public abstract void ProcessClientCredentials(TlsCredentials clientCredentials);
  140. public virtual void ProcessClientCertificate(Certificate clientCertificate)
  141. {
  142. }
  143. public abstract void GenerateClientKeyExchange(Stream output);
  144. public virtual void ProcessClientKeyExchange(Stream input)
  145. {
  146. // Key exchange implementation MUST support client key exchange
  147. throw new TlsFatalAlert(AlertDescription.internal_error);
  148. }
  149. public abstract byte[] GeneratePremasterSecret();
  150. }
  151. }
  152. #endif