TlsSrpKeyExchange.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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.Math;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
  9. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
  10. {
  11. /// <summary>(D)TLS SRP key exchange (RFC 5054).</summary>
  12. public class TlsSrpKeyExchange
  13. : AbstractTlsKeyExchange
  14. {
  15. private static int CheckKeyExchange(int keyExchange)
  16. {
  17. switch (keyExchange)
  18. {
  19. case KeyExchangeAlgorithm.SRP:
  20. case KeyExchangeAlgorithm.SRP_DSS:
  21. case KeyExchangeAlgorithm.SRP_RSA:
  22. return keyExchange;
  23. default:
  24. throw new ArgumentException("unsupported key exchange algorithm", "keyExchange");
  25. }
  26. }
  27. protected TlsSrpIdentity m_srpIdentity;
  28. protected TlsSrpConfigVerifier m_srpConfigVerifier;
  29. protected TlsCertificate m_serverCertificate = null;
  30. protected byte[] m_srpSalt = null;
  31. protected TlsSrp6Client m_srpClient = null;
  32. protected TlsSrpLoginParameters m_srpLoginParameters;
  33. protected TlsCredentialedSigner m_serverCredentials = null;
  34. protected TlsSrp6Server m_srpServer = null;
  35. protected BigInteger m_srpPeerCredentials = null;
  36. public TlsSrpKeyExchange(int keyExchange, TlsSrpIdentity srpIdentity, TlsSrpConfigVerifier srpConfigVerifier)
  37. : base(CheckKeyExchange(keyExchange))
  38. {
  39. this.m_srpIdentity = srpIdentity;
  40. this.m_srpConfigVerifier = srpConfigVerifier;
  41. }
  42. public TlsSrpKeyExchange(int keyExchange, TlsSrpLoginParameters srpLoginParameters)
  43. : base(CheckKeyExchange(keyExchange))
  44. {
  45. this.m_srpLoginParameters = srpLoginParameters;
  46. }
  47. public override void SkipServerCredentials()
  48. {
  49. if (m_keyExchange != KeyExchangeAlgorithm.SRP)
  50. throw new TlsFatalAlert(AlertDescription.internal_error);
  51. }
  52. public override void ProcessServerCredentials(TlsCredentials serverCredentials)
  53. {
  54. if (m_keyExchange == KeyExchangeAlgorithm.SRP)
  55. throw new TlsFatalAlert(AlertDescription.internal_error);
  56. this.m_serverCredentials = TlsUtilities.RequireSignerCredentials(serverCredentials);
  57. }
  58. public override void ProcessServerCertificate(Certificate serverCertificate)
  59. {
  60. if (m_keyExchange == KeyExchangeAlgorithm.SRP)
  61. throw new TlsFatalAlert(AlertDescription.internal_error);
  62. this.m_serverCertificate = serverCertificate.GetCertificateAt(0);
  63. }
  64. public override bool RequiresServerKeyExchange
  65. {
  66. get { return true; }
  67. }
  68. public override byte[] GenerateServerKeyExchange()
  69. {
  70. TlsSrpConfig config = m_srpLoginParameters.Config;
  71. this.m_srpServer = m_context.Crypto.CreateSrp6Server(config, m_srpLoginParameters.Verifier);
  72. BigInteger B = m_srpServer.GenerateServerCredentials();
  73. BigInteger[] ng = config.GetExplicitNG();
  74. ServerSrpParams srpParams = new ServerSrpParams(ng[0], ng[1], m_srpLoginParameters.Salt, B);
  75. DigestInputBuffer digestBuffer = new DigestInputBuffer();
  76. srpParams.Encode(digestBuffer);
  77. if (m_serverCredentials != null)
  78. {
  79. TlsUtilities.GenerateServerKeyExchangeSignature(m_context, m_serverCredentials, null, digestBuffer);
  80. }
  81. return digestBuffer.ToArray();
  82. }
  83. public override void ProcessServerKeyExchange(Stream input)
  84. {
  85. DigestInputBuffer digestBuffer = null;
  86. Stream teeIn = input;
  87. if (m_keyExchange != KeyExchangeAlgorithm.SRP)
  88. {
  89. digestBuffer = new DigestInputBuffer();
  90. teeIn = new TeeInputStream(input, digestBuffer);
  91. }
  92. ServerSrpParams srpParams = ServerSrpParams.Parse(teeIn);
  93. if (digestBuffer != null)
  94. {
  95. TlsUtilities.VerifyServerKeyExchangeSignature(m_context, input, m_serverCertificate, null,
  96. digestBuffer);
  97. }
  98. TlsSrpConfig config = new TlsSrpConfig();
  99. config.SetExplicitNG(new BigInteger[]{ srpParams.N, srpParams.G });
  100. if (!m_srpConfigVerifier.Accept(config))
  101. throw new TlsFatalAlert(AlertDescription.insufficient_security);
  102. this.m_srpSalt = srpParams.S;
  103. /*
  104. * RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter" alert if
  105. * B % N = 0.
  106. */
  107. this.m_srpPeerCredentials = ValidatePublicValue(srpParams.N, srpParams.B);
  108. this.m_srpClient = m_context.Crypto.CreateSrp6Client(config);
  109. }
  110. public override void ProcessClientCredentials(TlsCredentials clientCredentials)
  111. {
  112. throw new TlsFatalAlert(AlertDescription.internal_error);
  113. }
  114. public override void GenerateClientKeyExchange(Stream output)
  115. {
  116. byte[] identity = m_srpIdentity.GetSrpIdentity();
  117. byte[] password = m_srpIdentity.GetSrpPassword();
  118. BigInteger A = m_srpClient.GenerateClientCredentials(m_srpSalt, identity, password);
  119. TlsSrpUtilities.WriteSrpParameter(A, output);
  120. m_context.SecurityParameters.m_srpIdentity = Arrays.Clone(identity);
  121. }
  122. public override void ProcessClientKeyExchange(Stream input)
  123. {
  124. /*
  125. * RFC 5054 2.5.4: The server MUST abort the handshake with an "illegal_parameter" alert if
  126. * A % N = 0.
  127. */
  128. this.m_srpPeerCredentials = ValidatePublicValue(m_srpLoginParameters.Config.GetExplicitNG()[0],
  129. TlsSrpUtilities.ReadSrpParameter(input));
  130. m_context.SecurityParameters.m_srpIdentity = Arrays.Clone(m_srpLoginParameters.Identity);
  131. }
  132. public override TlsSecret GeneratePreMasterSecret()
  133. {
  134. BigInteger S = m_srpServer != null
  135. ? m_srpServer.CalculateSecret(m_srpPeerCredentials)
  136. : m_srpClient.CalculateSecret(m_srpPeerCredentials);
  137. // TODO Check if this needs to be a fixed size
  138. return m_context.Crypto.CreateSecret(BigIntegers.AsUnsignedByteArray(S));
  139. }
  140. protected static BigInteger ValidatePublicValue(BigInteger N, BigInteger val)
  141. {
  142. val = val.Mod(N);
  143. // Check that val % N != 0
  144. if (val.Equals(BigInteger.Zero))
  145. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  146. return val;
  147. }
  148. }
  149. }
  150. #pragma warning restore
  151. #endif