1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +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:
cameronrich 2011-05-06 12:35:32 +00:00
parent 1a19505e76
commit 70a8f79fa6
6 changed files with 123 additions and 51 deletions

2
ssl/test/killgnutls.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
ps -ef|grep gnutls-serv | /usr/bin/awk '{print $2}' |xargs kill -9

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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 */