AbstractTlsContext.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using System.Threading;
  4. using Org.BouncyCastle.Crypto.Prng;
  5. using Org.BouncyCastle.Security;
  6. using Org.BouncyCastle.Utilities;
  7. namespace Org.BouncyCastle.Crypto.Tls
  8. {
  9. internal abstract class AbstractTlsContext
  10. : TlsContext
  11. {
  12. private static long counter = Times.NanoTime();
  13. #if NETCF_1_0
  14. private static object counterLock = new object();
  15. private static long NextCounterValue()
  16. {
  17. lock (counterLock)
  18. {
  19. return ++counter;
  20. }
  21. }
  22. #else
  23. private static long NextCounterValue()
  24. {
  25. return Interlocked.Increment(ref counter);
  26. }
  27. #endif
  28. private readonly IRandomGenerator mNonceRandom;
  29. private readonly SecureRandom mSecureRandom;
  30. private readonly SecurityParameters mSecurityParameters;
  31. private ProtocolVersion mClientVersion = null;
  32. private ProtocolVersion mServerVersion = null;
  33. private TlsSession mSession = null;
  34. private object mUserObject = null;
  35. internal AbstractTlsContext(SecureRandom secureRandom, SecurityParameters securityParameters)
  36. {
  37. IDigest d = TlsUtilities.CreateHash(HashAlgorithm.sha256);
  38. byte[] seed = new byte[d.GetDigestSize()];
  39. secureRandom.NextBytes(seed);
  40. this.mNonceRandom = new DigestRandomGenerator(d);
  41. mNonceRandom.AddSeedMaterial(NextCounterValue());
  42. mNonceRandom.AddSeedMaterial(Times.NanoTime());
  43. mNonceRandom.AddSeedMaterial(seed);
  44. this.mSecureRandom = secureRandom;
  45. this.mSecurityParameters = securityParameters;
  46. }
  47. public virtual IRandomGenerator NonceRandomGenerator
  48. {
  49. get { return mNonceRandom; }
  50. }
  51. public virtual SecureRandom SecureRandom
  52. {
  53. get { return mSecureRandom; }
  54. }
  55. public virtual SecurityParameters SecurityParameters
  56. {
  57. get { return mSecurityParameters; }
  58. }
  59. public abstract bool IsServer { get; }
  60. public virtual ProtocolVersion ClientVersion
  61. {
  62. get { return mClientVersion; }
  63. }
  64. internal virtual void SetClientVersion(ProtocolVersion clientVersion)
  65. {
  66. this.mClientVersion = clientVersion;
  67. }
  68. public virtual ProtocolVersion ServerVersion
  69. {
  70. get { return mServerVersion; }
  71. }
  72. internal virtual void SetServerVersion(ProtocolVersion serverVersion)
  73. {
  74. this.mServerVersion = serverVersion;
  75. }
  76. public virtual TlsSession ResumableSession
  77. {
  78. get { return mSession; }
  79. }
  80. internal virtual void SetResumableSession(TlsSession session)
  81. {
  82. this.mSession = session;
  83. }
  84. public virtual object UserObject
  85. {
  86. get { return mUserObject; }
  87. set { this.mUserObject = value; }
  88. }
  89. public virtual byte[] ExportKeyingMaterial(string asciiLabel, byte[] context_value, int length)
  90. {
  91. /*
  92. * TODO[session-hash]
  93. *
  94. * draft-ietf-tls-session-hash-04 5.4. If a client or server chooses to continue with a full
  95. * handshake without the extended master secret extension, [..] the client or server MUST
  96. * NOT export any key material based on the new master secret for any subsequent
  97. * application-level authentication. In particular, it MUST disable [RFC5705] [..].
  98. */
  99. if (context_value != null && !TlsUtilities.IsValidUint16(context_value.Length))
  100. throw new ArgumentException("must have length less than 2^16 (or be null)", "context_value");
  101. SecurityParameters sp = SecurityParameters;
  102. byte[] cr = sp.ClientRandom, sr = sp.ServerRandom;
  103. int seedLength = cr.Length + sr.Length;
  104. if (context_value != null)
  105. {
  106. seedLength += (2 + context_value.Length);
  107. }
  108. byte[] seed = new byte[seedLength];
  109. int seedPos = 0;
  110. Array.Copy(cr, 0, seed, seedPos, cr.Length);
  111. seedPos += cr.Length;
  112. Array.Copy(sr, 0, seed, seedPos, sr.Length);
  113. seedPos += sr.Length;
  114. if (context_value != null)
  115. {
  116. TlsUtilities.WriteUint16(context_value.Length, seed, seedPos);
  117. seedPos += 2;
  118. Array.Copy(context_value, 0, seed, seedPos, context_value.Length);
  119. seedPos += context_value.Length;
  120. }
  121. if (seedPos != seedLength)
  122. throw new InvalidOperationException("error in calculation of seed for export");
  123. return TlsUtilities.PRF(this, sp.MasterSecret, asciiLabel, seed, length);
  124. }
  125. }
  126. }
  127. #endif