mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-17 22:23:10 +03:00
* Initial crack at TLS 1.2 client side only (server side is seriously broken).
git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@263 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
committed by
Yasuki Ikeuchi
parent
abda243710
commit
d476a79411
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2015, Cameron Rich
|
* Copyright (c) 2007-2016, Cameron Rich
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@ -200,6 +200,8 @@ void hmac_md5(const uint8_t *msg, int length, const uint8_t *key,
|
|||||||
int key_len, uint8_t *digest);
|
int key_len, uint8_t *digest);
|
||||||
void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key,
|
void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key,
|
||||||
int key_len, uint8_t *digest);
|
int key_len, uint8_t *digest);
|
||||||
|
void hmac_sha256(const uint8_t *msg, int length, const uint8_t *key,
|
||||||
|
int key_len, uint8_t *digest);
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* RSA declarations
|
* RSA declarations
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, Cameron Rich
|
* Copyright (c) 2007-2016, Cameron Rich
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@ -103,3 +103,37 @@ void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key,
|
|||||||
SHA1_Update(&context, digest, SHA1_SIZE);
|
SHA1_Update(&context, digest, SHA1_SIZE);
|
||||||
SHA1_Final(digest, &context);
|
SHA1_Final(digest, &context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform HMAC-SHA256
|
||||||
|
* NOTE: does not handle keys larger than the block size.
|
||||||
|
*/
|
||||||
|
void hmac_sha256(const uint8_t *msg, int length, const uint8_t *key,
|
||||||
|
int key_len, uint8_t *digest)
|
||||||
|
{
|
||||||
|
SHA256_CTX context;
|
||||||
|
uint8_t k_ipad[64];
|
||||||
|
uint8_t k_opad[64];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(k_ipad, 0, sizeof k_ipad);
|
||||||
|
memset(k_opad, 0, sizeof k_opad);
|
||||||
|
memcpy(k_ipad, key, key_len);
|
||||||
|
memcpy(k_opad, key, key_len);
|
||||||
|
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
k_ipad[i] ^= 0x36;
|
||||||
|
k_opad[i] ^= 0x5c;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHA256_Init(&context);
|
||||||
|
SHA256_Update(&context, k_ipad, 64);
|
||||||
|
SHA256_Update(&context, msg, length);
|
||||||
|
SHA256_Final(digest, &context);
|
||||||
|
SHA256_Init(&context);
|
||||||
|
SHA256_Update(&context, k_opad, 64);
|
||||||
|
SHA256_Update(&context, digest, SHA256_SIZE);
|
||||||
|
SHA256_Final(digest, &context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ extern "C" {
|
|||||||
#define SSL_ERROR_INVALID_PROT_MSG -261
|
#define SSL_ERROR_INVALID_PROT_MSG -261
|
||||||
#define SSL_ERROR_INVALID_HMAC -262
|
#define SSL_ERROR_INVALID_HMAC -262
|
||||||
#define SSL_ERROR_INVALID_VERSION -263
|
#define SSL_ERROR_INVALID_VERSION -263
|
||||||
|
#define SSL_ERROR_UNSUPPORTED_EXTENSION -264
|
||||||
#define SSL_ERROR_INVALID_SESSION -265
|
#define SSL_ERROR_INVALID_SESSION -265
|
||||||
#define SSL_ERROR_NO_CIPHER -266
|
#define SSL_ERROR_NO_CIPHER -266
|
||||||
#define SSL_ERROR_BAD_CERTIFICATE -268
|
#define SSL_ERROR_BAD_CERTIFICATE -268
|
||||||
@ -128,12 +129,13 @@ extern "C" {
|
|||||||
#define SSL_ALERT_DECRYPT_ERROR 51
|
#define SSL_ALERT_DECRYPT_ERROR 51
|
||||||
#define SSL_ALERT_INVALID_VERSION 70
|
#define SSL_ALERT_INVALID_VERSION 70
|
||||||
#define SSL_ALERT_NO_RENEGOTIATION 100
|
#define SSL_ALERT_NO_RENEGOTIATION 100
|
||||||
|
#define SSL_ALERT_UNSUPPORTED_EXTENSION 110
|
||||||
|
|
||||||
/* The ciphers that are supported */
|
/* The ciphers that are supported */
|
||||||
#define SSL_AES128_SHA 0x2f
|
#define SSL_AES128_SHA 0x2f
|
||||||
#define SSL_AES256_SHA 0x35
|
#define SSL_AES256_SHA 0x35
|
||||||
#define SSL_RC4_128_SHA 0x05
|
#define SSL_AES128_SHA256 0x3c
|
||||||
#define SSL_RC4_128_MD5 0x04
|
#define SSL_AES256_SHA256 0x3d
|
||||||
|
|
||||||
/* build mode ids' */
|
/* build mode ids' */
|
||||||
#define SSL_BUILD_SKELETON_MODE 0x01
|
#define SSL_BUILD_SKELETON_MODE 0x01
|
||||||
|
238
ssl/tls1.c
238
ssl/tls1.c
@ -64,13 +64,14 @@ static void session_free(SSL_SESSION *ssl_sessions[], int sess_index);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] =
|
const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] =
|
||||||
#ifdef CONFIG_SSL_PROT_LOW /* same as medium for now */
|
#ifdef CONFIG_SSL_PROT_LOW /* low security, fast speed */
|
||||||
{ SSL_AES128_SHA, SSL_AES256_SHA };
|
{ SSL_AES128_SHA, SSL_AES128_SHA256, SSL_AES256_SHA, SSL_AES256_SHA256 };
|
||||||
#elif CONFIG_SSL_PROT_MEDIUM /* medium security, medium speed */
|
#elif CONFIG_SSL_PROT_MEDIUM /* medium security, medium speed */
|
||||||
{ SSL_AES128_SHA, SSL_AES256_SHA };
|
{ SSL_AES128_SHA256, SSL_AES256_SHA256, SSL_AES256_SHA, SSL_AES128_SHA };
|
||||||
#else /* CONFIG_SSL_PROT_HIGH */ /* high security, low speed */
|
#else /* CONFIG_SSL_PROT_HIGH */ /* high security, low speed */
|
||||||
{ SSL_AES256_SHA, SSL_AES128_SHA };
|
{ SSL_AES256_SHA, SSL_AES128_SHA256, SSL_AES_256_SHA, SSL_AES128_SHA };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The cipher map containing all the essentials for each cipher.
|
* The cipher map containing all the essentials for each cipher.
|
||||||
*/
|
*/
|
||||||
@ -80,9 +81,9 @@ static const cipher_info_t cipher_info[NUM_PROTOCOLS] =
|
|||||||
SSL_AES128_SHA, /* AES128-SHA */
|
SSL_AES128_SHA, /* AES128-SHA */
|
||||||
16, /* key size */
|
16, /* key size */
|
||||||
16, /* iv size */
|
16, /* iv size */
|
||||||
2*(SHA1_SIZE+16+16), /* key block size */
|
|
||||||
16, /* block padding size */
|
16, /* block padding size */
|
||||||
SHA1_SIZE, /* digest size */
|
SHA1_SIZE, /* digest size */
|
||||||
|
2*(SHA1_SIZE+16+16), /* key block size */
|
||||||
hmac_sha1, /* hmac algorithm */
|
hmac_sha1, /* hmac algorithm */
|
||||||
(crypt_func)AES_cbc_encrypt, /* encrypt */
|
(crypt_func)AES_cbc_encrypt, /* encrypt */
|
||||||
(crypt_func)AES_cbc_decrypt /* decrypt */
|
(crypt_func)AES_cbc_decrypt /* decrypt */
|
||||||
@ -90,17 +91,40 @@ static const cipher_info_t cipher_info[NUM_PROTOCOLS] =
|
|||||||
{ /* AES256-SHA */
|
{ /* AES256-SHA */
|
||||||
SSL_AES256_SHA, /* AES256-SHA */
|
SSL_AES256_SHA, /* AES256-SHA */
|
||||||
32, /* key size */
|
32, /* key size */
|
||||||
16, /* iv size */
|
16, /* iv size */
|
||||||
2*(SHA1_SIZE+32+16), /* key block size */
|
|
||||||
16, /* block padding size */
|
16, /* block padding size */
|
||||||
SHA1_SIZE, /* digest size */
|
SHA1_SIZE, /* digest size */
|
||||||
|
2*(SHA1_SIZE+32+16), /* key block size */
|
||||||
hmac_sha1, /* hmac algorithm */
|
hmac_sha1, /* hmac algorithm */
|
||||||
(crypt_func)AES_cbc_encrypt, /* encrypt */
|
(crypt_func)AES_cbc_encrypt, /* encrypt */
|
||||||
(crypt_func)AES_cbc_decrypt /* decrypt */
|
(crypt_func)AES_cbc_decrypt /* decrypt */
|
||||||
},
|
},
|
||||||
|
{ /* AES128-SHA256 */
|
||||||
|
SSL_AES128_SHA256, /* AES128-SHA256 */
|
||||||
|
16, /* key size */
|
||||||
|
16, /* iv size */
|
||||||
|
16, /* block padding size */
|
||||||
|
SHA256_SIZE, /* digest size */
|
||||||
|
2*(SHA256_SIZE+32+16), /* key block size */
|
||||||
|
hmac_sha256, /* hmac algorithm */
|
||||||
|
(crypt_func)AES_cbc_encrypt, /* encrypt */
|
||||||
|
(crypt_func)AES_cbc_decrypt /* decrypt */
|
||||||
|
},
|
||||||
|
{ /* AES256-SHA256 */
|
||||||
|
SSL_AES256_SHA256, /* AES256-SHA256 */
|
||||||
|
32, /* key size */
|
||||||
|
16, /* iv size */
|
||||||
|
16, /* block padding size */
|
||||||
|
SHA256_SIZE, /* digest size */
|
||||||
|
2*(SHA256_SIZE+32+16), /* key block size */
|
||||||
|
hmac_sha256, /* hmac algorithm */
|
||||||
|
(crypt_func)AES_cbc_encrypt, /* encrypt */
|
||||||
|
(crypt_func)AES_cbc_decrypt /* decrypt */
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void prf(const uint8_t *sec, int sec_len, uint8_t *seed, int seed_len,
|
static void prf(SSL *ssl, const uint8_t *sec, int sec_len,
|
||||||
|
uint8_t *seed, int seed_len,
|
||||||
uint8_t *out, int olen);
|
uint8_t *out, int olen);
|
||||||
static const cipher_info_t *get_cipher_info(uint8_t cipher);
|
static const cipher_info_t *get_cipher_info(uint8_t cipher);
|
||||||
static void increment_read_sequence(SSL *ssl);
|
static void increment_read_sequence(SSL *ssl);
|
||||||
@ -615,36 +639,19 @@ static void increment_write_sequence(SSL *ssl)
|
|||||||
static void add_hmac_digest(SSL *ssl, int mode, uint8_t *hmac_header,
|
static void add_hmac_digest(SSL *ssl, int mode, uint8_t *hmac_header,
|
||||||
const uint8_t *buf, int buf_len, uint8_t *hmac_buf)
|
const uint8_t *buf, int buf_len, uint8_t *hmac_buf)
|
||||||
{
|
{
|
||||||
const size_t prefix_size = 8 + SSL_RECORD_SIZE;
|
int hmac_len = buf_len + 8 + SSL_RECORD_SIZE;
|
||||||
bool hmac_inplace = (uint32_t)buf - (uint32_t)ssl->bm_data >= prefix_size;
|
uint8_t *t_buf = (uint8_t *)alloca(buf_len);
|
||||||
uint8_t tmp[prefix_size];
|
|
||||||
int hmac_len = buf_len + prefix_size;
|
|
||||||
uint8_t *t_buf;
|
|
||||||
if (hmac_inplace) {
|
|
||||||
t_buf = ((uint8_t*)buf) - prefix_size;
|
|
||||||
memcpy(tmp, t_buf, prefix_size);
|
|
||||||
} else {
|
|
||||||
t_buf = (uint8_t *)malloc(hmac_len+10);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(t_buf, (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_WRITE) ?
|
memcpy(t_buf, (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_WRITE) ?
|
||||||
ssl->write_sequence : ssl->read_sequence, 8);
|
ssl->write_sequence : ssl->read_sequence, 8);
|
||||||
memcpy(&t_buf[8], hmac_header, SSL_RECORD_SIZE);
|
memcpy(&t_buf[8], hmac_header, SSL_RECORD_SIZE);
|
||||||
if (!hmac_inplace) {
|
memcpy(&t_buf[8+SSL_RECORD_SIZE], buf, buf_len);
|
||||||
memcpy(&t_buf[8+SSL_RECORD_SIZE], buf, buf_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
ssl->cipher_info->hmac(t_buf, hmac_len,
|
ssl->cipher_info->hmac(t_buf, hmac_len,
|
||||||
(mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ) ?
|
(mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ) ?
|
||||||
ssl->server_mac : ssl->client_mac,
|
ssl->server_mac : ssl->client_mac,
|
||||||
ssl->cipher_info->digest_size, hmac_buf);
|
ssl->cipher_info->digest_size, hmac_buf);
|
||||||
|
|
||||||
if (hmac_inplace) {
|
|
||||||
memcpy(t_buf, tmp, prefix_size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
free(t_buf);
|
|
||||||
}
|
|
||||||
#if 0
|
#if 0
|
||||||
print_blob("record", hmac_header, SSL_RECORD_SIZE);
|
print_blob("record", hmac_header, SSL_RECORD_SIZE);
|
||||||
print_blob("buf", buf, buf_len);
|
print_blob("buf", buf, buf_len);
|
||||||
@ -667,7 +674,7 @@ static void add_hmac_digest(SSL *ssl, int mode, uint8_t *hmac_header,
|
|||||||
print_blob("client mac",
|
print_blob("client mac",
|
||||||
ssl->client_mac, ssl->cipher_info->digest_size);
|
ssl->client_mac, ssl->cipher_info->digest_size);
|
||||||
}
|
}
|
||||||
print_blob("hmac", hmac_buf, SHA1_SIZE);
|
print_blob("hmac", hmac_buf, ssl->cipher_info->digest_size);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,7 +683,7 @@ static void add_hmac_digest(SSL *ssl, int mode, uint8_t *hmac_header,
|
|||||||
*/
|
*/
|
||||||
static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len)
|
static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len)
|
||||||
{
|
{
|
||||||
uint8_t hmac_buf[SHA1_SIZE];
|
uint8_t hmac_buf[SHA256_SIZE];
|
||||||
int hmac_offset;
|
int hmac_offset;
|
||||||
|
|
||||||
if (ssl->cipher_info->padding_size)
|
if (ssl->cipher_info->padding_size)
|
||||||
@ -731,8 +738,15 @@ static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len)
|
|||||||
*/
|
*/
|
||||||
void add_packet(SSL *ssl, const uint8_t *pkt, int len)
|
void add_packet(SSL *ssl, const uint8_t *pkt, int len)
|
||||||
{
|
{
|
||||||
MD5_Update(&ssl->dc->md5_ctx, pkt, len);
|
if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2
|
||||||
SHA1_Update(&ssl->dc->sha1_ctx, pkt, len);
|
{
|
||||||
|
SHA256_Update(&ssl->dc->sha256_ctx, pkt, len);
|
||||||
|
}
|
||||||
|
else // TLS1.0/1.0
|
||||||
|
{
|
||||||
|
MD5_Update(&ssl->dc->md5_ctx, pkt, len);
|
||||||
|
SHA1_Update(&ssl->dc->sha1_ctx, pkt, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -791,27 +805,63 @@ static void p_hash_sha1(const uint8_t *sec, int sec_len,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Work out the SHA256 PRF.
|
||||||
|
*/
|
||||||
|
static void p_hash_sha256(const uint8_t *sec, int sec_len,
|
||||||
|
uint8_t *seed, int seed_len, uint8_t *out, int olen)
|
||||||
|
{
|
||||||
|
uint8_t a1[128];
|
||||||
|
|
||||||
|
/* A(1) */
|
||||||
|
hmac_sha256(seed, seed_len, sec, sec_len, a1);
|
||||||
|
memcpy(&a1[SHA256_SIZE], seed, seed_len);
|
||||||
|
hmac_sha256(a1, SHA256_SIZE+seed_len, sec, sec_len, out);
|
||||||
|
|
||||||
|
while (olen > SHA256_SIZE)
|
||||||
|
{
|
||||||
|
uint8_t a2[SHA256_SIZE];
|
||||||
|
out += SHA256_SIZE;
|
||||||
|
olen -= SHA256_SIZE;
|
||||||
|
|
||||||
|
// A(N)
|
||||||
|
hmac_sha256(a1, SHA256_SIZE, sec, sec_len, a2);
|
||||||
|
memcpy(a1, a2, SHA256_SIZE);
|
||||||
|
|
||||||
|
// work out the actual hash
|
||||||
|
hmac_sha256(a1, SHA256_SIZE+seed_len, sec, sec_len, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Work out the PRF.
|
* Work out the PRF.
|
||||||
*/
|
*/
|
||||||
static void prf(const uint8_t *sec, int sec_len, uint8_t *seed, int seed_len,
|
static void prf(SSL *ssl, const uint8_t *sec, int sec_len,
|
||||||
|
uint8_t *seed, int seed_len,
|
||||||
uint8_t *out, int olen)
|
uint8_t *out, int olen)
|
||||||
{
|
{
|
||||||
int len, i;
|
if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2
|
||||||
const uint8_t *S1, *S2;
|
{
|
||||||
uint8_t xbuf[256]; /* needs to be > the amount of key data */
|
p_hash_sha256(sec, sec_len, seed, seed_len, out, olen);
|
||||||
uint8_t ybuf[256]; /* needs to be > the amount of key data */
|
}
|
||||||
|
else // TLS1.0/1.1
|
||||||
|
{
|
||||||
|
int len, i;
|
||||||
|
const uint8_t *S1, *S2;
|
||||||
|
uint8_t xbuf[256]; /* needs to be > the amount of key data */
|
||||||
|
uint8_t ybuf[256]; /* needs to be > the amount of key data */
|
||||||
|
|
||||||
len = sec_len/2;
|
len = sec_len/2;
|
||||||
S1 = sec;
|
S1 = sec;
|
||||||
S2 = &sec[len];
|
S2 = &sec[len];
|
||||||
len += (sec_len & 1); /* add for odd, make longer */
|
len += (sec_len & 1); /* add for odd, make longer */
|
||||||
|
|
||||||
p_hash_md5(S1, len, seed, seed_len, xbuf, olen);
|
p_hash_md5(S1, len, seed, seed_len, xbuf, olen);
|
||||||
p_hash_sha1(S2, len, seed, seed_len, ybuf, olen);
|
p_hash_sha1(S2, len, seed, seed_len, ybuf, olen);
|
||||||
|
|
||||||
for (i = 0; i < olen; i++)
|
for (i = 0; i < olen; i++)
|
||||||
out[i] = xbuf[i] ^ ybuf[i];
|
out[i] = xbuf[i] ^ ybuf[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -821,24 +871,32 @@ static void prf(const uint8_t *sec, int sec_len, uint8_t *seed, int seed_len,
|
|||||||
void generate_master_secret(SSL *ssl, const uint8_t *premaster_secret)
|
void generate_master_secret(SSL *ssl, const uint8_t *premaster_secret)
|
||||||
{
|
{
|
||||||
uint8_t buf[128]; /* needs to be > 13+32+32 in size */
|
uint8_t buf[128]; /* needs to be > 13+32+32 in size */
|
||||||
|
//print_blob("premaster secret", premaster_secret, 48);
|
||||||
strcpy((char *)buf, "master secret");
|
strcpy((char *)buf, "master secret");
|
||||||
memcpy(&buf[13], ssl->dc->client_random, SSL_RANDOM_SIZE);
|
memcpy(&buf[13], ssl->dc->client_random, SSL_RANDOM_SIZE);
|
||||||
memcpy(&buf[45], ssl->dc->server_random, SSL_RANDOM_SIZE);
|
memcpy(&buf[45], ssl->dc->server_random, SSL_RANDOM_SIZE);
|
||||||
prf(premaster_secret, SSL_SECRET_SIZE, buf, 77, ssl->dc->master_secret,
|
prf(ssl, premaster_secret, SSL_SECRET_SIZE, buf, 77, ssl->dc->master_secret,
|
||||||
SSL_SECRET_SIZE);
|
SSL_SECRET_SIZE);
|
||||||
|
#if 0
|
||||||
|
print_blob("client random", ssl->dc->client_random, 32);
|
||||||
|
print_blob("server random", ssl->dc->server_random, 32);
|
||||||
|
print_blob("master secret", ssl->dc->master_secret, 48);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a 'random' blob of data used for the generation of keys.
|
* Generate a 'random' blob of data used for the generation of keys.
|
||||||
*/
|
*/
|
||||||
static void generate_key_block(uint8_t *client_random, uint8_t *server_random,
|
static void generate_key_block(SSL *ssl,
|
||||||
|
uint8_t *client_random, uint8_t *server_random,
|
||||||
uint8_t *master_secret, uint8_t *key_block, int key_block_size)
|
uint8_t *master_secret, uint8_t *key_block, int key_block_size)
|
||||||
{
|
{
|
||||||
uint8_t buf[128];
|
uint8_t buf[128];
|
||||||
strcpy((char *)buf, "key expansion");
|
strcpy((char *)buf, "key expansion");
|
||||||
memcpy(&buf[13], server_random, SSL_RANDOM_SIZE);
|
memcpy(&buf[13], server_random, SSL_RANDOM_SIZE);
|
||||||
memcpy(&buf[45], client_random, SSL_RANDOM_SIZE);
|
memcpy(&buf[45], client_random, SSL_RANDOM_SIZE);
|
||||||
prf(master_secret, SSL_SECRET_SIZE, buf, 77, key_block, key_block_size);
|
prf(ssl, master_secret, SSL_SECRET_SIZE, buf, 77,
|
||||||
|
key_block, key_block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -849,8 +907,6 @@ void finished_digest(SSL *ssl, const char *label, uint8_t *digest)
|
|||||||
{
|
{
|
||||||
uint8_t mac_buf[128];
|
uint8_t mac_buf[128];
|
||||||
uint8_t *q = mac_buf;
|
uint8_t *q = mac_buf;
|
||||||
MD5_CTX md5_ctx = ssl->dc->md5_ctx;
|
|
||||||
SHA1_CTX sha1_ctx = ssl->dc->sha1_ctx;
|
|
||||||
|
|
||||||
if (label)
|
if (label)
|
||||||
{
|
{
|
||||||
@ -858,25 +914,47 @@ void finished_digest(SSL *ssl, const char *label, uint8_t *digest)
|
|||||||
q += strlen(label);
|
q += strlen(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
MD5_Final(q, &md5_ctx);
|
if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2
|
||||||
q += MD5_SIZE;
|
{
|
||||||
|
SHA256_CTX sha256_ctx = ssl->dc->sha256_ctx; // interim copy
|
||||||
SHA1_Final(q, &sha1_ctx);
|
SHA256_Final(q, &sha256_ctx);
|
||||||
q += SHA1_SIZE;
|
q += SHA256_SIZE;
|
||||||
|
|
||||||
if (label)
|
if (label)
|
||||||
{
|
{
|
||||||
prf(ssl->dc->master_secret, SSL_SECRET_SIZE, mac_buf, (int)(q-mac_buf),
|
prf(ssl, ssl->dc->master_secret, SSL_SECRET_SIZE,
|
||||||
digest, SSL_FINISHED_HASH_SIZE);
|
mac_buf, (int)(q-mac_buf), digest,
|
||||||
|
SSL_FINISHED_HASH_SIZE);
|
||||||
|
}
|
||||||
|
else // for use in a certificate verify
|
||||||
|
{
|
||||||
|
memcpy(digest, mac_buf, SHA256_SIZE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else /* for use in a certificate verify */
|
else // TLS1.0/1.1
|
||||||
{
|
{
|
||||||
memcpy(digest, mac_buf, MD5_SIZE + SHA1_SIZE);
|
MD5_CTX md5_ctx = ssl->dc->md5_ctx; // interim copy
|
||||||
|
SHA1_CTX sha1_ctx = ssl->dc->sha1_ctx;
|
||||||
|
|
||||||
|
MD5_Final(q, &md5_ctx);
|
||||||
|
q += MD5_SIZE;
|
||||||
|
|
||||||
|
SHA1_Final(q, &sha1_ctx);
|
||||||
|
q += SHA1_SIZE;
|
||||||
|
|
||||||
|
if (label)
|
||||||
|
{
|
||||||
|
prf(ssl, ssl->dc->master_secret, SSL_SECRET_SIZE,
|
||||||
|
mac_buf, (int)(q-mac_buf), digest, SSL_FINISHED_HASH_SIZE);
|
||||||
|
}
|
||||||
|
else /* for use in a certificate verify */
|
||||||
|
{
|
||||||
|
memcpy(digest, mac_buf, MD5_SIZE + SHA1_SIZE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("label: %s\n", label);
|
printf("label: %s\n", label);
|
||||||
print_blob("master secret", ssl->dc->master_secret, 48);
|
|
||||||
print_blob("mac_buf", mac_buf, q-mac_buf);
|
print_blob("mac_buf", mac_buf, q-mac_buf);
|
||||||
print_blob("finished digest", digest, SSL_FINISHED_HASH_SIZE);
|
print_blob("finished digest", digest, SSL_FINISHED_HASH_SIZE);
|
||||||
#endif
|
#endif
|
||||||
@ -890,6 +968,7 @@ static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt, void
|
|||||||
switch (ssl->cipher)
|
switch (ssl->cipher)
|
||||||
{
|
{
|
||||||
case SSL_AES128_SHA:
|
case SSL_AES128_SHA:
|
||||||
|
case SSL_AES128_SHA256:
|
||||||
{
|
{
|
||||||
AES_CTX *aes_ctx;
|
AES_CTX *aes_ctx;
|
||||||
if (cached)
|
if (cached)
|
||||||
@ -907,6 +986,7 @@ static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt, void
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SSL_AES256_SHA:
|
case SSL_AES256_SHA:
|
||||||
|
case SSL_AES256_SHA256:
|
||||||
{
|
{
|
||||||
AES_CTX *aes_ctx;
|
AES_CTX *aes_ctx;
|
||||||
if (cached)
|
if (cached)
|
||||||
@ -923,6 +1003,7 @@ static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt, void
|
|||||||
|
|
||||||
return (void *)aes_ctx;
|
return (void *)aes_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL; /* its all gone wrong */
|
return NULL; /* its all gone wrong */
|
||||||
@ -1058,7 +1139,7 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length)
|
|||||||
increment_write_sequence(ssl);
|
increment_write_sequence(ssl);
|
||||||
|
|
||||||
/* add the explicit IV for TLS1.1 */
|
/* add the explicit IV for TLS1.1 */
|
||||||
if (ssl->version >= SSL_PROTOCOL_VERSION1_1 &&
|
if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_1 &&
|
||||||
ssl->cipher_info->iv_size)
|
ssl->cipher_info->iv_size)
|
||||||
{
|
{
|
||||||
uint8_t iv_size = ssl->cipher_info->iv_size;
|
uint8_t iv_size = ssl->cipher_info->iv_size;
|
||||||
@ -1109,16 +1190,14 @@ static int set_key_block(SSL *ssl, int is_write)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* only do once in a handshake */
|
/* only do once in a handshake */
|
||||||
if (ssl->dc->key_block == NULL)
|
if (ssl->dc->bm_proc_index ==0 )
|
||||||
{
|
{
|
||||||
ssl->dc->key_block = (uint8_t *)malloc(ciph_info->key_block_size);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
print_blob("client", ssl->dc->client_random, 32);
|
print_blob("client", ssl->dc->client_random, 32);
|
||||||
print_blob("server", ssl->dc->server_random, 32);
|
print_blob("server", ssl->dc->server_random, 32);
|
||||||
print_blob("master", ssl->dc->master_secret, SSL_SECRET_SIZE);
|
print_blob("master", ssl->dc->master_secret, SSL_SECRET_SIZE);
|
||||||
#endif
|
#endif
|
||||||
generate_key_block(ssl->dc->client_random, ssl->dc->server_random,
|
generate_key_block(ssl, ssl->dc->client_random, ssl->dc->server_random,
|
||||||
ssl->dc->master_secret, ssl->dc->key_block,
|
ssl->dc->master_secret, ssl->dc->key_block,
|
||||||
ciph_info->key_block_size);
|
ciph_info->key_block_size);
|
||||||
#if 0
|
#if 0
|
||||||
@ -1146,13 +1225,10 @@ static int set_key_block(SSL *ssl, int is_write)
|
|||||||
memcpy(server_key, q, ciph_info->key_size);
|
memcpy(server_key, q, ciph_info->key_size);
|
||||||
q += ciph_info->key_size;
|
q += ciph_info->key_size;
|
||||||
|
|
||||||
if (ciph_info->iv_size) /* RC4 has no IV, AES does */
|
memcpy(client_iv, q, ciph_info->iv_size);
|
||||||
{
|
q += ciph_info->iv_size;
|
||||||
memcpy(client_iv, q, ciph_info->iv_size);
|
memcpy(server_iv, q, ciph_info->iv_size);
|
||||||
q += ciph_info->iv_size;
|
q += ciph_info->iv_size;
|
||||||
memcpy(server_iv, q, ciph_info->iv_size);
|
|
||||||
q += ciph_info->iv_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// free(is_write ? ssl->encrypt_ctx : ssl->decrypt_ctx);
|
// free(is_write ? ssl->encrypt_ctx : ssl->decrypt_ctx);
|
||||||
|
|
||||||
@ -1274,7 +1350,7 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
|||||||
{
|
{
|
||||||
ssl->cipher_info->decrypt(ssl->decrypt_ctx, buf, buf, read_len);
|
ssl->cipher_info->decrypt(ssl->decrypt_ctx, buf, buf, read_len);
|
||||||
|
|
||||||
if (ssl->version >= SSL_PROTOCOL_VERSION1_1 &&
|
if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_1 &&
|
||||||
ssl->cipher_info->iv_size)
|
ssl->cipher_info->iv_size)
|
||||||
{
|
{
|
||||||
buf += ssl->cipher_info->iv_size;
|
buf += ssl->cipher_info->iv_size;
|
||||||
@ -1464,7 +1540,7 @@ int send_change_cipher_spec(SSL *ssl)
|
|||||||
*/
|
*/
|
||||||
int send_finished(SSL *ssl)
|
int send_finished(SSL *ssl)
|
||||||
{
|
{
|
||||||
uint8_t buf[SSL_FINISHED_HASH_SIZE+4] = {
|
uint8_t buf[128] = {
|
||||||
HS_FINISHED, 0, 0, SSL_FINISHED_HASH_SIZE };
|
HS_FINISHED, 0, 0, SSL_FINISHED_HASH_SIZE };
|
||||||
|
|
||||||
/* now add the finished digest mac (12 bytes) */
|
/* now add the finished digest mac (12 bytes) */
|
||||||
@ -1653,6 +1729,7 @@ void disposable_new(SSL *ssl)
|
|||||||
if (ssl->dc == NULL)
|
if (ssl->dc == NULL)
|
||||||
{
|
{
|
||||||
ssl->dc = (DISPOSABLE_CTX *)calloc(1, sizeof(DISPOSABLE_CTX));
|
ssl->dc = (DISPOSABLE_CTX *)calloc(1, sizeof(DISPOSABLE_CTX));
|
||||||
|
SHA256_Init(&ssl->dc->sha256_ctx);
|
||||||
MD5_Init(&ssl->dc->md5_ctx);
|
MD5_Init(&ssl->dc->md5_ctx);
|
||||||
SHA1_Init(&ssl->dc->sha1_ctx);
|
SHA1_Init(&ssl->dc->sha1_ctx);
|
||||||
}
|
}
|
||||||
@ -1665,7 +1742,6 @@ void disposable_free(SSL *ssl)
|
|||||||
{
|
{
|
||||||
if (ssl->dc)
|
if (ssl->dc)
|
||||||
{
|
{
|
||||||
free(ssl->dc->key_block);
|
|
||||||
memset(ssl->dc, 0, sizeof(DISPOSABLE_CTX));
|
memset(ssl->dc, 0, sizeof(DISPOSABLE_CTX));
|
||||||
free(ssl->dc);
|
free(ssl->dc);
|
||||||
ssl->dc = NULL;
|
ssl->dc = NULL;
|
||||||
|
26
ssl/tls1.h
26
ssl/tls1.h
@ -48,9 +48,9 @@ extern "C" {
|
|||||||
#include "crypto_misc.h"
|
#include "crypto_misc.h"
|
||||||
|
|
||||||
#define SSL_PROTOCOL_MIN_VERSION 0x31 /* TLS v1.0 */
|
#define SSL_PROTOCOL_MIN_VERSION 0x31 /* TLS v1.0 */
|
||||||
#define SSL_PROTOCOL_MINOR_VERSION 0x02 /* TLS v1.1 */
|
#define SSL_PROTOCOL_VERSION_MAX 0x33 /* TLS v1.2 */
|
||||||
#define SSL_PROTOCOL_VERSION_MAX 0x32 /* TLS v1.1 */
|
#define SSL_PROTOCOL_VERSION_TLS1_1 0x32 /* TLS v1.1 */
|
||||||
#define SSL_PROTOCOL_VERSION1_1 0x32 /* TLS v1.1 */
|
#define SSL_PROTOCOL_VERSION_TLS1_2 0x33 /* TLS v1.2 */
|
||||||
#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
|
||||||
@ -80,7 +80,8 @@ extern "C" {
|
|||||||
#define RT_EXTRA 1024
|
#define RT_EXTRA 1024
|
||||||
#define BM_RECORD_OFFSET 5
|
#define BM_RECORD_OFFSET 5
|
||||||
|
|
||||||
#define NUM_PROTOCOLS 2
|
#define NUM_PROTOCOLS 4
|
||||||
|
#define SIG_ALG_EXTENSION 0x0d
|
||||||
|
|
||||||
#define PARANOIA_CHECK(A, B) if (A < B) { \
|
#define PARANOIA_CHECK(A, B) if (A < B) { \
|
||||||
ret = SSL_ERROR_INVALID_HANDSHAKE; goto error; }
|
ret = SSL_ERROR_INVALID_HANDSHAKE; goto error; }
|
||||||
@ -114,9 +115,9 @@ typedef struct
|
|||||||
uint8_t cipher;
|
uint8_t cipher;
|
||||||
uint8_t key_size;
|
uint8_t key_size;
|
||||||
uint8_t iv_size;
|
uint8_t iv_size;
|
||||||
uint8_t key_block_size;
|
|
||||||
uint8_t padding_size;
|
uint8_t padding_size;
|
||||||
uint8_t digest_size;
|
uint8_t digest_size;
|
||||||
|
uint8_t key_block_size;
|
||||||
hmac_func hmac;
|
hmac_func hmac;
|
||||||
crypt_func encrypt;
|
crypt_func encrypt;
|
||||||
crypt_func decrypt;
|
crypt_func decrypt;
|
||||||
@ -147,11 +148,12 @@ typedef struct
|
|||||||
{
|
{
|
||||||
MD5_CTX md5_ctx;
|
MD5_CTX md5_ctx;
|
||||||
SHA1_CTX sha1_ctx;
|
SHA1_CTX sha1_ctx;
|
||||||
uint8_t final_finish_mac[SSL_FINISHED_HASH_SIZE];
|
SHA256_CTX sha256_ctx;
|
||||||
uint8_t *key_block;
|
|
||||||
uint8_t master_secret[SSL_SECRET_SIZE];
|
|
||||||
uint8_t client_random[SSL_RANDOM_SIZE]; /* client's random sequence */
|
uint8_t client_random[SSL_RANDOM_SIZE]; /* client's random sequence */
|
||||||
uint8_t server_random[SSL_RANDOM_SIZE]; /* server's random sequence */
|
uint8_t server_random[SSL_RANDOM_SIZE]; /* server's random sequence */
|
||||||
|
uint8_t final_finish_mac[128];
|
||||||
|
uint8_t master_secret[SSL_SECRET_SIZE];
|
||||||
|
uint8_t key_block[256];
|
||||||
uint16_t bm_proc_index;
|
uint16_t bm_proc_index;
|
||||||
} DISPOSABLE_CTX;
|
} DISPOSABLE_CTX;
|
||||||
|
|
||||||
@ -189,10 +191,10 @@ struct _SSL
|
|||||||
bool can_free_certificates;
|
bool can_free_certificates;
|
||||||
#endif
|
#endif
|
||||||
uint8_t session_id[SSL_SESSION_ID_SIZE];
|
uint8_t session_id[SSL_SESSION_ID_SIZE];
|
||||||
uint8_t client_mac[SHA1_SIZE]; /* for HMAC verification */
|
uint8_t client_mac[SHA256_SIZE]; /* for HMAC verification */
|
||||||
uint8_t server_mac[SHA1_SIZE]; /* for HMAC verification */
|
uint8_t server_mac[SHA256_SIZE]; /* for HMAC verification */
|
||||||
uint8_t read_sequence[8]; /* 64 bit sequence number */
|
uint8_t read_sequence[8]; /* 64 bit sequence number */
|
||||||
uint8_t write_sequence[8]; /* 64 bit sequence number */
|
uint8_t write_sequence[8]; /* 64 bit sequence number */
|
||||||
uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */
|
uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */
|
||||||
char *host_name; /* Needed for the SNI support */
|
char *host_name; /* Needed for the SNI support */
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, Cameron Rich
|
* Copyright (c) 2007-2016, Cameron Rich
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@ -37,6 +37,11 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_SSL_ENABLE_CLIENT /* all commented out if no client */
|
#ifdef CONFIG_SSL_ENABLE_CLIENT /* all commented out if no client */
|
||||||
|
|
||||||
|
/* support sha512/384/256/224/1 rsa */
|
||||||
|
static const uint8_t g_sig_alg[] = { 0x00, 0x10,
|
||||||
|
0x00, SIG_ALG_EXTENSION, 0x00, 0x0c, 0x00, 0x0a,
|
||||||
|
0x06, 0x01, 0x05, 0x01, 0x04, 0x01, 0x03, 0x01, 0x02, 0x01 };
|
||||||
|
|
||||||
static int send_client_hello(SSL *ssl);
|
static int send_client_hello(SSL *ssl);
|
||||||
static int process_server_hello(SSL *ssl);
|
static int process_server_hello(SSL *ssl);
|
||||||
static int process_server_hello_done(SSL *ssl);
|
static int process_server_hello_done(SSL *ssl);
|
||||||
@ -227,23 +232,10 @@ static int send_client_hello(SSL *ssl)
|
|||||||
buf[offset++] = 1; /* no compression */
|
buf[offset++] = 1; /* no compression */
|
||||||
buf[offset++] = 0;
|
buf[offset++] = 0;
|
||||||
|
|
||||||
if (ssl->host_name != NULL) {
|
if (ssl->version > SSL_PROTOCOL_VERSION_TLS1_1)
|
||||||
unsigned int host_len = strlen(ssl->host_name);
|
{
|
||||||
|
memcpy(&buf[offset], g_sig_alg, sizeof(g_sig_alg));
|
||||||
buf[offset++] = 0;
|
offset += sizeof(g_sig_alg);
|
||||||
buf[offset++] = host_len+9; /* extensions length */
|
|
||||||
|
|
||||||
buf[offset++] = 0;
|
|
||||||
buf[offset++] = 0; /* server_name(0) (65535) */
|
|
||||||
buf[offset++] = 0;
|
|
||||||
buf[offset++] = host_len+5; /* server_name length */
|
|
||||||
buf[offset++] = 0;
|
|
||||||
buf[offset++] = host_len+3; /* server_list length */
|
|
||||||
buf[offset++] = 0; /* host_name(0) (255) */
|
|
||||||
buf[offset++] = 0;
|
|
||||||
buf[offset++] = host_len; /* host_name length */
|
|
||||||
strncpy((char*) &buf[offset], ssl->host_name, host_len);
|
|
||||||
offset += host_len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[3] = offset - 4; /* handshake size */
|
buf[3] = offset - 4; /* handshake size */
|
||||||
@ -306,13 +298,46 @@ static int process_server_hello(SSL *ssl)
|
|||||||
ssl->sess_id_size = sess_id_size;
|
ssl->sess_id_size = sess_id_size;
|
||||||
offset += sess_id_size;
|
offset += sess_id_size;
|
||||||
|
|
||||||
/* get the real cipher we are using */
|
/* get the real cipher we are using - ignore MSB */
|
||||||
ssl->cipher = buf[++offset];
|
ssl->cipher = buf[++offset];
|
||||||
ssl->next_state = IS_SET_SSL_FLAG(SSL_SESSION_RESUME) ?
|
ssl->next_state = IS_SET_SSL_FLAG(SSL_SESSION_RESUME) ?
|
||||||
HS_FINISHED : HS_CERTIFICATE;
|
HS_FINISHED : HS_CERTIFICATE;
|
||||||
|
|
||||||
offset++; // skip the compr
|
offset++; // skip the compr
|
||||||
PARANOIA_CHECK(pkt_size, offset);
|
PARANOIA_CHECK(pkt_size, offset);
|
||||||
|
|
||||||
|
// Check for extensions from the server - only the signature algorithm
|
||||||
|
// is supported
|
||||||
|
if (pkt_size > offset)
|
||||||
|
{
|
||||||
|
if (buf[offset++] > 0) // MSB of extension len must be 0
|
||||||
|
{
|
||||||
|
ret = SSL_ALERT_UNSUPPORTED_EXTENSION;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset++; // ignore the extension size as we only look at one
|
||||||
|
|
||||||
|
if (buf[offset++] == 0 && buf[offset++] == SIG_ALG_EXTENSION)
|
||||||
|
{
|
||||||
|
if (buf[offset++] != 0) // MSB of alg_sig_len must be 0
|
||||||
|
{
|
||||||
|
ret = SSL_ALERT_UNSUPPORTED_EXTENSION;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int alg_sig_len = buf[offset++];
|
||||||
|
offset += alg_sig_len;
|
||||||
|
PARANOIA_CHECK(pkt_size, offset);
|
||||||
|
// we don't use what comes back (for now)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = SSL_ALERT_UNSUPPORTED_EXTENSION;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ssl->dc->bm_proc_index = offset+1;
|
ssl->dc->bm_proc_index = offset+1;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -340,8 +365,10 @@ static int send_client_key_xchg(SSL *ssl)
|
|||||||
buf[0] = HS_CLIENT_KEY_XCHG;
|
buf[0] = HS_CLIENT_KEY_XCHG;
|
||||||
buf[1] = 0;
|
buf[1] = 0;
|
||||||
|
|
||||||
premaster_secret[0] = 0x03; /* encode the version number */
|
// spec says client must use the what is initially negotiated -
|
||||||
premaster_secret[1] = SSL_PROTOCOL_MINOR_VERSION; /* must be TLS 1.1 */
|
// and this is our current version
|
||||||
|
premaster_secret[0] = 0x03;
|
||||||
|
premaster_secret[1] = SSL_PROTOCOL_VERSION_MAX & 0x0f;
|
||||||
if (get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]) < 0)
|
if (get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]) < 0)
|
||||||
return SSL_NOT_OK;
|
return SSL_NOT_OK;
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ static int send_server_hello(SSL *ssl)
|
|||||||
|
|
||||||
buf[offset++] = 0; /* cipher we are using */
|
buf[offset++] = 0; /* cipher we are using */
|
||||||
buf[offset++] = ssl->cipher;
|
buf[offset++] = ssl->cipher;
|
||||||
buf[offset++] = 0; /* no compression */
|
buf[offset++] = 0; /* no compression and no extensions supported */
|
||||||
buf[3] = offset - 4; /* handshake size */
|
buf[3] = offset - 4; /* handshake size */
|
||||||
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
|
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user