mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-22 21:23:07 +03:00
TLSv1.1 feature added.
git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@207 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
parent
1a19505e76
commit
70a8f79fa6
2
ssl/test/killgnutls.sh
Executable file
2
ssl/test/killgnutls.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
ps -ef|grep gnutls-serv | /usr/bin/awk '{print $2}' |xargs kill -9
|
@ -802,7 +802,7 @@ static void do_client(client_t *clnt)
|
||||
"-connect localhost:%d %s 2>&1 | grep \"Session-ID:\"",
|
||||
g_port, clnt->openssl_option);
|
||||
}
|
||||
else
|
||||
else if (strstr(clnt->testname, "GNUTLS") == NULL)
|
||||
{
|
||||
sprintf(openssl_buf, "echo \"hello client\" | openssl s_client -tls1 "
|
||||
#ifdef WIN32
|
||||
@ -812,6 +812,16 @@ static void do_client(client_t *clnt)
|
||||
#endif
|
||||
g_port, clnt->openssl_option);
|
||||
}
|
||||
else /* gnutls */
|
||||
{
|
||||
sprintf(openssl_buf, "echo \"hello client\" | gnutls-cli "
|
||||
#ifdef WIN32
|
||||
"-p %d %s 127.0.0.1",
|
||||
#else
|
||||
"-p %d %s 127.0.0.1 > /dev/null 2>&1",
|
||||
#endif
|
||||
g_port, clnt->openssl_option);
|
||||
}
|
||||
|
||||
system(openssl_buf);
|
||||
}
|
||||
@ -1243,6 +1253,15 @@ int SSL_server_tests(void)
|
||||
NULL, "abcd", DEFAULT_SVR_OPTION)))
|
||||
goto cleanup;
|
||||
|
||||
/*
|
||||
* GNUTLS
|
||||
*/
|
||||
if ((ret = SSL_server_test("GNUTLS client",
|
||||
"",
|
||||
"../ssl/test/axTLS.x509_1024.cer", NULL,
|
||||
"../ssl/test/axTLS.key_1024",
|
||||
NULL, NULL, DEFAULT_SVR_OPTION)))
|
||||
goto cleanup;
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
@ -1279,6 +1298,7 @@ typedef struct
|
||||
{
|
||||
const char *testname;
|
||||
const char *openssl_option;
|
||||
int do_gnutls;
|
||||
} server_t;
|
||||
|
||||
static void do_server(server_t *svr)
|
||||
@ -1287,8 +1307,17 @@ static void do_server(server_t *svr)
|
||||
#ifndef WIN32
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||
#endif
|
||||
sprintf(openssl_buf, "openssl s_server -tls1 "
|
||||
"-accept %d -quiet %s ", g_port, svr->openssl_option);
|
||||
if (svr->do_gnutls)
|
||||
{
|
||||
sprintf(openssl_buf, "gnutls-serv "
|
||||
"-p %d --quiet %s ", g_port, svr->openssl_option);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(openssl_buf, "openssl s_server -tls1 "
|
||||
"-accept %d -quiet %s ", g_port, svr->openssl_option);
|
||||
}
|
||||
|
||||
system(openssl_buf);
|
||||
}
|
||||
|
||||
@ -1311,6 +1340,8 @@ static int SSL_client_test(
|
||||
pthread_t thread;
|
||||
#endif
|
||||
|
||||
server_data.do_gnutls = strstr(test, "GNUTLS") != NULL;
|
||||
|
||||
if (sess_resume == NULL || sess_resume->start_server)
|
||||
{
|
||||
g_port++;
|
||||
@ -1592,6 +1623,14 @@ int SSL_client_tests(void)
|
||||
}
|
||||
|
||||
printf("SSL client test \"Invalid certificate type\" passed\n");
|
||||
|
||||
if ((ret = SSL_client_test("GNUTLS client",
|
||||
&ssl_ctx,
|
||||
"--x509certfile ../ssl/test/axTLS.x509_1024.pem "
|
||||
"--x509keyfile ../ssl/test/axTLS.key_1024.pem -q", NULL,
|
||||
DEFAULT_CLNT_OPTION, NULL, NULL, NULL)))
|
||||
goto cleanup;
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
@ -1600,6 +1639,7 @@ cleanup:
|
||||
ssl_display_error(ret);
|
||||
printf("Error: A client test failed\n");
|
||||
system("sh ../ssl/test/killopenssl.sh");
|
||||
system("sh ../ssl/test/killgnutls.sh");
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
@ -2171,6 +2211,7 @@ int main(int argc, char *argv[])
|
||||
goto cleanup;
|
||||
|
||||
system("sh ../ssl/test/killopenssl.sh");
|
||||
system("sh ../ssl/test/killgnutls.sh");
|
||||
|
||||
if (SSL_server_tests())
|
||||
goto cleanup;
|
||||
|
90
ssl/tls1.c
90
ssl/tls1.c
@ -715,7 +715,7 @@ static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else /* stream cipher */
|
||||
{
|
||||
hmac_offset = read_len - ssl->cipher_info->digest_size;
|
||||
|
||||
@ -1009,9 +1009,7 @@ static int send_raw_packet(SSL *ssl, uint8_t protocol)
|
||||
*/
|
||||
int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length)
|
||||
{
|
||||
int msg_length = length;
|
||||
int ret, pad_bytes = 0;
|
||||
ssl->bm_index = msg_length;
|
||||
int ret, msg_length = 0;
|
||||
|
||||
/* if our state is bad, don't bother */
|
||||
if (ssl->hs_status == SSL_ERROR_DEAD)
|
||||
@ -1022,17 +1020,19 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length)
|
||||
memcpy(ssl->bm_data, in, length);
|
||||
}
|
||||
|
||||
msg_length += length;
|
||||
if (IS_SET_SSL_FLAG(SSL_TX_ENCRYPTED))
|
||||
{
|
||||
int mode = IS_SET_SSL_FLAG(SSL_IS_CLIENT) ?
|
||||
SSL_CLIENT_WRITE : SSL_SERVER_WRITE;
|
||||
uint8_t hmac_header[SSL_RECORD_SIZE];
|
||||
|
||||
hmac_header[0] = protocol;
|
||||
hmac_header[1] = 0x03; /* version = 3.1 or higher */
|
||||
hmac_header[2] = ssl->version & 0x0f;
|
||||
hmac_header[3] = length >> 8;
|
||||
hmac_header[4] = length & 0xff;
|
||||
uint8_t hmac_header[SSL_RECORD_SIZE] =
|
||||
{
|
||||
protocol,
|
||||
0x03, /* version = 3.1 or higher */
|
||||
ssl->version & 0x0f,
|
||||
msg_length >> 8,
|
||||
msg_length & 0xff
|
||||
};
|
||||
|
||||
if (protocol == PT_HANDSHAKE_PROTOCOL)
|
||||
{
|
||||
@ -1040,21 +1040,20 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length)
|
||||
|
||||
if (ssl->bm_data[0] != HS_HELLO_REQUEST)
|
||||
{
|
||||
add_packet(ssl, ssl->bm_data, ssl->bm_index);
|
||||
add_packet(ssl, ssl->bm_data, msg_length);
|
||||
}
|
||||
}
|
||||
|
||||
/* add the packet digest */
|
||||
add_hmac_digest(ssl, mode, hmac_header, ssl->bm_data, msg_length,
|
||||
&ssl->bm_data[msg_length]);
|
||||
msg_length += ssl->cipher_info->digest_size;
|
||||
ssl->bm_index = msg_length;
|
||||
add_hmac_digest(ssl, mode, hmac_header, ssl->bm_data, length,
|
||||
&ssl->bm_data[length]);
|
||||
|
||||
/* add padding? */
|
||||
if (ssl->cipher_info->padding_size)
|
||||
{
|
||||
int last_blk_size = msg_length%ssl->cipher_info->padding_size;
|
||||
pad_bytes = ssl->cipher_info->padding_size - last_blk_size;
|
||||
int pad_bytes = ssl->cipher_info->padding_size - last_blk_size;
|
||||
|
||||
/* ensure we always have at least 1 padding byte */
|
||||
if (pad_bytes == 0)
|
||||
@ -1062,12 +1061,24 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length)
|
||||
|
||||
memset(&ssl->bm_data[msg_length], pad_bytes-1, pad_bytes);
|
||||
msg_length += pad_bytes;
|
||||
ssl->bm_index = msg_length;
|
||||
}
|
||||
|
||||
DISPLAY_BYTES(ssl, "unencrypted write", ssl->bm_data, msg_length);
|
||||
increment_write_sequence(ssl);
|
||||
|
||||
/* add the explicit IV for TLS1.1 */
|
||||
if (ssl->version >= SSL_PROTOCOL_VERSION1_1 &&
|
||||
ssl->cipher_info->iv_size)
|
||||
|
||||
{
|
||||
uint8_t iv_size = ssl->cipher_info->iv_size;
|
||||
uint8_t *t_buf = alloca(msg_length + iv_size);
|
||||
memcpy(t_buf + iv_size, ssl->bm_data, msg_length);
|
||||
get_random(iv_size, t_buf);
|
||||
msg_length += iv_size;
|
||||
memcpy(ssl->bm_data, t_buf, msg_length);
|
||||
}
|
||||
|
||||
/* now encrypt the packet */
|
||||
ssl->cipher_info->encrypt(ssl->encrypt_ctx, ssl->bm_data,
|
||||
ssl->bm_data, msg_length);
|
||||
@ -1078,10 +1089,11 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length)
|
||||
|
||||
if (ssl->bm_data[0] != HS_HELLO_REQUEST)
|
||||
{
|
||||
add_packet(ssl, ssl->bm_data, ssl->bm_index);
|
||||
add_packet(ssl, ssl->bm_data, length);
|
||||
}
|
||||
}
|
||||
|
||||
ssl->bm_index = msg_length;
|
||||
if ((ret = send_raw_packet(ssl, protocol)) <= 0)
|
||||
return ret;
|
||||
|
||||
@ -1223,10 +1235,27 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
||||
if (IS_SET_SSL_FLAG(SSL_NEED_RECORD))
|
||||
{
|
||||
/* check for sslv2 "client hello" */
|
||||
if (buf[0] & 0x80 && buf[2] == 1 && buf[3] == 0x03)
|
||||
if (buf[0] & 0x80 && buf[2] == 1)
|
||||
{
|
||||
#ifdef CONFIG_SSL_ENABLE_V23_HANDSHAKE
|
||||
uint8_t version = (buf[3] << 4) + buf[4];
|
||||
DISPLAY_BYTES(ssl, "ssl2 record", buf, 5);
|
||||
|
||||
/* should be v3.1 (TLSv1) or better */
|
||||
ssl->version = ssl->client_version = version;
|
||||
|
||||
if (version > SSL_PROTOCOL_VERSION_MAX)
|
||||
{
|
||||
/* use client's version */
|
||||
ssl->version = SSL_PROTOCOL_VERSION_MAX;
|
||||
}
|
||||
else if (version < SSL_PROTOCOL_MIN_VERSION)
|
||||
{
|
||||
ret = SSL_ERROR_INVALID_VERSION;
|
||||
ssl_display_error(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
add_packet(ssl, &buf[2], 3);
|
||||
ret = process_sslv23_client_hello(ssl);
|
||||
#else
|
||||
@ -1259,6 +1288,14 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
||||
if (IS_SET_SSL_FLAG(SSL_RX_ENCRYPTED))
|
||||
{
|
||||
ssl->cipher_info->decrypt(ssl->decrypt_ctx, buf, buf, read_len);
|
||||
|
||||
if (ssl->version >= SSL_PROTOCOL_VERSION1_1 &&
|
||||
ssl->cipher_info->iv_size)
|
||||
{
|
||||
buf += ssl->cipher_info->iv_size;
|
||||
read_len -= ssl->cipher_info->iv_size;
|
||||
}
|
||||
|
||||
read_len = verify_digest(ssl,
|
||||
is_client ? SSL_CLIENT_READ : SSL_SERVER_READ, buf, read_len);
|
||||
|
||||
@ -1310,7 +1347,7 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
||||
case PT_APP_PROTOCOL_DATA:
|
||||
if (in_data)
|
||||
{
|
||||
*in_data = ssl->bm_data; /* point to the work buffer */
|
||||
*in_data = buf; /* point to the work buffer */
|
||||
(*in_data)[read_len] = 0; /* null terminate just in case */
|
||||
}
|
||||
|
||||
@ -1414,12 +1451,8 @@ int send_change_cipher_spec(SSL *ssl)
|
||||
*/
|
||||
int send_finished(SSL *ssl)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
|
||||
buf[0] = HS_FINISHED;
|
||||
buf[1] = 0;
|
||||
buf[2] = 0;
|
||||
buf[3] = SSL_FINISHED_HASH_SIZE;
|
||||
uint8_t buf[SSL_FINISHED_HASH_SIZE+4] = {
|
||||
HS_FINISHED, 0, 0, SSL_FINISHED_HASH_SIZE };
|
||||
|
||||
/* now add the finished digest mac (12 bytes) */
|
||||
finished_digest(ssl,
|
||||
@ -1436,7 +1469,7 @@ int send_finished(SSL *ssl)
|
||||
#endif
|
||||
|
||||
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL,
|
||||
NULL, SSL_FINISHED_HASH_SIZE+4);
|
||||
buf, SSL_FINISHED_HASH_SIZE+4);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1516,9 +1549,8 @@ int send_alert(SSL *ssl, int error_code)
|
||||
/**
|
||||
* Process a client finished message.
|
||||
*/
|
||||
int process_finished(SSL *ssl, int hs_len)
|
||||
int process_finished(SSL *ssl, uint8_t *buf, int hs_len)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
int ret = SSL_OK;
|
||||
int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
|
||||
int resume = IS_SET_SSL_FLAG(SSL_SESSION_RESUME);
|
||||
|
@ -45,10 +45,9 @@ extern "C" {
|
||||
#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_PROTOCOL_MINOR_VERSION 0x02 /* TLS v1.1 */
|
||||
#define SSL_PROTOCOL_VERSION_MAX 0x32 /* TLS v1.1 */
|
||||
#define SSL_PROTOCOL_VERSION1_1 0x32 /* TLS v1.1 */
|
||||
#define SSL_RANDOM_SIZE 32
|
||||
#define SSL_SECRET_SIZE 48
|
||||
#define SSL_FINISHED_HASH_SIZE 12
|
||||
@ -236,7 +235,7 @@ int send_packet(SSL *ssl, uint8_t protocol,
|
||||
const uint8_t *in, int length);
|
||||
int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len);
|
||||
int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len);
|
||||
int process_finished(SSL *ssl, int hs_len);
|
||||
int process_finished(SSL *ssl, uint8_t *buf, int hs_len);
|
||||
int process_sslv23_client_hello(SSL *ssl);
|
||||
int send_alert(SSL *ssl, int error_code);
|
||||
int send_finished(SSL *ssl);
|
||||
|
@ -51,7 +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)
|
||||
{
|
||||
SSL *ssl = ssl_new(ssl_ctx, client_fd);
|
||||
ssl->version = SSL_PROTOCOL_VERSION;
|
||||
ssl->version = SSL_PROTOCOL_VERSION_MAX; /* try top version first */
|
||||
|
||||
if (session_id && ssl_ctx->num_sessions)
|
||||
{
|
||||
@ -118,7 +118,7 @@ int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
|
||||
break;
|
||||
|
||||
case HS_FINISHED:
|
||||
ret = process_finished(ssl, hs_len);
|
||||
ret = process_finished(ssl, buf, hs_len);
|
||||
disposable_free(ssl); /* free up some memory */
|
||||
/* note: client renegotiation is not allowed after this */
|
||||
break;
|
||||
@ -234,8 +234,10 @@ static int process_server_hello(SSL *ssl)
|
||||
|
||||
/* check that we are talking to a TLSv1 server */
|
||||
uint8_t version = (buf[4] << 4) + buf[5];
|
||||
if (version > SSL_PROTOCOL_VERSION)
|
||||
version = SSL_PROTOCOL_VERSION;
|
||||
if (version > SSL_PROTOCOL_VERSION_MAX)
|
||||
{
|
||||
version = SSL_PROTOCOL_VERSION_MAX;
|
||||
}
|
||||
else if (ssl->version < SSL_PROTOCOL_MIN_VERSION)
|
||||
{
|
||||
ret = SSL_ERROR_INVALID_VERSION;
|
||||
|
@ -103,7 +103,7 @@ int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
|
||||
break;
|
||||
|
||||
case HS_FINISHED:
|
||||
ret = process_finished(ssl, hs_len);
|
||||
ret = process_finished(ssl, buf, hs_len);
|
||||
disposable_free(ssl); /* free up some memory */
|
||||
break;
|
||||
}
|
||||
@ -125,8 +125,11 @@ static int process_client_hello(SSL *ssl)
|
||||
uint8_t version = (record_buf[1] << 4) + record_buf[2];
|
||||
ssl->version = ssl->client_version = version;
|
||||
|
||||
if (version > SSL_PROTOCOL_VERSION)
|
||||
ssl->version = SSL_PROTOCOL_VERSION; /* use client's version */
|
||||
if (version > SSL_PROTOCOL_VERSION_MAX)
|
||||
{
|
||||
/* use client's version instead */
|
||||
ssl->version = SSL_PROTOCOL_VERSION_MAX;
|
||||
}
|
||||
else if (version < SSL_PROTOCOL_MIN_VERSION) /* old version supported? */
|
||||
{
|
||||
ret = SSL_ERROR_INVALID_VERSION;
|
||||
@ -196,13 +199,6 @@ int process_sslv23_client_hello(SSL *ssl)
|
||||
|
||||
DISPLAY_BYTES(ssl, "received %d bytes", buf, read_len, read_len);
|
||||
|
||||
/* should be v3.1 (TLSv1) or better */
|
||||
ssl->version = (buf[3] << 4) + buf[4];
|
||||
if (ssl->version < SSL_PROTOCOL_MIN_VERSION)
|
||||
{
|
||||
return SSL_ERROR_INVALID_VERSION;
|
||||
}
|
||||
|
||||
add_packet(ssl, buf, read_len);
|
||||
|
||||
/* connection has gone, so die */
|
||||
|
Loading…
x
Reference in New Issue
Block a user