void ParseSupportedECPoints(HMParser sh) { /* * TODO: see if we should parse this information. The * server sends that extension after seeing the client's * ClientHello, so it may "lie" about its actual abilities. */ sh.SkipRemainder(); }
void ParseServerKeyExchangeInner(HMParser hm) { CipherSuite cs; if (!CipherSuite.ALL.TryGetValue(selectedCipherSuite, out cs)) { unknownSKE = true; hm.Close(true); return; } if (cs.IsDHE) { /* * If this is DHE_PSK, then there is first a * "key hint" to skip. */ if (cs.IsPSK) { hm.ReadBlobVar(2); } /* * DH parameters: p, g, y. We are only interested * in p. */ byte[] p = hm.ReadBlobVar(2); dhSize = M.BitLength(p); hm.ReadBlobVar(2); hm.ReadBlobVar(2); if (cs.ServerKeyType != "none") { if (version >= M.TLSv12) { /* * Hash-and-sign identifiers. */ hm.Read2(); } hm.ReadBlobVar(2); } } else if (cs.IsECDHE) { /* * If this is ECDHE_PSK, then there is first a * "key hint" to skip. */ if (cs.IsPSK) { hm.ReadBlobVar(2); } /* * Read curve type: one byte. */ switch (hm.Read1()) { case 1: /* * explicit_prime: p, a, b, G, * order, cofactor. */ hm.ReadBlobVar(1); hm.ReadBlobVar(1); hm.ReadBlobVar(1); hm.ReadBlobVar(1); ecSize = M.AdjustedBitLength(hm.ReadBlobVar(1)); hm.ReadBlobVar(1); curveExplicitPrime = true; break; case 2: /* explicit_char2 */ hm.Read2(); switch (hm.Read1()) { case 1: /* trinomial */ hm.ReadBlobVar(1); break; case 2: /* pentanomial */ hm.ReadBlobVar(1); hm.ReadBlobVar(1); hm.ReadBlobVar(1); break; default: hm.Close(true); unknownSKE = true; return; } hm.ReadBlobVar(1); hm.ReadBlobVar(1); hm.ReadBlobVar(1); ecSize = M.AdjustedBitLength(hm.ReadBlobVar(1)); hm.ReadBlobVar(1); curveExplicitChar2 = true; break; case 3: /* * named_curve. */ int id = hm.Read2(); if (SSLCurve.ALL.TryGetValue(id, out curve)) { ecSize = curve.Size; } else { curve = null; hm.Close(true); unknownSKE = true; return; } break; default: hm.Close(true); unknownSKE = true; return; } /* * Read public key: one curve point. */ hm.ReadBlobVar(1); if (cs.ServerKeyType != "none") { if (version >= M.TLSv12) { /* * Hash-and-sign identifiers. */ hm.Read2(); } hm.ReadBlobVar(2); } } else if (cs.IsRSAExport) { /* * If cipher suite uses RSA key exchange and is * flagged "export" then it may send an ephemeral * RSA key pair, which will be weak and probably * not very ephemeral, since RSA key pair generation * is kinda expensive. * * Format: modulus, public exponent, signature. */ hm.ReadBlobVar(2); hm.ReadBlobVar(2); if (version >= M.TLSv12) { /* * Hash-and-sign identifiers. */ hm.Read2(); } hm.ReadBlobVar(2); } else if (cs.IsSRP) { /* * SRP parameters are: N, g, s, B. N is the * modulus. */ dhSize = M.BitLength(hm.ReadBlobVar(2)); hm.ReadBlobVar(2); hm.ReadBlobVar(1); hm.ReadBlobVar(2); /* * RFC 5054 says that there is a signature, * except if the server sent no certificate. What * happens at the encoding level is unclear, so * we skip the remaining bytes. */ hm.SkipRemainder(); } else if (cs.IsPSK) { /* * Key hint from the server. */ hm.ReadBlobVar(2); } else { throw new IOException("Unexpected ServerKeyExchange"); } hm.Close(); }