TlsECDheKeyExchange.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using System.IO;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
  11. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Tls
  12. {
  13. /// <summary>(D)TLS ECDHE key exchange (see RFC 4492).</summary>
  14. public class TlsECDheKeyExchange
  15. : TlsECDHKeyExchange
  16. {
  17. protected TlsSignerCredentials mServerCredentials = null;
  18. public TlsECDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, int[] namedCurves,
  19. byte[] clientECPointFormats, byte[] serverECPointFormats)
  20. : base(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats)
  21. {
  22. }
  23. public override void ProcessServerCredentials(TlsCredentials serverCredentials)
  24. {
  25. if (!(serverCredentials is TlsSignerCredentials))
  26. throw new TlsFatalAlert(AlertDescription.internal_error);
  27. ProcessServerCertificate(serverCredentials.Certificate);
  28. this.mServerCredentials = (TlsSignerCredentials)serverCredentials;
  29. }
  30. public override byte[] GenerateServerKeyExchange()
  31. {
  32. DigestInputBuffer buf = new DigestInputBuffer();
  33. this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves,
  34. mClientECPointFormats, buf);
  35. /*
  36. * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
  37. */
  38. SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(
  39. mContext, mServerCredentials);
  40. IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm);
  41. SecurityParameters securityParameters = mContext.SecurityParameters;
  42. d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
  43. d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
  44. buf.UpdateDigest(d);
  45. byte[] hash = DigestUtilities.DoFinal(d);
  46. byte[] signature = mServerCredentials.GenerateCertificateSignature(hash);
  47. DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature);
  48. signed_params.Encode(buf);
  49. return buf.ToArray();
  50. }
  51. public override void ProcessServerKeyExchange(Stream input)
  52. {
  53. SecurityParameters securityParameters = mContext.SecurityParameters;
  54. SignerInputBuffer buf = new SignerInputBuffer();
  55. Stream teeIn = new TeeInputStream(input, buf);
  56. ECDomainParameters curve_params = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, teeIn);
  57. byte[] point = TlsUtilities.ReadOpaque8(teeIn);
  58. DigitallySigned signed_params = ParseSignature(input);
  59. ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters);
  60. buf.UpdateSigner(signer);
  61. if (!signer.VerifySignature(signed_params.Signature))
  62. throw new TlsFatalAlert(AlertDescription.decrypt_error);
  63. this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(
  64. mClientECPointFormats, curve_params, point));
  65. }
  66. public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
  67. {
  68. /*
  69. * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with
  70. * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because
  71. * the use of a long-term ECDH client key would jeopardize the forward secrecy property of
  72. * these algorithms.
  73. */
  74. byte[] types = certificateRequest.CertificateTypes;
  75. for (int i = 0; i < types.Length; ++i)
  76. {
  77. switch (types[i])
  78. {
  79. case ClientCertificateType.rsa_sign:
  80. case ClientCertificateType.dss_sign:
  81. case ClientCertificateType.ecdsa_sign:
  82. break;
  83. default:
  84. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  85. }
  86. }
  87. }
  88. public override void ProcessClientCredentials(TlsCredentials clientCredentials)
  89. {
  90. if (clientCredentials is TlsSignerCredentials)
  91. {
  92. // OK
  93. }
  94. else
  95. {
  96. throw new TlsFatalAlert(AlertDescription.internal_error);
  97. }
  98. }
  99. protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm,
  100. SecurityParameters securityParameters)
  101. {
  102. ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey);
  103. signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
  104. signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
  105. return signer;
  106. }
  107. }
  108. }
  109. #pragma warning restore
  110. #endif