示例#1
0
    /*
     * Begin a new handshake, and return the server data. If the
     * server refused to complete the handshake with an explicit
     * alert, then an SSLAlertException is thrown; for all other
     * error conditions, an other kind of exception is thrown.
     */
    internal SSLTestResult RunTest(SSLRecord rec)
    {
        /*
         * Send ClientHello.
         */
        byte[] ch = MakeClientHello(cipherSuites);
        rec.SetOutType(M.HANDSHAKE);
        rec.SetOutVersion(recordVersion);
        rec.Write(ch);
        rec.Flush();

        /*
         * Read handshake messages from server, up to the
         * ServerHelloDone.
         */
        SSLTestResult tr = new SSLTestResult();

        tr.Parse(rec);
        tr.CipherSuiteInClientList = false;
        foreach (int s in cipherSuites)
        {
            if (s == tr.SelectedCipherSuite)
            {
                tr.CipherSuiteInClientList = true;
            }
        }
        return(tr);
    }
示例#2
0
    /*
     * Try a connection with the current test settings. Connection
     * errors get through as exceptions. Other errors result in a
     * null returned value. If the handshake failed after the
     * ServerHello, then a non-null object is returned.
     */
    SSLTestResult DoConnect()
    {
        Stream ns = null;

        try {
            ns = OpenConnection();
            if (verbose)
            {
                Console.Write(".");
            }
            if (!gotSSLAnswer && readTimeout > 0)
            {
                RTStream rns = new RTStream(ns);
                rns.RTimeout = readTimeout;
                ns           = rns;
            }
            try {
                bool hasECExt = tb.SupportedCurves != null &&
                                tb.SupportedCurves.Length > 0;
                SSLRecord     rec = new SSLRecord(ns);
                SSLTestResult tr  = tb.RunTest(rec);
                gotSSLAnswer = true;
                if (tr != null)
                {
                    if (tr.DeflateCompress)
                    {
                        serverCompress = true;
                    }
                    AddServerChain(tr.CertificateChain);
                    AddServerTime(tr.TimeMillis);
                    AddServerDHSize(tr.DHSize);
                    AddServerECSize(tr.ECSize, hasECExt);
                    AddServerNamedCurve(tr.Curve);
                    if (tr.CurveExplicitPrime)
                    {
                        curveExplicitPrime = tr.ECSize;
                    }
                    else if (tr.CurveExplicitChar2)
                    {
                        curveExplicitChar2 = tr.ECSize;
                    }
                    if (tr.UnknownSKE)
                    {
                        unknownSKE = true;
                    }
                    if (tr.RenegotiationInfo != null)
                    {
                        doesRenego = true;
                    }
                    if (tr.DoesEtM)
                    {
                        doesEtM = true;
                    }
                }
                return(tr);
            } catch (SSLAlertException ae) {
                gotSSLAnswer = true;
                sslAlert     = ae.Alert;
                return(null);
            } catch (ReadTimeoutException) {
                gotReadTimeout = true;
                return(null);
            } catch (Exception) {
                return(null);
            }
        } finally {
            try {
                if (ns != null)
                {
                    ns.Close();
                }
            } catch (Exception) {
                // ignored
            }
        }
    }
示例#3
0
    /*
     * 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();
    }