Esempio n. 1
0
    /*
     * Build a ClientHello using the provided cipher suites.
     * Returned array contains the complete message with its
     * 4-byte header (but not the record header).
     */
    byte[] MakeClientHello(int[] ccs)
    {
        /*
         * Assemble ClientHello.
         */
        HList chs = new HList(0xFFFFFF);

        /*
         * Maximum protocol version.
         */
        M.Write2(chs, maxVersion);

        /*
         * Client random. The first four bytes encode the
         * current time.
         */
        byte[] clientRandom = new byte[32];
        M.Enc32be((int)(M.CurrentTimeMillis() / 1000), clientRandom, 0);
        M.Rand(clientRandom, 4, clientRandom.Length - 4);
        chs.Write(clientRandom, 0, clientRandom.Length);

        /*
         * Session ID, for session resumption.
         */
        if (sessionID == null)
        {
            M.Write1(chs, 0);
        }
        else
        {
            M.Write1(chs, sessionID.Length);
            chs.Write(sessionID, 0, sessionID.Length);
        }

        /*
         * Cipher suites.
         */
        List <int> lcs = new List <int>();

        if (ccs != null)
        {
            foreach (int s in ccs)
            {
                lcs.Add(s);
            }
            if (renegotiationSCSV)
            {
                lcs.Add(M.TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
            }
            if (fallbackSCSV)
            {
                lcs.Add(M.TLS_FALLBACK_SCSV);
            }
        }
        M.Write2(chs, lcs.Count << 1);
        foreach (int s in lcs)
        {
            M.Write2(chs, s);
        }

        /*
         * Compression support: the NULL compression must
         * always be specified; optionally, Deflate compression
         * can be supported.
         */
        if (deflateCompress)
        {
            M.Write1(chs, 2);
            M.Write1(chs, 1);
            M.Write1(chs, 0);
        }
        else
        {
            M.Write1(chs, 1);
            M.Write1(chs, 0);
        }

        /*
         * Extensions.
         */
        HList exs = new HList(0xFFFF);

        if (serverName != null)
        {
            M.Write2(exs, M.EXT_SERVER_NAME);
            HList sndata = new HList(0xFFFF);
            HList snles  = new HList(0xFFFF);
            snles.WriteByte(0);
            HList snes = new HList(0xFFFF);
            snes.Write(Encoding.UTF8.GetBytes(serverName));
            snles.Write(snes.ToArray());
            sndata.Write(snles.ToArray());
            exs.Write(sndata.ToArray());
        }
        if (renegotiationExtension)
        {
            M.Write2(exs, M.EXT_RENEGOTIATION_INFO);
            M.Write2(exs, 1);
            M.Write1(exs, 0);
        }
        if (supportedCurves != null && supportedCurves.Length > 0)
        {
            M.Write2(exs, M.EXT_SUPPORTED_CURVES);
            HList ecdata = new HList(0xFFFF);
            HList ecl    = new HList(0xFFFF);
            foreach (int ec in supportedCurves)
            {
                M.Write2(ecl, ec);
            }
            ecdata.Write(ecl.ToArray());
            exs.Write(ecdata.ToArray());
        }

        if (exs.Length != 0)
        {
            chs.Write(exs.ToArray());
        }

        byte[]       msg = chs.ToArray();
        MemoryStream ms  = new MemoryStream();

        ms.WriteByte(M.CLIENT_HELLO);
        ms.Write(msg, 0, msg.Length);
        return(ms.ToArray());
    }
Esempio n. 2
0
    /*
     * Build a ClientHello using the provided cipher suites.
     * Returned array contains the complete message with its
     * 4-byte header (but not the record header).
     */
    byte[] MakeClientHello(int[] ccs)
    {
        /*
         * Assemble ClientHello.
         */
        HList chs = new HList(0xFFFFFF);

        /*
         * Maximum protocol version.
         */
        M.Write2(chs, maxVersion);

        /*
         * Client random. The first four bytes encode the
         * current time.
         */
        byte[] clientRandom = new byte[32];
        M.Enc32be((int)(M.CurrentTimeMillis() / 1000), clientRandom, 0);
        M.Rand(clientRandom, 4, clientRandom.Length - 4);
        chs.Write(clientRandom, 0, clientRandom.Length);

        /*
         * Session ID, for session resumption.
         */
        if (sessionID == null)
        {
            M.Write1(chs, 0);
        }
        else
        {
            M.Write1(chs, sessionID.Length);
            chs.Write(sessionID, 0, sessionID.Length);
        }

        /*
         * Cipher suites.
         */
        List <int> lcs = new List <int>();

        if (ccs != null)
        {
            foreach (int s in ccs)
            {
                lcs.Add(s);
            }
            if (renegotiationSCSV)
            {
                lcs.Add(M.TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
            }
            if (fallbackSCSV)
            {
                lcs.Add(M.TLS_FALLBACK_SCSV);
            }
        }
        M.Write2(chs, lcs.Count << 1);
        foreach (int s in lcs)
        {
            M.Write2(chs, s);
        }

        /*
         * Compression support: the NULL compression must
         * always be specified; optionally, Deflate compression
         * can be supported.
         */
        if (deflateCompress)
        {
            M.Write1(chs, 2);
            M.Write1(chs, 1);
            M.Write1(chs, 0);
        }
        else
        {
            M.Write1(chs, 1);
            M.Write1(chs, 0);
        }

        /*
         * Extensions.
         */
        HList exs = new HList(0xFFFF);

        /*
         * With TLS 1.2, the "signature algorithms" extension is
         * _always_ included, even if all other extensions are
         * disabled.
         */
        if (maxVersion >= M.TLSv12)
        {
            M.Write2(exs, M.EXT_SIGNATURE_ALGORITHMS);
            M.Write2(exs, 38);
            M.Write2(exs, 36);
            for (int s = 3; s >= 1; s--)
            {
                for (int h = 6; h >= 1; h--)
                {
                    M.Write1(exs, h);
                    M.Write1(exs, s);
                }
            }
        }

        if (serverName != null)
        {
            M.Write2(exs, M.EXT_SERVER_NAME);
            HList sndata = new HList(0xFFFF);
            HList snles  = new HList(0xFFFF);
            snles.WriteByte(0);
            HList snes = new HList(0xFFFF);
            snes.Write(Encoding.UTF8.GetBytes(serverName));
            snles.Write(snes.ToArray());
            sndata.Write(snles.ToArray());
            exs.Write(sndata.ToArray());
        }
        if (renegotiationExtension)
        {
            M.Write2(exs, M.EXT_RENEGOTIATION_INFO);
            M.Write2(exs, 1);
            M.Write1(exs, 0);
        }
        if (encryptThenMACExtension)
        {
            M.Write2(exs, M.EXT_ENCRYPT_THEN_MAC);
            M.Write2(exs, 0);
        }
        if (supportedCurves != null && supportedCurves.Length > 0)
        {
            M.Write2(exs, M.EXT_SUPPORTED_CURVES);
            HList ecdata = new HList(0xFFFF);
            HList ecl    = new HList(0xFFFF);
            foreach (int ec in supportedCurves)
            {
                M.Write2(ecl, ec);
            }
            ecdata.Write(ecl.ToArray());
            exs.Write(ecdata.ToArray());

            /*
             * Also send supported point format extension; it
             * seems to be required by some servers.
             */
            M.Write2(exs, M.EXT_SUPPORTED_EC_POINTS);
            HList epdata = new HList(0xFFFF);
            HList epl    = new HList(0xFF);
            M.Write1(epl, 0x00);
            M.Write1(epl, 0x01);
            M.Write1(epl, 0x02);
            epdata.Write(epl.ToArray());
            exs.Write(epdata.ToArray());
        }

        if (exs.Length != 0)
        {
            chs.Write(exs.ToArray());
        }

        byte[]       msg = chs.ToArray();
        MemoryStream ms  = new MemoryStream();

        ms.WriteByte(M.CLIENT_HELLO);
        ms.Write(msg, 0, msg.Length);
        return(ms.ToArray());
    }