void ParseCertificate(HMParser hm) { if (certificateChain != null) { throw new Exception("Duplicate Certificate message"); } List <byte[]> chain = new List <byte[]>(); hm.OpenVar(3); while (!hm.EndOfStruct) { chain.Add(hm.ReadBlobVar(3)); } hm.Close(); hm.Close(); certificateChain = chain.ToArray(); certificate = (chain.Count > 0) ? chain[0] : null; }
/* * Parse messages from the server: from ServerHello to * ServerHelloDone. */ internal void Parse(SSLRecord rec) { rec.SetExpectedType(M.HANDSHAKE); /* * First parse a ServerHello. */ HMParser sh = new HMParser(rec); if (sh.MessageType != M.SERVER_HELLO) { throw new Exception("Not a ServerHello"); } version = sh.Read2(); byte[] serverRandom = sh.ReadBlobFixed(32); timeMillis = 1000 * (long)M.Dec32be(serverRandom, 0); sessionID = sh.ReadBlobVar(1); if (sessionID.Length > 32) { throw new Exception("Oversized session ID"); } selectedCipherSuite = sh.Read2(); int cm = sh.Read1(); if (cm == 0) { deflateCompress = false; } else if (cm == 1) { deflateCompress = true; } else { throw new Exception( "Unknown compression method: " + cm); } if (!sh.EndOfStruct) { sh.OpenVar(2); Dictionary <int, bool> d = new Dictionary <int, bool>(); while (!sh.EndOfStruct) { int extType = sh.Read2(); if (d.ContainsKey(extType)) { throw new Exception( "Duplicate extension: " + extType); } d[extType] = true; sh.OpenVar(2); switch (extType) { case M.EXT_SERVER_NAME: ParseEmptyServerName(sh); break; case M.EXT_RENEGOTIATION_INFO: ParseRenegInfo(sh); break; case M.EXT_SUPPORTED_CURVES: ParseSupportedCurves(sh); break; case M.EXT_SUPPORTED_EC_POINTS: ParseSupportedECPoints(sh); break; default: throw new Exception( "Unknown extension: " + extType); } sh.Close(); } sh.Close(); } sh.Close(); /* * Read other messages, up to the ServerHelloDone. */ try { bool seenSHD = false; while (!seenSHD) { HMParser hm = new HMParser(rec); switch (hm.MessageType) { case M.CERTIFICATE: ParseCertificate(hm); break; case M.SERVER_KEY_EXCHANGE: ParseServerKeyExchange(hm); break; case M.CERTIFICATE_REQUEST: ParseCertificateRequest(hm); break; case M.SERVER_HELLO_DONE: hm.Close(); seenSHD = true; break; default: hm.Close(true); break; } } } catch { failedAfterHello = true; } recordVersion = rec.GetInVersion(); }