mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-09 03:41:41 +03:00
Started to implement TLS1.1 (but disabled for now)
git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@204 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
parent
222f2d98f1
commit
2ae9a3ec83
@ -192,7 +192,7 @@ config CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME
|
|||||||
|
|
||||||
config CONFIG_SSL_ENABLE_V23_HANDSHAKE
|
config CONFIG_SSL_ENABLE_V23_HANDSHAKE
|
||||||
bool "Enable v23 Handshake"
|
bool "Enable v23 Handshake"
|
||||||
default y
|
default n
|
||||||
help
|
help
|
||||||
Some browsers use the v23 handshake client hello message
|
Some browsers use the v23 handshake client hello message
|
||||||
(an SSL2 format message which all SSL servers can understand).
|
(an SSL2 format message which all SSL servers can understand).
|
||||||
|
40
ssl/tls1.c
40
ssl/tls1.c
@ -287,7 +287,6 @@ EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data)
|
|||||||
int ret = basic_read(ssl, in_data);
|
int ret = basic_read(ssl, in_data);
|
||||||
|
|
||||||
/* check for return code so we can send an alert */
|
/* check for return code so we can send an alert */
|
||||||
|
|
||||||
if (ret < SSL_OK && ret != SSL_CLOSE_NOTIFY)
|
if (ret < SSL_OK && ret != SSL_CLOSE_NOTIFY)
|
||||||
{
|
{
|
||||||
if (ret != SSL_ERROR_CONN_LOST)
|
if (ret != SSL_ERROR_CONN_LOST)
|
||||||
@ -695,19 +694,38 @@ static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len)
|
|||||||
|
|
||||||
if (ssl->cipher_info->padding_size)
|
if (ssl->cipher_info->padding_size)
|
||||||
{
|
{
|
||||||
hmac_offset = read_len-buf[read_len-1]-ssl->cipher_info->digest_size-1;
|
int last_blk_size = buf[read_len-1], i;
|
||||||
|
hmac_offset = read_len-last_blk_size-ssl->cipher_info->digest_size-1;
|
||||||
|
|
||||||
|
/* guard against a timing attack - make sure we do the digest */
|
||||||
|
if (hmac_offset < 0 || last_blk_size > ssl->cipher_info->padding_size)
|
||||||
|
{
|
||||||
|
hmac_offset = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* already looked at last byte */
|
||||||
|
for (i = 1; i < last_blk_size; i++)
|
||||||
|
{
|
||||||
|
if (buf[read_len-i] != last_blk_size)
|
||||||
|
{
|
||||||
|
hmac_offset = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hmac_offset = read_len - ssl->cipher_info->digest_size;
|
hmac_offset = read_len - ssl->cipher_info->digest_size;
|
||||||
|
|
||||||
|
if (hmac_offset < 0)
|
||||||
|
{
|
||||||
|
hmac_offset = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sanity check the offset */
|
/* sanity check the offset */
|
||||||
if (hmac_offset < 0)
|
|
||||||
{
|
|
||||||
return SSL_ERROR_INVALID_HMAC;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssl->hmac_header[3] = hmac_offset >> 8; /* insert size */
|
ssl->hmac_header[3] = hmac_offset >> 8; /* insert size */
|
||||||
ssl->hmac_header[4] = hmac_offset & 0xff;
|
ssl->hmac_header[4] = hmac_offset & 0xff;
|
||||||
add_hmac_digest(ssl, mode, ssl->hmac_header, buf, hmac_offset, hmac_buf);
|
add_hmac_digest(ssl, mode, ssl->hmac_header, buf, hmac_offset, hmac_buf);
|
||||||
@ -935,8 +953,8 @@ static int send_raw_packet(SSL *ssl, uint8_t protocol)
|
|||||||
int ret = SSL_OK;
|
int ret = SSL_OK;
|
||||||
|
|
||||||
rec_buf[0] = protocol;
|
rec_buf[0] = protocol;
|
||||||
rec_buf[1] = 0x03; /* version = 3.1 (TLS) */
|
rec_buf[1] = 0x03; /* version = 3.1 or higher */
|
||||||
rec_buf[2] = 0x01;
|
rec_buf[2] = ssl->version & 0x0f;
|
||||||
rec_buf[3] = ssl->bm_index >> 8;
|
rec_buf[3] = ssl->bm_index >> 8;
|
||||||
rec_buf[4] = ssl->bm_index & 0xff;
|
rec_buf[4] = ssl->bm_index & 0xff;
|
||||||
|
|
||||||
@ -1011,8 +1029,8 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length)
|
|||||||
uint8_t hmac_header[SSL_RECORD_SIZE];
|
uint8_t hmac_header[SSL_RECORD_SIZE];
|
||||||
|
|
||||||
hmac_header[0] = protocol;
|
hmac_header[0] = protocol;
|
||||||
hmac_header[1] = 0x03;
|
hmac_header[1] = 0x03; /* version = 3.1 or higher */
|
||||||
hmac_header[2] = 0x01;
|
hmac_header[2] = ssl->version & 0x0f;
|
||||||
hmac_header[3] = length >> 8;
|
hmac_header[3] = length >> 8;
|
||||||
hmac_header[4] = length & 0xff;
|
hmac_header[4] = length & 0xff;
|
||||||
|
|
||||||
|
@ -44,6 +44,11 @@ extern "C" {
|
|||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include "crypto_misc.h"
|
#include "crypto_misc.h"
|
||||||
|
|
||||||
|
#define SSL_PROTOCOL_MIN_VERSION 0x31 /* TLS v1.0 */
|
||||||
|
//#define SSL_PROTOCOL_MINOR_VERSION 0x02 /* TLS v1.1 */
|
||||||
|
#define SSL_PROTOCOL_MINOR_VERSION 0x01 /* TLS v1.0 */
|
||||||
|
//#define SSL_PROTOCOL_VERSION 0x32 /* TLS v1.1 */
|
||||||
|
#define SSL_PROTOCOL_VERSION 0x31 /* TLS v1.1 */
|
||||||
#define SSL_RANDOM_SIZE 32
|
#define SSL_RANDOM_SIZE 32
|
||||||
#define SSL_SECRET_SIZE 48
|
#define SSL_SECRET_SIZE 48
|
||||||
#define SSL_FINISHED_HASH_SIZE 12
|
#define SSL_FINISHED_HASH_SIZE 12
|
||||||
@ -160,6 +165,8 @@ struct _SSL
|
|||||||
uint8_t record_type;
|
uint8_t record_type;
|
||||||
uint8_t cipher;
|
uint8_t cipher;
|
||||||
uint8_t sess_id_size;
|
uint8_t sess_id_size;
|
||||||
|
uint8_t version;
|
||||||
|
uint8_t client_version;
|
||||||
int16_t next_state;
|
int16_t next_state;
|
||||||
int16_t hs_status;
|
int16_t hs_status;
|
||||||
DISPOSABLE_CTX *dc; /* temporary data which we'll get rid of soon */
|
DISPOSABLE_CTX *dc; /* temporary data which we'll get rid of soon */
|
||||||
|
@ -51,6 +51,7 @@ EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const
|
|||||||
uint8_t *session_id, uint8_t sess_id_size)
|
uint8_t *session_id, uint8_t sess_id_size)
|
||||||
{
|
{
|
||||||
SSL *ssl = ssl_new(ssl_ctx, client_fd);
|
SSL *ssl = ssl_new(ssl_ctx, client_fd);
|
||||||
|
ssl->version = SSL_PROTOCOL_VERSION;
|
||||||
|
|
||||||
if (session_id && ssl_ctx->num_sessions)
|
if (session_id && ssl_ctx->num_sessions)
|
||||||
{
|
{
|
||||||
@ -178,7 +179,7 @@ static int send_client_hello(SSL *ssl)
|
|||||||
buf[2] = 0;
|
buf[2] = 0;
|
||||||
/* byte 3 is calculated later */
|
/* byte 3 is calculated later */
|
||||||
buf[4] = 0x03;
|
buf[4] = 0x03;
|
||||||
buf[5] = 0x01;
|
buf[5] = ssl->version & 0x0f;
|
||||||
|
|
||||||
/* client random value - spec says that 1st 4 bytes are big endian time */
|
/* client random value - spec says that 1st 4 bytes are big endian time */
|
||||||
*tm_ptr++ = (uint8_t)(((long)tm & 0xff000000) >> 24);
|
*tm_ptr++ = (uint8_t)(((long)tm & 0xff000000) >> 24);
|
||||||
@ -227,14 +228,22 @@ static int process_server_hello(SSL *ssl)
|
|||||||
{
|
{
|
||||||
uint8_t *buf = ssl->bm_data;
|
uint8_t *buf = ssl->bm_data;
|
||||||
int pkt_size = ssl->bm_index;
|
int pkt_size = ssl->bm_index;
|
||||||
int version = (buf[4] << 4) + buf[5];
|
|
||||||
int num_sessions = ssl->ssl_ctx->num_sessions;
|
int num_sessions = ssl->ssl_ctx->num_sessions;
|
||||||
uint8_t sess_id_size;
|
uint8_t sess_id_size;
|
||||||
int offset, ret = SSL_OK;
|
int offset, ret = SSL_OK;
|
||||||
|
|
||||||
/* check that we are talking to a TLSv1 server */
|
/* check that we are talking to a TLSv1 server */
|
||||||
if (version != 0x31)
|
uint8_t version = (buf[4] << 4) + buf[5];
|
||||||
return SSL_ERROR_INVALID_VERSION;
|
if (version > SSL_PROTOCOL_VERSION)
|
||||||
|
version = SSL_PROTOCOL_VERSION;
|
||||||
|
else if (ssl->version < SSL_PROTOCOL_MIN_VERSION)
|
||||||
|
{
|
||||||
|
ret = SSL_ERROR_INVALID_VERSION;
|
||||||
|
ssl_display_error(ret);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl->version = version;
|
||||||
|
|
||||||
/* get the server random value */
|
/* get the server random value */
|
||||||
memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE);
|
memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE);
|
||||||
@ -300,7 +309,7 @@ static int send_client_key_xchg(SSL *ssl)
|
|||||||
buf[1] = 0;
|
buf[1] = 0;
|
||||||
|
|
||||||
premaster_secret[0] = 0x03; /* encode the version number */
|
premaster_secret[0] = 0x03; /* encode the version number */
|
||||||
premaster_secret[1] = 0x01;
|
premaster_secret[1] = SSL_PROTOCOL_MINOR_VERSION; /* must be TLS 1.1 */
|
||||||
get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]);
|
get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]);
|
||||||
DISPLAY_RSA(ssl, ssl->x509_ctx->rsa_ctx);
|
DISPLAY_RSA(ssl, ssl->x509_ctx->rsa_ctx);
|
||||||
|
|
||||||
|
@ -120,17 +120,20 @@ static int process_client_hello(SSL *ssl)
|
|||||||
uint8_t *record_buf = ssl->hmac_header;
|
uint8_t *record_buf = ssl->hmac_header;
|
||||||
int pkt_size = ssl->bm_index;
|
int pkt_size = ssl->bm_index;
|
||||||
int i, j, cs_len, id_len, offset = 6 + SSL_RANDOM_SIZE;
|
int i, j, cs_len, id_len, offset = 6 + SSL_RANDOM_SIZE;
|
||||||
int version = (record_buf[1] << 4) + record_buf[2];
|
|
||||||
int ret = SSL_OK;
|
int ret = SSL_OK;
|
||||||
|
|
||||||
/* should be v3.1 (TLSv1) or better - we'll send in v3.1 mode anyway */
|
/* should be v3.1 (TLSv1) or better - we'll send in v3.1 mode anyway */
|
||||||
if (version < 0x31)
|
uint8_t version = (record_buf[1] << 4) + record_buf[2];
|
||||||
|
if (version > SSL_PROTOCOL_VERSION)
|
||||||
|
version = SSL_PROTOCOL_VERSION;
|
||||||
|
else if (ssl->version < SSL_PROTOCOL_MIN_VERSION)
|
||||||
{
|
{
|
||||||
ret = SSL_ERROR_INVALID_VERSION;
|
ret = SSL_ERROR_INVALID_VERSION;
|
||||||
ssl_display_error(ret);
|
ssl_display_error(ret);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssl->version = ssl->client_version = version;
|
||||||
memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE);
|
memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE);
|
||||||
|
|
||||||
/* process the session id */
|
/* process the session id */
|
||||||
@ -151,10 +154,11 @@ static int process_client_hello(SSL *ssl)
|
|||||||
|
|
||||||
PARANOIA_CHECK(pkt_size, offset);
|
PARANOIA_CHECK(pkt_size, offset);
|
||||||
|
|
||||||
/* work out what cipher suite we are going to use */
|
/* work out what cipher suite we are going to use - client defines
|
||||||
for (j = 0; j < NUM_PROTOCOLS; j++)
|
the preference */
|
||||||
|
for (i = 0; i < cs_len; i += 2)
|
||||||
{
|
{
|
||||||
for (i = 0; i < cs_len; i += 2)
|
for (j = 0; j < NUM_PROTOCOLS; j++)
|
||||||
{
|
{
|
||||||
if (ssl_prot_prefs[j] == buf[offset+i]) /* got a match? */
|
if (ssl_prot_prefs[j] == buf[offset+i]) /* got a match? */
|
||||||
{
|
{
|
||||||
@ -180,7 +184,6 @@ int process_sslv23_client_hello(SSL *ssl)
|
|||||||
{
|
{
|
||||||
uint8_t *buf = ssl->bm_data;
|
uint8_t *buf = ssl->bm_data;
|
||||||
int bytes_needed = ((buf[0] & 0x7f) << 8) + buf[1];
|
int bytes_needed = ((buf[0] & 0x7f) << 8) + buf[1];
|
||||||
int version = (buf[3] << 4) + buf[4];
|
|
||||||
int ret = SSL_OK;
|
int ret = SSL_OK;
|
||||||
|
|
||||||
/* we have already read 3 extra bytes so far */
|
/* we have already read 3 extra bytes so far */
|
||||||
@ -193,8 +196,9 @@ int process_sslv23_client_hello(SSL *ssl)
|
|||||||
|
|
||||||
DISPLAY_BYTES(ssl, "received %d bytes", buf, read_len, read_len);
|
DISPLAY_BYTES(ssl, "received %d bytes", buf, read_len, read_len);
|
||||||
|
|
||||||
/* should be v3.1 (TLSv1) or better - we'll send in v3.1 mode anyway */
|
/* should be v3.1 (TLSv1) or better */
|
||||||
if (version < 0x31)
|
ssl->version = (buf[3] << 4) + buf[4];
|
||||||
|
if (ssl->version < SSL_PROTOCOL_MIN_VERSION)
|
||||||
{
|
{
|
||||||
return SSL_ERROR_INVALID_VERSION;
|
return SSL_ERROR_INVALID_VERSION;
|
||||||
}
|
}
|
||||||
@ -308,7 +312,7 @@ static int send_server_hello(SSL *ssl)
|
|||||||
buf[2] = 0;
|
buf[2] = 0;
|
||||||
/* byte 3 is calculated later */
|
/* byte 3 is calculated later */
|
||||||
buf[4] = 0x03;
|
buf[4] = 0x03;
|
||||||
buf[5] = 0x01;
|
buf[5] = ssl->version & 0x0f;
|
||||||
|
|
||||||
/* server random value */
|
/* server random value */
|
||||||
get_random(SSL_RANDOM_SIZE, &buf[6]);
|
get_random(SSL_RANDOM_SIZE, &buf[6]);
|
||||||
@ -396,11 +400,12 @@ static int process_client_key_xchg(SSL *ssl)
|
|||||||
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
|
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
|
||||||
|
|
||||||
if (premaster_size != SSL_SECRET_SIZE ||
|
if (premaster_size != SSL_SECRET_SIZE ||
|
||||||
premaster_secret[0] != 0x03 || /* check version is 3.1 (TLS) */
|
premaster_secret[0] != 0x03 || /* must be the same as client
|
||||||
premaster_secret[1] != 0x01)
|
offered version */
|
||||||
|
premaster_secret[1] != (ssl->client_version & 0x0f))
|
||||||
{
|
{
|
||||||
/* guard against a Bleichenbacher attack */
|
/* guard against a Bleichenbacher attack */
|
||||||
memset(premaster_secret, 0, SSL_SECRET_SIZE);
|
get_random(SSL_SECRET_SIZE, premaster_secret);
|
||||||
/* and continue - will die eventually when checking the mac */
|
/* and continue - will die eventually when checking the mac */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user