TlsECDheKeyExchange.cs 5.3 KB

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