TlsPskKeyExchange.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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.Asn1.X509;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  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 PSK key exchange (RFC 4279).</summary>
  14. public class TlsPskKeyExchange
  15. : AbstractTlsKeyExchange
  16. {
  17. protected TlsPskIdentity mPskIdentity;
  18. protected TlsPskIdentityManager mPskIdentityManager;
  19. protected TlsDHVerifier mDHVerifier;
  20. protected DHParameters mDHParameters;
  21. protected int[] mNamedCurves;
  22. protected byte[] mClientECPointFormats, mServerECPointFormats;
  23. protected byte[] mPskIdentityHint = null;
  24. protected byte[] mPsk = null;
  25. protected DHPrivateKeyParameters mDHAgreePrivateKey = null;
  26. protected DHPublicKeyParameters mDHAgreePublicKey = null;
  27. protected ECPrivateKeyParameters mECAgreePrivateKey = null;
  28. protected ECPublicKeyParameters mECAgreePublicKey = null;
  29. protected AsymmetricKeyParameter mServerPublicKey = null;
  30. protected RsaKeyParameters mRsaServerPublicKey = null;
  31. protected TlsEncryptionCredentials mServerCredentials = null;
  32. protected byte[] mPremasterSecret;
  33. [Obsolete("Use constructor that takes a TlsDHVerifier")]
  34. public TlsPskKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsPskIdentity pskIdentity,
  35. TlsPskIdentityManager pskIdentityManager, DHParameters dhParameters, int[] namedCurves,
  36. byte[] clientECPointFormats, byte[] serverECPointFormats)
  37. : this(keyExchange, supportedSignatureAlgorithms, pskIdentity, pskIdentityManager, new DefaultTlsDHVerifier(),
  38. dhParameters, namedCurves, clientECPointFormats, serverECPointFormats)
  39. {
  40. }
  41. public TlsPskKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsPskIdentity pskIdentity,
  42. TlsPskIdentityManager pskIdentityManager, TlsDHVerifier dhVerifier, DHParameters dhParameters, int[] namedCurves,
  43. byte[] clientECPointFormats, byte[] serverECPointFormats)
  44. : base(keyExchange, supportedSignatureAlgorithms)
  45. {
  46. switch (keyExchange)
  47. {
  48. case KeyExchangeAlgorithm.DHE_PSK:
  49. case KeyExchangeAlgorithm.ECDHE_PSK:
  50. case KeyExchangeAlgorithm.PSK:
  51. case KeyExchangeAlgorithm.RSA_PSK:
  52. break;
  53. default:
  54. throw new InvalidOperationException("unsupported key exchange algorithm");
  55. }
  56. this.mPskIdentity = pskIdentity;
  57. this.mPskIdentityManager = pskIdentityManager;
  58. this.mDHVerifier = dhVerifier;
  59. this.mDHParameters = dhParameters;
  60. this.mNamedCurves = namedCurves;
  61. this.mClientECPointFormats = clientECPointFormats;
  62. this.mServerECPointFormats = serverECPointFormats;
  63. }
  64. public override void SkipServerCredentials()
  65. {
  66. if (mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
  67. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  68. }
  69. public override void ProcessServerCredentials(TlsCredentials serverCredentials)
  70. {
  71. if (!(serverCredentials is TlsEncryptionCredentials))
  72. throw new TlsFatalAlert(AlertDescription.internal_error);
  73. ProcessServerCertificate(serverCredentials.Certificate);
  74. this.mServerCredentials = (TlsEncryptionCredentials)serverCredentials;
  75. }
  76. public override byte[] GenerateServerKeyExchange()
  77. {
  78. this.mPskIdentityHint = mPskIdentityManager.GetHint();
  79. if (this.mPskIdentityHint == null && !RequiresServerKeyExchange)
  80. return null;
  81. MemoryStream buf = new MemoryStream();
  82. if (this.mPskIdentityHint == null)
  83. {
  84. TlsUtilities.WriteOpaque16(TlsUtilities.EmptyBytes, buf);
  85. }
  86. else
  87. {
  88. TlsUtilities.WriteOpaque16(this.mPskIdentityHint, buf);
  89. }
  90. if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
  91. {
  92. if (this.mDHParameters == null)
  93. throw new TlsFatalAlert(AlertDescription.internal_error);
  94. this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom,
  95. this.mDHParameters, buf);
  96. }
  97. else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
  98. {
  99. this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom,
  100. mNamedCurves, mClientECPointFormats, buf);
  101. }
  102. return buf.ToArray();
  103. }
  104. public override void ProcessServerCertificate(Certificate serverCertificate)
  105. {
  106. if (mKeyExchange != KeyExchangeAlgorithm.RSA_PSK)
  107. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  108. if (serverCertificate.IsEmpty)
  109. throw new TlsFatalAlert(AlertDescription.bad_certificate);
  110. X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);
  111. SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
  112. try
  113. {
  114. this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo);
  115. }
  116. catch (Exception e)
  117. {
  118. throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e);
  119. }
  120. // Sanity check the PublicKeyFactory
  121. if (this.mServerPublicKey.IsPrivate)
  122. throw new TlsFatalAlert(AlertDescription.internal_error);
  123. this.mRsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.mServerPublicKey);
  124. TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment);
  125. base.ProcessServerCertificate(serverCertificate);
  126. }
  127. public override bool RequiresServerKeyExchange
  128. {
  129. get
  130. {
  131. switch (mKeyExchange)
  132. {
  133. case KeyExchangeAlgorithm.DHE_PSK:
  134. case KeyExchangeAlgorithm.ECDHE_PSK:
  135. return true;
  136. default:
  137. return false;
  138. }
  139. }
  140. }
  141. public override void ProcessServerKeyExchange(Stream input)
  142. {
  143. this.mPskIdentityHint = TlsUtilities.ReadOpaque16(input);
  144. if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
  145. {
  146. this.mDHParameters = TlsDHUtilities.ReceiveDHParameters(mDHVerifier, input);
  147. this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters);
  148. }
  149. else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
  150. {
  151. ECDomainParameters ecParams = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, input);
  152. byte[] point = TlsUtilities.ReadOpaque8(input);
  153. this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(
  154. mClientECPointFormats, ecParams, point));
  155. }
  156. }
  157. public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
  158. {
  159. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  160. }
  161. public override void ProcessClientCredentials(TlsCredentials clientCredentials)
  162. {
  163. throw new TlsFatalAlert(AlertDescription.internal_error);
  164. }
  165. public override void GenerateClientKeyExchange(Stream output)
  166. {
  167. if (mPskIdentityHint == null)
  168. {
  169. mPskIdentity.SkipIdentityHint();
  170. }
  171. else
  172. {
  173. mPskIdentity.NotifyIdentityHint(mPskIdentityHint);
  174. }
  175. byte[] psk_identity = mPskIdentity.GetPskIdentity();
  176. if (psk_identity == null)
  177. throw new TlsFatalAlert(AlertDescription.internal_error);
  178. this.mPsk = mPskIdentity.GetPsk();
  179. if (mPsk == null)
  180. throw new TlsFatalAlert(AlertDescription.internal_error);
  181. TlsUtilities.WriteOpaque16(psk_identity, output);
  182. mContext.SecurityParameters.pskIdentity = psk_identity;
  183. if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
  184. {
  185. this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom,
  186. mDHParameters, output);
  187. }
  188. else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
  189. {
  190. this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom,
  191. mServerECPointFormats, mECAgreePublicKey.Parameters, output);
  192. }
  193. else if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
  194. {
  195. this.mPremasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(mContext,
  196. this.mRsaServerPublicKey, output);
  197. }
  198. }
  199. public override void ProcessClientKeyExchange(Stream input)
  200. {
  201. byte[] psk_identity = TlsUtilities.ReadOpaque16(input);
  202. this.mPsk = mPskIdentityManager.GetPsk(psk_identity);
  203. if (mPsk == null)
  204. throw new TlsFatalAlert(AlertDescription.unknown_psk_identity);
  205. mContext.SecurityParameters.pskIdentity = psk_identity;
  206. if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
  207. {
  208. this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters);
  209. }
  210. else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
  211. {
  212. byte[] point = TlsUtilities.ReadOpaque8(input);
  213. ECDomainParameters curve_params = this.mECAgreePrivateKey.Parameters;
  214. this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(
  215. mServerECPointFormats, curve_params, point));
  216. }
  217. else if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
  218. {
  219. byte[] encryptedPreMasterSecret;
  220. if (TlsUtilities.IsSsl(mContext))
  221. {
  222. // TODO Do any SSLv3 clients actually include the length?
  223. encryptedPreMasterSecret = Streams.ReadAll(input);
  224. }
  225. else
  226. {
  227. encryptedPreMasterSecret = TlsUtilities.ReadOpaque16(input);
  228. }
  229. this.mPremasterSecret = mServerCredentials.DecryptPreMasterSecret(encryptedPreMasterSecret);
  230. }
  231. }
  232. public override byte[] GeneratePremasterSecret()
  233. {
  234. byte[] other_secret = GenerateOtherSecret(mPsk.Length);
  235. MemoryStream buf = new MemoryStream(4 + other_secret.Length + mPsk.Length);
  236. TlsUtilities.WriteOpaque16(other_secret, buf);
  237. TlsUtilities.WriteOpaque16(mPsk, buf);
  238. Arrays.Fill(mPsk, (byte)0);
  239. this.mPsk = null;
  240. return buf.ToArray();
  241. }
  242. protected virtual byte[] GenerateOtherSecret(int pskLength)
  243. {
  244. if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
  245. {
  246. if (mDHAgreePrivateKey != null)
  247. {
  248. return TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreePublicKey, mDHAgreePrivateKey);
  249. }
  250. throw new TlsFatalAlert(AlertDescription.internal_error);
  251. }
  252. if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
  253. {
  254. if (mECAgreePrivateKey != null)
  255. {
  256. return TlsEccUtilities.CalculateECDHBasicAgreement(mECAgreePublicKey, mECAgreePrivateKey);
  257. }
  258. throw new TlsFatalAlert(AlertDescription.internal_error);
  259. }
  260. if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
  261. {
  262. return this.mPremasterSecret;
  263. }
  264. return new byte[pskLength];
  265. }
  266. protected virtual RsaKeyParameters ValidateRsaPublicKey(RsaKeyParameters key)
  267. {
  268. // TODO What is the minimum bit length required?
  269. // key.Modulus.BitLength;
  270. if (!key.Exponent.IsProbablePrime(2))
  271. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  272. return key;
  273. }
  274. }
  275. }
  276. #pragma warning restore
  277. #endif