TlsECDheKeyExchange.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
  7. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
  8. {
  9. /// <summary>(D)TLS ECDHE key exchange (see RFC 4492).</summary>
  10. public class TlsECDheKeyExchange
  11. : AbstractTlsKeyExchange
  12. {
  13. private static int CheckKeyExchange(int keyExchange)
  14. {
  15. switch (keyExchange)
  16. {
  17. case KeyExchangeAlgorithm.ECDHE_ECDSA:
  18. case KeyExchangeAlgorithm.ECDHE_RSA:
  19. return keyExchange;
  20. default:
  21. throw new ArgumentException("unsupported key exchange algorithm", "keyExchange");
  22. }
  23. }
  24. protected TlsECConfig m_ecConfig;
  25. protected TlsCredentialedSigner m_serverCredentials = null;
  26. protected TlsCertificate m_serverCertificate = null;
  27. protected TlsAgreement m_agreement;
  28. public TlsECDheKeyExchange(int keyExchange)
  29. : this(keyExchange, null)
  30. {
  31. }
  32. public TlsECDheKeyExchange(int keyExchange, TlsECConfig ecConfig)
  33. : base(CheckKeyExchange(keyExchange))
  34. {
  35. this.m_ecConfig = ecConfig;
  36. }
  37. public override void SkipServerCredentials()
  38. {
  39. throw new TlsFatalAlert(AlertDescription.internal_error);
  40. }
  41. public override void ProcessServerCredentials(TlsCredentials serverCredentials)
  42. {
  43. this.m_serverCredentials = TlsUtilities.RequireSignerCredentials(serverCredentials);
  44. }
  45. public override void ProcessServerCertificate(Certificate serverCertificate)
  46. {
  47. this.m_serverCertificate = serverCertificate.GetCertificateAt(0);
  48. }
  49. public override bool RequiresServerKeyExchange
  50. {
  51. get { return true; }
  52. }
  53. public override byte[] GenerateServerKeyExchange()
  54. {
  55. DigestInputBuffer digestBuffer = new DigestInputBuffer();
  56. TlsEccUtilities.WriteECConfig(m_ecConfig, digestBuffer);
  57. this.m_agreement = m_context.Crypto.CreateECDomain(m_ecConfig).CreateECDH();
  58. GenerateEphemeral(digestBuffer);
  59. TlsUtilities.GenerateServerKeyExchangeSignature(m_context, m_serverCredentials, null, digestBuffer);
  60. return digestBuffer.ToArray();
  61. }
  62. public override void ProcessServerKeyExchange(Stream input)
  63. {
  64. DigestInputBuffer digestBuffer = new DigestInputBuffer();
  65. Stream teeIn = new TeeInputStream(input, digestBuffer);
  66. this.m_ecConfig = TlsEccUtilities.ReceiveECDHConfig(m_context, teeIn);
  67. byte[] point = TlsUtilities.ReadOpaque8(teeIn, 1);
  68. TlsUtilities.VerifyServerKeyExchangeSignature(m_context, input, m_serverCertificate, null, digestBuffer);
  69. this.m_agreement = m_context.Crypto.CreateECDomain(m_ecConfig).CreateECDH();
  70. ProcessEphemeral(point);
  71. }
  72. public override short[] GetClientCertificateTypes()
  73. {
  74. /*
  75. * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with
  76. * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because
  77. * the use of a long-term ECDH client key would jeopardize the forward secrecy property of
  78. * these algorithms.
  79. */
  80. return new short[]{ ClientCertificateType.dss_sign, ClientCertificateType.ecdsa_sign,
  81. ClientCertificateType.rsa_sign };
  82. }
  83. public override void ProcessClientCredentials(TlsCredentials clientCredentials)
  84. {
  85. TlsUtilities.RequireSignerCredentials(clientCredentials);
  86. }
  87. public override void GenerateClientKeyExchange(Stream output)
  88. {
  89. GenerateEphemeral(output);
  90. }
  91. public override void ProcessClientKeyExchange(Stream input)
  92. {
  93. byte[] point = TlsUtilities.ReadOpaque8(input, 1);
  94. ProcessEphemeral(point);
  95. }
  96. public override TlsSecret GeneratePreMasterSecret()
  97. {
  98. return m_agreement.CalculateSecret();
  99. }
  100. protected virtual void GenerateEphemeral(Stream output)
  101. {
  102. byte[] point = m_agreement.GenerateEphemeral();
  103. TlsUtilities.WriteOpaque8(point, output);
  104. }
  105. protected virtual void ProcessEphemeral(byte[] point)
  106. {
  107. TlsEccUtilities.CheckPointEncoding(m_ecConfig.NamedGroup, point);
  108. this.m_agreement.ReceivePeerValue(point);
  109. }
  110. }
  111. }
  112. #pragma warning restore
  113. #endif