BcTlsDHDomain.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement;
  7. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators;
  8. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  9. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
  10. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  11. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
  12. {
  13. /// <summary>BC light-weight support class for Diffie-Hellman key pair generation and key agreement over a
  14. /// specified Diffie-Hellman configuration.</summary>
  15. public class BcTlsDHDomain
  16. : TlsDHDomain
  17. {
  18. private static byte[] EncodeValue(DHParameters dh, bool padded, BigInteger x)
  19. {
  20. return padded
  21. ? BigIntegers.AsUnsignedByteArray(GetValueLength(dh), x)
  22. : BigIntegers.AsUnsignedByteArray(x);
  23. }
  24. private static int GetValueLength(DHParameters dh)
  25. {
  26. return BigIntegers.GetUnsignedByteLength(dh.P);
  27. }
  28. public static BcTlsSecret CalculateDHAgreement(BcTlsCrypto crypto, DHPrivateKeyParameters privateKey,
  29. DHPublicKeyParameters publicKey, bool padded)
  30. {
  31. DHBasicAgreement basicAgreement = new DHBasicAgreement();
  32. basicAgreement.Init(privateKey);
  33. BigInteger agreementValue = basicAgreement.CalculateAgreement(publicKey);
  34. byte[] secret = EncodeValue(privateKey.Parameters, padded, agreementValue);
  35. return crypto.AdoptLocalSecret(secret);
  36. }
  37. public static DHParameters GetDomainParameters(TlsDHConfig dhConfig)
  38. {
  39. DHGroup dhGroup = TlsDHUtilities.GetDHGroup(dhConfig);
  40. if (dhGroup == null)
  41. throw new ArgumentException("No DH configuration provided");
  42. return new DHParameters(dhGroup.P, dhGroup.G, dhGroup.Q, dhGroup.L);
  43. }
  44. protected readonly BcTlsCrypto m_crypto;
  45. protected readonly TlsDHConfig m_config;
  46. protected readonly DHParameters m_domainParameters;
  47. public BcTlsDHDomain(BcTlsCrypto crypto, TlsDHConfig dhConfig)
  48. {
  49. this.m_crypto = crypto;
  50. this.m_config = dhConfig;
  51. this.m_domainParameters = GetDomainParameters(dhConfig);
  52. }
  53. public virtual BcTlsSecret CalculateDHAgreement(DHPrivateKeyParameters privateKey,
  54. DHPublicKeyParameters publicKey)
  55. {
  56. return CalculateDHAgreement(m_crypto, privateKey, publicKey, m_config.IsPadded);
  57. }
  58. public virtual TlsAgreement CreateDH()
  59. {
  60. return new BcTlsDH(this);
  61. }
  62. /// <exception cref="IOException"/>
  63. public virtual BigInteger DecodeParameter(byte[] encoding)
  64. {
  65. if (m_config.IsPadded && GetValueLength(m_domainParameters) != encoding.Length)
  66. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  67. return new BigInteger(1, encoding);
  68. }
  69. /// <exception cref="IOException"/>
  70. public virtual DHPublicKeyParameters DecodePublicKey(byte[] encoding)
  71. {
  72. /*
  73. * RFC 7919 3. [..] the client MUST verify that dh_Ys is in the range 1 < dh_Ys < dh_p - 1.
  74. * If dh_Ys is not in this range, the client MUST terminate the connection with a fatal
  75. * handshake_failure(40) alert.
  76. */
  77. try
  78. {
  79. BigInteger y = DecodeParameter(encoding);
  80. return new DHPublicKeyParameters(y, m_domainParameters);
  81. }
  82. catch (Exception e)
  83. {
  84. throw new TlsFatalAlert(AlertDescription.handshake_failure, e);
  85. }
  86. }
  87. public virtual byte[] EncodeParameter(BigInteger x)
  88. {
  89. return EncodeValue(m_domainParameters, m_config.IsPadded, x);
  90. }
  91. public virtual byte[] EncodePublicKey(DHPublicKeyParameters publicKey)
  92. {
  93. return EncodeValue(m_domainParameters, true, publicKey.Y);
  94. }
  95. public virtual AsymmetricCipherKeyPair GenerateKeyPair()
  96. {
  97. DHBasicKeyPairGenerator keyPairGenerator = new DHBasicKeyPairGenerator();
  98. keyPairGenerator.Init(new DHKeyGenerationParameters(m_crypto.SecureRandom, m_domainParameters));
  99. return keyPairGenerator.GenerateKeyPair();
  100. }
  101. }
  102. }
  103. #pragma warning restore
  104. #endif