示例#1
0
/*
 * Some browsers use a hybrid SSLv2 "client hello"
 */
int process_sslv23_client_hello(SSL *ssl) {
	uint8_t *buf = ssl->bm_data;
	int bytes_needed = ((buf[0] & 0x7f) << 8) + buf[1];
	int ret = SSL_OK;

	/* we have already read 3 extra bytes so far */
//    int read_len = SOCKET_READ(ssl->client_fd, buf, bytes_needed-3);
	int read_len = pbuf_copy_partial(ssl->ssl_pbuf, buf, bytes_needed - 3, 0);
	int cs_len = buf[1];
	int id_len = buf[3];
	int ch_len = buf[5];
	int i, j, offset = 8;   /* start at first cipher */
	int random_offset = 0;

	DISPLAY_BYTES(ssl, "received %d bytes", buf, read_len, read_len);

	add_packet(ssl, buf, read_len);

	/* connection has gone, so die */
	if (bytes_needed < 0) {
		return SSL_ERROR_CONN_LOST;
	}

	/* now work out what cipher suite we are going to use */
	for (j = 0; j < NUM_PROTOCOLS; j++) {
		for (i = 0; i < cs_len; i += 3) {
			if (ssl_prot_prefs[j] == buf[offset + i]) {
				ssl->cipher = ssl_prot_prefs[j];
				goto server_hello;
			}
		}
	}

	/* ouch! protocol is not supported */
	ret = SSL_ERROR_NO_CIPHER;
	goto error;

server_hello:
	/* get the session id */
	offset += cs_len - 2;   /* we've gone 2 bytes past the end */
#ifndef CONFIG_SSL_SKELETON_MODE
	ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions,
									  ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL);
#endif

	/* get the client random data */
	offset += id_len;

	/* random can be anywhere between 16 and 32 bytes long - so it is padded
	 * with 0's to the left */
	if (ch_len == 0x10) {
		random_offset += 0x10;
	}

	memcpy(&ssl->dc->client_random[random_offset], &buf[offset], ch_len);
	ret = send_server_hello_sequence(ssl);

error:
	return ret;
}
/*
 * Process the handshake record.
 */
int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
{
    int ret = SSL_OK;
    ssl->hs_status = SSL_NOT_OK;            /* not connected */

    /* To get here the state must be valid */
    switch (handshake_type)
    {
        case HS_CLIENT_HELLO:
            if ((ret = process_client_hello(ssl)) == SSL_OK)
                ret = send_server_hello_sequence(ssl);
            break;

#ifdef CONFIG_SSL_CERT_VERIFICATION
        case HS_CERTIFICATE:/* the client sends its cert */
            ret = process_certificate(ssl, &ssl->x509_ctx);

            if (ret == SSL_OK)    /* verify the cert */
            { 
                int cert_res;
                int pathLenConstraint = 0;

                cert_res = x509_verify(ssl->ssl_ctx->ca_cert_ctx, 
                        ssl->x509_ctx, &pathLenConstraint);
                ret = (cert_res == 0) ? SSL_OK : SSL_X509_ERROR(cert_res);
            }
            break;

        case HS_CERT_VERIFY:    
            ret = process_cert_verify(ssl);
            add_packet(ssl, buf, hs_len);   /* needs to be done after */
            break;
#endif
        case HS_CLIENT_KEY_XCHG:
            ret = process_client_key_xchg(ssl);
            break;

        case HS_FINISHED:
            ret = process_finished(ssl, buf, hs_len);
            disposable_free(ssl);   /* free up some memory */
            break;
    }

    return ret;
}