BcX25519.cs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Rfc7748;
  5. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
  6. {
  7. /// <summary>Support class for X25519 using the BC light-weight library.</summary>
  8. public class BcX25519
  9. : TlsAgreement
  10. {
  11. protected readonly BcTlsCrypto m_crypto;
  12. protected readonly byte[] m_privateKey = new byte[X25519.ScalarSize];
  13. protected readonly byte[] m_peerPublicKey = new byte[X25519.PointSize];
  14. public BcX25519(BcTlsCrypto crypto)
  15. {
  16. this.m_crypto = crypto;
  17. }
  18. public virtual byte[] GenerateEphemeral()
  19. {
  20. m_crypto.SecureRandom.NextBytes(m_privateKey);
  21. byte[] publicKey = new byte[X25519.PointSize];
  22. X25519.ScalarMultBase(m_privateKey, 0, publicKey, 0);
  23. return publicKey;
  24. }
  25. public virtual void ReceivePeerValue(byte[] peerValue)
  26. {
  27. if (peerValue == null || peerValue.Length != X25519.PointSize)
  28. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  29. Array.Copy(peerValue, 0, m_peerPublicKey, 0, X25519.PointSize);
  30. }
  31. public virtual TlsSecret CalculateSecret()
  32. {
  33. try
  34. {
  35. byte[] secret = new byte[X25519.PointSize];
  36. if (!X25519.CalculateAgreement(m_privateKey, 0, m_peerPublicKey, 0, secret, 0))
  37. throw new TlsFatalAlert(AlertDescription.handshake_failure);
  38. return m_crypto.AdoptLocalSecret(secret);
  39. }
  40. finally
  41. {
  42. Array.Clear(m_privateKey, 0, m_privateKey.Length);
  43. Array.Clear(m_peerPublicKey, 0, m_peerPublicKey.Length);
  44. }
  45. }
  46. }
  47. }
  48. #pragma warning restore
  49. #endif