BcTlsDHDomain.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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.Crypto;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  11. namespace BestHTTP.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 (dh.P.BitLength + 7) / 8;
  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 GetParameters(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 crypto;
  45. protected readonly TlsDHConfig dhConfig;
  46. protected readonly DHParameters dhParameters;
  47. public BcTlsDHDomain(BcTlsCrypto crypto, TlsDHConfig dhConfig)
  48. {
  49. this.crypto = crypto;
  50. this.dhConfig = dhConfig;
  51. this.dhParameters = GetParameters(dhConfig);
  52. }
  53. public virtual BcTlsSecret CalculateDHAgreement(DHPrivateKeyParameters privateKey,
  54. DHPublicKeyParameters publicKey)
  55. {
  56. return CalculateDHAgreement(crypto, privateKey, publicKey, dhConfig.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 (dhConfig.IsPadded && GetValueLength(dhParameters) != 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, dhParameters);
  81. }
  82. catch (Exception e)
  83. {
  84. throw new TlsFatalAlert(AlertDescription.handshake_failure, e);
  85. }
  86. }
  87. /// <exception cref="IOException"/>
  88. public virtual byte[] EncodeParameter(BigInteger x)
  89. {
  90. return EncodeValue(dhParameters, dhConfig.IsPadded, x);
  91. }
  92. /// <exception cref="IOException"/>
  93. public virtual byte[] EncodePublicKey(DHPublicKeyParameters publicKey)
  94. {
  95. return EncodeValue(dhParameters, true, publicKey.Y);
  96. }
  97. public virtual AsymmetricCipherKeyPair GenerateKeyPair()
  98. {
  99. DHBasicKeyPairGenerator keyPairGenerator = new DHBasicKeyPairGenerator();
  100. keyPairGenerator.Init(new DHKeyGenerationParameters(crypto.SecureRandom, dhParameters));
  101. return keyPairGenerator.GenerateKeyPair();
  102. }
  103. }
  104. }
  105. #pragma warning restore
  106. #endif