Beispiel #1
0
std::string avjackif::async_client_hello(boost::asio::yield_context yield_context)
{
	proto::client_hello client_hello;
	client_hello.set_client("avim");
	client_hello.set_version(0001);

	unsigned char to[512];

	auto dh = DH_new();
	DH_generate_parameters_ex(dh,64,DH_GENERATOR_5,NULL);
	DH_generate_key(dh);

	// 把 g,p, pubkey 传过去
	client_hello.set_random_g((const void*)to, BN_bn2bin(dh->g, to));
	client_hello.set_random_p((const void*)to, BN_bn2bin(dh->p, to));
	client_hello.set_random_pub_key((const void*)to, BN_bn2bin(dh->pub_key, to));

	auto tobesend = av_router::encode(client_hello);

	boost::asio::async_write(*m_sock, boost::asio::buffer(tobesend), yield_context);

	// 解码
	std::unique_ptr<proto::server_hello> server_hello(
		(proto::server_hello*)async_read_protobuf_message(*m_sock, yield_context));

	m_remote_addr.reset(new proto::av_address(
		av_address_from_string(server_hello->server_av_address())));

	auto server_pubkey = BN_bin2bn((const unsigned char *) server_hello->random_pub_key().data(),
		server_hello->random_pub_key().length(), NULL);

	m_shared_key.resize(DH_size(dh));
	// 密钥就算出来啦!
	DH_compute_key(&m_shared_key[0], server_pubkey, dh);
	BN_free(server_pubkey);

    std::printf("key = 0x");
    for (int i=0; i<DH_size(dh); ++i)
	{
        std::printf("%x%x", (m_shared_key[i] >> 4) & 0xf, m_shared_key[i] & 0xf);
    }
    std::printf("\n");
	DH_free(dh);

	return server_hello->random_pub_key();
}
Beispiel #2
0
bool avjackif::async_handshake(boost::asio::yield_context yield_context)
{
	proto::client_hello client_hello;
	client_hello.set_client("avim");
	client_hello.set_version(0001);

	unsigned char to[512];

	auto dh = DH_new();
	DH_generate_parameters_ex(dh,64,DH_GENERATOR_5,NULL);
	DH_generate_key(dh);

	// 把 g,p, pubkey 传过去
	client_hello.set_random_g((const void*)to, BN_bn2bin(dh->g, to));
	client_hello.set_random_p((const void*)to, BN_bn2bin(dh->p, to));
	client_hello.set_random_pub_key((const void*)to, BN_bn2bin(dh->pub_key, to));

	auto tobesend = av_router::encode(client_hello);

	boost::asio::async_write(*m_sock, boost::asio::buffer(tobesend), yield_context);

	std::uint32_t l;
	boost::asio::async_read(*m_sock, boost::asio::buffer(&l, sizeof(l)), boost::asio::transfer_exactly(4), yield_context);
	auto hostl = htonl(l);
	std::string  buf;

	buf.resize(hostl + 4);
	memcpy(&buf[0], &l, 4);
	hostl = boost::asio::async_read(*m_sock, boost::asio::buffer(&buf[4], hostl),
		boost::asio::transfer_exactly(hostl), yield_context);

	// 解码
	boost::scoped_ptr<proto::server_hello> server_hello((proto::server_hello*)av_router::decode(buf));

	m_remote_addr.reset(new proto::avAddress(
		av_address_from_string(server_hello->server_av_address())));

	auto server_pubkey = BN_bin2bn((const unsigned char *) server_hello->random_pub_key().data(),
		server_hello->random_pub_key().length(), NULL);

	m_shared_key.resize(DH_size(dh));
	// 密钥就算出来啦!
	DH_compute_key(&m_shared_key[0], server_pubkey, dh);
	BN_free(server_pubkey);

    std::printf("key = 0x");
    for (int i=0; i<DH_size(dh); ++i) {
        std::printf("%x%x", (m_shared_key[i] >> 4) & 0xf, m_shared_key[i] & 0xf);
    }
    std::printf("\n");
	DH_free(dh);

	// 接着私钥加密 随机数
	auto singned = RSA_private_encrypt(_rsa.get(), server_hello->random_pub_key());

	proto::login login_packet;
	login_packet.set_user_cert( i2d_X509(_x509.get()) );
	login_packet.set_encryped_radom_key(singned);

	boost::asio::async_write(*m_sock, boost::asio::buffer(av_router::encode(login_packet)),
		yield_context);

	// 读取回应
	boost::asio::async_read(*m_sock, boost::asio::buffer(&l, sizeof(l)),
		boost::asio::transfer_exactly(hostl), yield_context);

	hostl = htonl(l);
	buf.resize(htonl(l) + 4);
	memcpy(&buf[0], &l, 4);
	boost::asio::async_read(*m_sock, boost::asio::buffer(&buf[4], htonl(l)),
		boost::asio::transfer_exactly(hostl), yield_context);
	// 解码
	boost::scoped_ptr<proto::login_result> login_result((proto::login_result*)av_router::decode(buf));

	return login_result.get()->result() == proto::login_result_login_result_code_LOGIN_SUCCEED;
}
Beispiel #3
0
static void
content_parse(
        const struct Banner1 *banner1,
        void *banner1_private,
        struct Banner1State *pstate,
        const unsigned char *px, size_t length,
        char *banner, unsigned *banner_offset, size_t banner_max)
{
    struct SSLRECORD *ssl = &pstate->sub.ssl;
    unsigned state = ssl->record.state;
    unsigned remaining = ssl->record.remaining;
	unsigned i;
    enum {
        START,
        LENGTH0, LENGTH1, LENGTH2,
        CONTENTS,
        UNKNOWN,
    };

    for (i=0; i<length; i++) 
    switch (state) {
    case START:
        if (px[i] & 0x80) {
            state = UNKNOWN;
            break;
        }
        remaining = 0;
        ssl->record.type = px[i];
        ssl->x.all.state = 0;
        DROPDOWN(i,length,state);

    case LENGTH0: 
        remaining = px[i];
        DROPDOWN(i,length,state);

    case LENGTH1:
        remaining <<= 8;
        remaining |= px[i];
        DROPDOWN(i,length,state);

    case LENGTH2:
        remaining <<= 8;
        remaining |= px[i];
        DROPDOWN(i,length,state);

    case CONTENTS:
        {
            unsigned len = (unsigned)length-i;
            if (len > remaining)
                len = remaining;

            switch (ssl->record.type) {
            case 0x02: /* server hello */
                server_hello(      banner1,
                                    banner1_private,
                                    pstate,
                                    px+i, len,
                                    banner, banner_offset, banner_max);
                break;
            case 0x0b: /* server certificate */
                server_cert(        banner1,
                                    banner1_private,
                                    pstate,
                                    px+i, len,
                                    banner, banner_offset, banner_max);
                break;
            }

            remaining -= len;
            i += len-1;

            if (remaining == 0)
                state = START;
        }

        break;
    case UNKNOWN:
    default:
        i = (unsigned)length;
    }

    ssl->record.state = state;
    ssl->record.remaining = remaining;
}