mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-30 16:24:09 +03:00
added versioning/fragmentation
git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@56 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
@ -210,6 +210,19 @@ config CONFIG_SSL_MAX_CERTS
|
||||
The default is to allow one certificate + 1 certificate in the chain
|
||||
(which may be the certificate authority certificate).
|
||||
|
||||
config CONFIG_SSLCTX_MUTEXING
|
||||
bool "Enable SSLCTX mutexing"
|
||||
default n
|
||||
help
|
||||
Normally mutexing is not required - each SSLCTX object can deal with
|
||||
many SSL objects (as long as each SSLCTX object is using a single
|
||||
thread).
|
||||
|
||||
If the SSLCTX object is not thread safe e.g. the case where a
|
||||
new thread is created for each SSL object, then mutexing is required.
|
||||
|
||||
Select y when a mutex on the SSLCTX object is required.
|
||||
|
||||
config CONFIG_USE_DEV_URANDOM
|
||||
bool "Use /dev/urandom"
|
||||
default y
|
||||
|
@ -39,7 +39,7 @@ endif
|
||||
|
||||
# shared library major/minor numbers
|
||||
LIBMAJOR=$(BASETARGET).1
|
||||
LIBMINOR=$(BASETARGET).1.0
|
||||
LIBMINOR=$(BASETARGET).1.1
|
||||
else
|
||||
TARGET1=axtls.lib
|
||||
TARGET2=../$(STAGE)/axtls.dll
|
||||
@ -49,7 +49,7 @@ endif
|
||||
libs: $(TARGET1) $(TARGET2)
|
||||
|
||||
OBJ=\
|
||||
aes.o \
|
||||
aes.o \
|
||||
asn1.o \
|
||||
bigint.o \
|
||||
crypto_misc.o \
|
||||
|
@ -400,7 +400,6 @@ static void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
a1 ^= tmp1 ^ AES_xtime(a1 ^ a2);
|
||||
a2 ^= tmp1 ^ AES_xtime(a2 ^ a3);
|
||||
a3 ^= tmp1 ^ AES_xtime(a3 ^ old_a0);
|
||||
|
||||
}
|
||||
|
||||
tmp[row] = ((a0 << 24) | (a1 << 16) | (a2 << 8) | a3);
|
||||
|
10
ssl/bigint.c
10
ssl/bigint.c
@ -781,7 +781,9 @@ void bi_free_mod(BI_CTX *ctx, int mod_offset)
|
||||
*/
|
||||
static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
|
||||
{
|
||||
int i, j, i_plus_j, n = bia->size, t = bib->size;
|
||||
int i, j, i_plus_j;
|
||||
int n = bia->size;
|
||||
int t = bib->size;
|
||||
bigint *biR = alloc(ctx, n + t);
|
||||
comp *sr = biR->comps;
|
||||
comp *sa = bia->comps;
|
||||
@ -1397,9 +1399,7 @@ bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
|
||||
|
||||
#ifdef CONFIG_BIGINT_SLIDING_WINDOW
|
||||
for (j = i; j > 32; j /= 5) /* work out an optimum size */
|
||||
{
|
||||
window_size++;
|
||||
}
|
||||
|
||||
/* work out the slide constants */
|
||||
precompute_slide_window(ctx, window_size, bi);
|
||||
@ -1420,15 +1420,11 @@ bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
|
||||
int part_exp = 0;
|
||||
|
||||
if (l < 0) /* LSB of exponent will always be 1 */
|
||||
{
|
||||
l = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (exp_bit_is_one(biexp, l) == 0)
|
||||
{
|
||||
l++; /* go back up */
|
||||
}
|
||||
}
|
||||
|
||||
/* build up the section of the exponent */
|
||||
|
10
ssl/bigint.h
10
ssl/bigint.h
@ -74,14 +74,14 @@ bigint *bi_str_import(BI_CTX *ctx, const char *data);
|
||||
* appropriate reduction technique (which is bi_mod() when doing classical
|
||||
* reduction).
|
||||
*/
|
||||
#if defined(CONFIG_BIGINT_CLASSICAL)
|
||||
#define bi_residue(A, B) bi_mod(A, B)
|
||||
#if defined(CONFIG_BIGINT_MONTGOMERY)
|
||||
#define bi_residue(A, B) bi_mont(A, B)
|
||||
bigint *bi_mont(BI_CTX *ctx, bigint *bixy);
|
||||
#elif defined(CONFIG_BIGINT_BARRETT)
|
||||
#define bi_residue(A, B) bi_barrett(A, B)
|
||||
bigint *bi_barrett(BI_CTX *ctx, bigint *bi);
|
||||
#else /* CONFIG_BIGINT_MONTGOMERY */
|
||||
#define bi_residue(A, B) bi_mont(A, B)
|
||||
bigint *bi_mont(BI_CTX *ctx, bigint *bixy);
|
||||
#else /* if defined(CONFIG_BIGINT_CLASSICAL) */
|
||||
#define bi_residue(A, B) bi_mod(A, B)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BIGINT_SQUARE
|
||||
|
21
ssl/crypto.h
21
ssl/crypto.h
@ -143,7 +143,6 @@ typedef struct
|
||||
bigint *qInv; /* q^-1 mod p */
|
||||
#endif
|
||||
int num_octets;
|
||||
bigint *sig_m; /* signature modulus */
|
||||
BI_CTX *bi_ctx;
|
||||
} RSA_CTX;
|
||||
|
||||
@ -163,15 +162,14 @@ void RSA_pub_key_new(RSA_CTX **rsa_ctx,
|
||||
const uint8_t *modulus, int mod_len,
|
||||
const uint8_t *pub_exp, int pub_len);
|
||||
void RSA_free(RSA_CTX *ctx);
|
||||
int RSA_decrypt(RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
|
||||
int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
|
||||
int is_decryption);
|
||||
bigint *RSA_private(RSA_CTX *c, bigint *bi_msg);
|
||||
bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg);
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
bigint *RSA_raw_sign_verify(RSA_CTX *c, bigint *bi_msg);
|
||||
bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
|
||||
bigint *modulus, bigint *pub_exp);
|
||||
bigint *RSA_public(RSA_CTX *c, bigint *bi_msg);
|
||||
int RSA_encrypt(RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
|
||||
bigint *RSA_public(const RSA_CTX * c, bigint *bi_msg);
|
||||
int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
|
||||
uint8_t *out_data, int is_signing);
|
||||
void RSA_print(const RSA_CTX *ctx);
|
||||
#endif
|
||||
@ -267,17 +265,6 @@ typedef void (*crypt_func)(void *, const uint8_t *, uint8_t *, int);
|
||||
typedef void (*hmac_func)(const uint8_t *msg, int length, const uint8_t *key,
|
||||
int key_len, uint8_t *digest);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *pre_data; /* include the ssl record bytes */
|
||||
uint8_t *data; /* the regular ssl data */
|
||||
int max_len;
|
||||
int index;
|
||||
} BUF_MEM;
|
||||
|
||||
BUF_MEM buf_new(void);
|
||||
void buf_grow(BUF_MEM *bm, int len);
|
||||
void buf_free(BUF_MEM *bm);
|
||||
int get_file(const char *filename, uint8_t **buf);
|
||||
|
||||
#if defined(CONFIG_SSL_FULL_MODE) || defined(WIN32) || defined(CONFIG_DEBUG)
|
||||
|
@ -29,8 +29,6 @@
|
||||
#include "wincrypt.h"
|
||||
#endif
|
||||
|
||||
#define BM_RECORD_OFFSET 5 /* same as SSL_RECORD_SIZE */
|
||||
|
||||
#ifndef WIN32
|
||||
static int rng_fd = -1;
|
||||
#elif defined(CONFIG_WIN32_USE_CRYPTO_LIB)
|
||||
@ -44,45 +42,6 @@ static uint64_t rng_num;
|
||||
static int rng_ref_count;
|
||||
const char * const unsupported_str = "Error: feature not supported\n";
|
||||
|
||||
/**
|
||||
* Allocate a new memory buffer
|
||||
*/
|
||||
BUF_MEM buf_new()
|
||||
{
|
||||
BUF_MEM bm;
|
||||
bm.pre_data = (uint8_t *)calloc(1, 2048); /* start with this */
|
||||
bm.data = bm.pre_data+BM_RECORD_OFFSET; /* some space at the start */
|
||||
bm.max_len = 2048-BM_RECORD_OFFSET;
|
||||
bm.index = 0;
|
||||
return bm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grow a buffer if necessary
|
||||
*/
|
||||
void buf_grow(BUF_MEM *bm, int len)
|
||||
{
|
||||
if (len <= bm->max_len)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* add 1kB just to be sure */
|
||||
bm->pre_data = (uint8_t *)realloc(bm->pre_data, len+1024+BM_RECORD_OFFSET);
|
||||
bm->data = bm->pre_data+BM_RECORD_OFFSET;
|
||||
bm->max_len = len + 1024;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a buffer
|
||||
*/
|
||||
void buf_free(BUF_MEM *bm)
|
||||
{
|
||||
free(bm->pre_data);
|
||||
bm->pre_data = NULL;
|
||||
bm->data = NULL;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SSL_SKELETON_MODE
|
||||
/**
|
||||
* Retrieve a file and put it into memory
|
||||
|
28
ssl/loader.c
28
ssl/loader.c
@ -76,9 +76,7 @@ EXP_FUNC int STDCALL ssl_obj_load(SSLCTX *ssl_ctx, int obj_type,
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = do_obj(ssl_ctx, obj_type, ssl_obj, password);
|
||||
}
|
||||
|
||||
error:
|
||||
ssl_obj_free(ssl_obj);
|
||||
@ -149,15 +147,18 @@ static int do_obj(SSLCTX *ssl_ctx, int obj_type,
|
||||
}
|
||||
|
||||
/*
|
||||
* Release things.
|
||||
* Clean up our mess.
|
||||
*/
|
||||
void ssl_obj_free(SSLObjLoader *ssl_obj)
|
||||
{
|
||||
free(ssl_obj->buf);
|
||||
free(ssl_obj);
|
||||
if (ssl_obj)
|
||||
{
|
||||
free(ssl_obj->buf);
|
||||
free(ssl_obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Support for PEM encoded keys/certificates.
|
||||
*/
|
||||
#ifdef CONFIG_SSL_HAS_PEM
|
||||
@ -214,7 +215,7 @@ static int base64_decode(const uint8_t *in, int len,
|
||||
g = 3;
|
||||
for (x = y = z = t = 0; x < len; x++)
|
||||
{
|
||||
if ((c = map[in[x]&0x7F]) == 0xff)
|
||||
if ((c = map[in[x] & 0x7F]) == 0xff)
|
||||
continue;
|
||||
|
||||
if (c == 254) /* this is the end... */
|
||||
@ -234,14 +235,10 @@ static int base64_decode(const uint8_t *in, int len,
|
||||
out[z++] = (uint8_t)((t>>16)&255);
|
||||
|
||||
if (g > 1)
|
||||
{
|
||||
out[z++] = (uint8_t)((t>>8)&255);
|
||||
}
|
||||
|
||||
if (g > 2)
|
||||
{
|
||||
out[z++] = (uint8_t)(t&255);
|
||||
}
|
||||
|
||||
y = t = 0;
|
||||
}
|
||||
@ -256,9 +253,7 @@ static int base64_decode(const uint8_t *in, int len,
|
||||
error:
|
||||
#ifdef CONFIG_SSL_FULL_MODE
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("Error: Invalid base64 file\n");
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@ -312,7 +307,7 @@ static int pem_decrypt(const uint8_t *where, const uint8_t *end,
|
||||
uint8_t c = *start++ - '0';
|
||||
iv[i] = (c > 9 ? c + '0' - 'A' + 10 : c) << 4;
|
||||
c = *start++ - '0';
|
||||
iv[i] +=(c > 9 ? c + '0' - 'A' + 10 : c);
|
||||
iv[i] += (c > 9 ? c + '0' - 'A' + 10 : c);
|
||||
}
|
||||
|
||||
while (*start == '\r' || *start == '\n')
|
||||
@ -402,10 +397,7 @@ static int new_pem_obj(SSLCTX *ssl_ctx, int is_cacert, uint8_t *where,
|
||||
|
||||
/* In a format we can now understand - so process it */
|
||||
if ((ret = do_obj(ssl_ctx, obj_type, ssl_obj, password)))
|
||||
{
|
||||
ssl_obj_free(ssl_obj);
|
||||
goto error;
|
||||
}
|
||||
|
||||
end += strlen(ends[i]);
|
||||
remain -= strlen(ends[i]);
|
||||
@ -415,7 +407,6 @@ static int new_pem_obj(SSLCTX *ssl_ctx, int is_cacert, uint8_t *where,
|
||||
remain--;
|
||||
}
|
||||
|
||||
ssl_obj_free(ssl_obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -428,6 +419,7 @@ static int new_pem_obj(SSLCTX *ssl_ctx, int is_cacert, uint8_t *where,
|
||||
ret = new_pem_obj(ssl_ctx, is_cacert, end, remain, password);
|
||||
|
||||
error:
|
||||
ssl_obj_free(ssl_obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ static void MD5Transform(uint32_t state[4], const uint8_t block[64]);
|
||||
static void Encode(uint8_t *output, uint32_t *input, uint32_t len);
|
||||
static void Decode(uint32_t *output, const uint8_t *input, uint32_t len);
|
||||
|
||||
static uint8_t PADDING[64] =
|
||||
static const uint8_t PADDING[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@ -114,8 +114,7 @@ void MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
|
||||
x = (uint32_t)((ctx->count[0] >> 3) & 0x3F);
|
||||
|
||||
/* Update number of bits */
|
||||
if ((ctx->count[0] += ((uint32_t)len << 3))
|
||||
< ((uint32_t)len << 3))
|
||||
if ((ctx->count[0] += ((uint32_t)len << 3)) < ((uint32_t)len << 3))
|
||||
ctx->count[1]++;
|
||||
ctx->count[1] += ((uint32_t)len >> 29);
|
||||
|
||||
|
@ -389,6 +389,7 @@ int pkcs12_decode(SSLCTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password)
|
||||
/* get the salt */
|
||||
if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 || len != 8)
|
||||
goto error;
|
||||
|
||||
salt = &buf[offset];
|
||||
|
||||
/* work out what the mac should be */
|
||||
|
@ -36,9 +36,7 @@ void RC4_setup(RC4_CTX *ctx, const uint8_t *key, int length)
|
||||
m = ctx->m;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
m[i] = i;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
@ -48,9 +46,7 @@ void RC4_setup(RC4_CTX *ctx, const uint8_t *key, int length)
|
||||
m[j] = a;
|
||||
|
||||
if (++k >= length)
|
||||
{
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
19
ssl/rsa.c
19
ssl/rsa.c
@ -28,7 +28,7 @@
|
||||
#include "crypto.h"
|
||||
|
||||
#ifdef CONFIG_BIGINT_CRT
|
||||
static bigint *bi_crt(RSA_CTX *rsa, bigint *bi);
|
||||
static bigint *bi_crt(const RSA_CTX *rsa, bigint *bi);
|
||||
#endif
|
||||
|
||||
void RSA_priv_key_new(RSA_CTX **ctx,
|
||||
@ -126,8 +126,8 @@ void RSA_free(RSA_CTX *rsa_ctx)
|
||||
* @return The number of bytes that were originally encrypted. -1 on error.
|
||||
* @see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
|
||||
*/
|
||||
int RSA_decrypt(RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
|
||||
int is_decryption)
|
||||
int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
|
||||
uint8_t *out_data, int is_decryption)
|
||||
{
|
||||
int byte_size = ctx->num_octets;
|
||||
uint8_t *block;
|
||||
@ -155,10 +155,9 @@ int RSA_decrypt(RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
|
||||
if (is_decryption == 0) /* PKCS1.5 signing pads with "0xff"s */
|
||||
{
|
||||
while (block[i++] == 0xff && i < byte_size);
|
||||
|
||||
if (block[i-2] != 0xff)
|
||||
{
|
||||
i = byte_size; /*ensure size is 0 */
|
||||
}
|
||||
}
|
||||
else /* PKCS1.5 encryption padding is random */
|
||||
#endif
|
||||
@ -169,9 +168,7 @@ int RSA_decrypt(RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
|
||||
|
||||
/* get only the bit we want */
|
||||
if (size > 0)
|
||||
{
|
||||
memcpy(out_data, &block[i], size);
|
||||
}
|
||||
|
||||
free(block);
|
||||
return size ? size : -1;
|
||||
@ -180,7 +177,7 @@ int RSA_decrypt(RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
|
||||
/**
|
||||
* Performs m = c^d mod n
|
||||
*/
|
||||
bigint *RSA_private(RSA_CTX *c, bigint *bi_msg)
|
||||
bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg)
|
||||
{
|
||||
#ifdef CONFIG_BIGINT_CRT
|
||||
return bi_crt(c, bi_msg);
|
||||
@ -197,7 +194,7 @@ bigint *RSA_private(RSA_CTX *c, bigint *bi_msg)
|
||||
* This should really be in bigint.c (and was at one stage), but needs
|
||||
* access to the RSA_CTX context...
|
||||
*/
|
||||
static bigint *bi_crt(RSA_CTX *rsa, bigint *bi)
|
||||
static bigint *bi_crt(const RSA_CTX *rsa, bigint *bi)
|
||||
{
|
||||
BI_CTX *ctx = rsa->bi_ctx;
|
||||
bigint *m1, *m2, *h;
|
||||
@ -245,7 +242,7 @@ void RSA_print(const RSA_CTX *rsa_ctx)
|
||||
/**
|
||||
* Performs c = m^e mod n
|
||||
*/
|
||||
bigint *RSA_public(RSA_CTX *c, bigint *bi_msg)
|
||||
bigint *RSA_public(const RSA_CTX * c, bigint *bi_msg)
|
||||
{
|
||||
c->bi_ctx->mod_offset = BIGINT_M_OFFSET;
|
||||
return bi_mod_power(c->bi_ctx, bi_msg, c->e);
|
||||
@ -255,7 +252,7 @@ bigint *RSA_public(RSA_CTX *c, bigint *bi_msg)
|
||||
* Use PKCS1.5 for encryption/signing.
|
||||
* see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
|
||||
*/
|
||||
int RSA_encrypt(RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
|
||||
int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
|
||||
uint8_t *out_data, int is_signing)
|
||||
{
|
||||
int byte_size = ctx->num_octets;
|
||||
|
@ -57,17 +57,13 @@ void SHA1Update(SHA1_CTX *ctx, const uint8_t *msg, int len)
|
||||
while (len--)
|
||||
{
|
||||
ctx->Message_Block[ctx->Message_Block_Index++] = (*msg & 0xFF);
|
||||
|
||||
ctx->Length_Low += 8;
|
||||
|
||||
if (ctx->Length_Low == 0)
|
||||
{
|
||||
ctx->Length_High++;
|
||||
}
|
||||
|
||||
if (ctx->Message_Block_Index == 64)
|
||||
{
|
||||
SHA1ProcessMessageBlock(ctx);
|
||||
}
|
||||
|
||||
msg++;
|
||||
}
|
||||
|
19
ssl/ssl.h
19
ssl/ssl.h
@ -150,14 +150,17 @@ extern "C" {
|
||||
* @brief Establish a new client/server context.
|
||||
*
|
||||
* This function is called before any client/server SSL connections are made.
|
||||
* If multiple threads are used, then each thread will have its own SSLCTX
|
||||
* context. Any number of connections may be made with a single
|
||||
* context.
|
||||
*
|
||||
* Each new connection will use the this context's private key and
|
||||
* certificate chain. If a different certificate chain is required, then a
|
||||
* different context needs to be be used.
|
||||
*
|
||||
* There are two threading models supported - a single thread with one
|
||||
* SSLCTX can support any number of SSL connections - and multiple threads can
|
||||
* support one SSLCTX object each (the default). But if a single SSLCTX
|
||||
* object uses many SSL objects in individual threads, then the
|
||||
* CONFIG_SSLCTX_MUTEXING option needs to be configured.
|
||||
*
|
||||
* @param options [in] Any particular options. At present the options
|
||||
* supported are:
|
||||
* - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if the server
|
||||
@ -233,6 +236,7 @@ EXP_FUNC void STDCALL ssl_free(SSL *ssl);
|
||||
|
||||
/**
|
||||
* @brief Read the SSL data stream.
|
||||
* The socket must be in blocking mode.
|
||||
* @param ssl [in] An SSL object reference.
|
||||
* @param in_data [out] If the read was successful, a pointer to the read
|
||||
* buffer will be here. Do NOT ever free this memory as this buffer is used in
|
||||
@ -248,7 +252,8 @@ EXP_FUNC void STDCALL ssl_free(SSL *ssl);
|
||||
EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data);
|
||||
|
||||
/**
|
||||
* @brief Write to the SSL data stream.
|
||||
* @brief Write to the SSL data stream.
|
||||
* The socket must be in blocking mode.
|
||||
* @param ssl [in] An SSL obect reference.
|
||||
* @param out_data [in] The data to be written
|
||||
* @param out_len [in] The number of bytes to be written.
|
||||
@ -407,6 +412,12 @@ EXP_FUNC int STDCALL ssl_obj_load(SSLCTX *ssl_ctx, int obj_type, const char *fil
|
||||
*/
|
||||
EXP_FUNC int STDCALL ssl_obj_memory_load(SSLCTX *ssl_ctx, int obj_type, const uint8_t *data, int len, const char *password);
|
||||
|
||||
/**
|
||||
* @brief Return the axTLS library version as a string.
|
||||
* @note New API function for v1.1
|
||||
*/
|
||||
EXP_FUNC const char * STDCALL ssl_version(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1445,179 +1445,269 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**************************************************************************
|
||||
* SSL Basic Testing (test a big packet handshake)
|
||||
*
|
||||
**************************************************************************/
|
||||
static uint8_t basic_buf[256*1024];
|
||||
|
||||
static void do_basic(void)
|
||||
{
|
||||
int client_fd;
|
||||
SSL *ssl_clnt;
|
||||
SSLCTX *ssl_clnt_ctx = ssl_ctx_new(
|
||||
DEFAULT_CLNT_OPTION, SSL_DEFAULT_CLNT_SESS);
|
||||
usleep(200000); /* allow server to start */
|
||||
|
||||
if ((client_fd = client_socket_init(g_port)) < 0)
|
||||
goto error;
|
||||
|
||||
if (ssl_obj_load(ssl_clnt_ctx, SSL_OBJ_X509_CACERT,
|
||||
"../ssl/test/axTLS.ca_x509.cer", NULL))
|
||||
goto error;
|
||||
|
||||
ssl_clnt = ssl_client_new(ssl_clnt_ctx, client_fd, NULL);
|
||||
|
||||
/* check the return status */
|
||||
if (ssl_handshake_status(ssl_clnt))
|
||||
{
|
||||
printf("Client ");
|
||||
ssl_display_error(ssl_handshake_status(ssl_clnt));
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssl_write(ssl_clnt, basic_buf, sizeof(basic_buf));
|
||||
ssl_free(ssl_clnt);
|
||||
|
||||
error:
|
||||
ssl_ctx_free(ssl_clnt_ctx);
|
||||
close(client_fd);
|
||||
|
||||
/* exit this thread */
|
||||
}
|
||||
|
||||
static int SSL_basic_test(void)
|
||||
{
|
||||
int server_fd, client_fd, ret = 0, size = 0, offset = 0;
|
||||
SSLCTX *ssl_svr_ctx = NULL;
|
||||
struct sockaddr_in client_addr;
|
||||
uint8_t *read_buf;
|
||||
int clnt_len = sizeof(client_addr);
|
||||
SSL *ssl_svr;
|
||||
#ifndef WIN32
|
||||
pthread_t thread;
|
||||
#endif
|
||||
memset(basic_buf, 0xA5, sizeof(basic_buf)/2);
|
||||
memset(&basic_buf[sizeof(basic_buf)/2], 0x5A, sizeof(basic_buf)/2);
|
||||
|
||||
if ((server_fd = server_socket_init(&g_port)) < 0)
|
||||
goto error;
|
||||
|
||||
ssl_svr_ctx = ssl_ctx_new(DEFAULT_SVR_OPTION, SSL_DEFAULT_SVR_SESS);
|
||||
|
||||
#ifndef WIN32
|
||||
pthread_create(&thread, NULL,
|
||||
(void *(*)(void *))do_basic, NULL);
|
||||
pthread_detach(thread);
|
||||
#else
|
||||
CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_basic, NULL, 0, NULL);
|
||||
#endif
|
||||
|
||||
/* Wait for a client to connect */
|
||||
if ((client_fd = accept(server_fd,
|
||||
(struct sockaddr *) &client_addr, &clnt_len)) < 0)
|
||||
{
|
||||
ret = SSL_ERROR_SOCK_SETUP_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* we are ready to go */
|
||||
ssl_svr = ssl_server_new(ssl_svr_ctx, client_fd);
|
||||
|
||||
do
|
||||
{
|
||||
while ((size = ssl_read(ssl_svr, &read_buf)) == SSL_OK);
|
||||
|
||||
if (size < SSL_OK) /* got some alert or something nasty */
|
||||
{
|
||||
printf("Server ");
|
||||
ssl_display_error(size);
|
||||
ret = size;
|
||||
break;
|
||||
}
|
||||
else /* looks more promising */
|
||||
{
|
||||
if (memcmp(read_buf, &basic_buf[offset], size) != 0)
|
||||
{
|
||||
ret = SSL_NOT_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
offset += size;
|
||||
} while (offset < sizeof(basic_buf));
|
||||
|
||||
printf(ret == SSL_OK && offset == sizeof(basic_buf) ?
|
||||
"SSL basic test passed\n" :
|
||||
"SSL basic test failed\n");
|
||||
TTY_FLUSH();
|
||||
|
||||
ssl_free(ssl_svr);
|
||||
close(server_fd);
|
||||
close(client_fd);
|
||||
|
||||
error:
|
||||
ssl_ctx_free(ssl_svr_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(WIN32) && defined(CONFIG_SSL_CTX_MUTEXING)
|
||||
/**************************************************************************
|
||||
* Multi-Threading Tests
|
||||
*
|
||||
**************************************************************************/
|
||||
#define NUM_THREADS 1
|
||||
#define NUM_THREADS_STR "1"
|
||||
|
||||
static SSL *my_ssls[NUM_THREADS*3]; /* enough for all client fds */
|
||||
#define NUM_THREADS 200
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SSLCTX *ssl_ctx;
|
||||
SSLCTX *ssl_clnt_ctx;
|
||||
int port;
|
||||
int thread_id;
|
||||
} multi_t;
|
||||
|
||||
int do_connect(multi_t *multi_data)
|
||||
void do_multi_clnt(multi_t *multi_data)
|
||||
{
|
||||
int res = 1, client_fd, i;
|
||||
SSL *ssl = NULL;
|
||||
char tmp[5];
|
||||
|
||||
/* make sure other threads work before this one */
|
||||
if (multi_data->thread_id == NUM_THREADS)
|
||||
{
|
||||
sleep(2); /* sets the maximum time this test will run */
|
||||
}
|
||||
|
||||
if ((client_fd = client_socket_init(multi_data->port)) < 0)
|
||||
goto client_test_exit;
|
||||
sleep(0);
|
||||
|
||||
ssl = ssl_client_new(multi_data->ssl_ctx, client_fd, NULL);
|
||||
sleep(1);
|
||||
ssl = ssl_client_new(multi_data->ssl_clnt_ctx, client_fd, NULL);
|
||||
|
||||
if ((res = ssl_handshake_status(ssl)))
|
||||
goto client_test_exit;
|
||||
|
||||
sprintf(tmp, "%d\n", multi_data->thread_id);
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
ssl_write(ssl, (uint8_t *)tmp, strlen(tmp)+1);
|
||||
printf("Client ");
|
||||
ssl_display_error(res);
|
||||
goto client_test_exit;
|
||||
}
|
||||
|
||||
res = 0;
|
||||
sprintf(tmp, "%d\n", multi_data->thread_id);
|
||||
for (i = 0; i < 10; i++)
|
||||
ssl_write(ssl, (uint8_t *)tmp, strlen(tmp)+1);
|
||||
|
||||
client_test_exit:
|
||||
ssl_free(ssl);
|
||||
close(client_fd);
|
||||
free(multi_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void do_multi_svr(SSL *ssl)
|
||||
{
|
||||
uint8_t *read_buf;
|
||||
int *res_ptr = malloc(sizeof(int));
|
||||
int res;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
res = ssl_read(ssl, &read_buf);
|
||||
|
||||
/* kill the client */
|
||||
if (res != SSL_OK)
|
||||
{
|
||||
if (res == SSL_ERROR_CONN_LOST)
|
||||
{
|
||||
close(ssl->client_fd);
|
||||
ssl_free(ssl);
|
||||
break;
|
||||
}
|
||||
else if (res > 0)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
else /* some problem */
|
||||
{
|
||||
printf("Server ");
|
||||
ssl_display_error(res);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res = SSL_OK;
|
||||
error:
|
||||
*res_ptr = res;
|
||||
pthread_exit(res_ptr);
|
||||
}
|
||||
|
||||
int multi_thread_test(void)
|
||||
{
|
||||
int server_fd;
|
||||
SSLCTX *ssl_server_ctx = NULL;
|
||||
uint8_t buf[1024];
|
||||
pthread_t threads[NUM_THREADS];
|
||||
int i, res = 1;
|
||||
SSLCTX *ssl_server_ctx;
|
||||
SSLCTX *ssl_clnt_ctx;
|
||||
pthread_t clnt_threads[NUM_THREADS];
|
||||
pthread_t svr_threads[NUM_THREADS];
|
||||
int i, res = 0;
|
||||
struct sockaddr_in client_addr;
|
||||
int clnt_len = sizeof(client_addr);
|
||||
fd_set read_set;
|
||||
int max_fd;
|
||||
int death_total = 0;
|
||||
SSLCTX *ssl_client_ctx = ssl_ctx_new(DEFAULT_CLNT_OPTION,
|
||||
SSL_DEFAULT_CLNT_SESS, NULL);
|
||||
|
||||
printf("Do multi-threading test (takes a minute)\n");
|
||||
|
||||
FD_ZERO(&read_set);
|
||||
ssl_server_ctx = ssl_ctx_new(DEFAULT_SVR_OPTION, SSL_DEFAULT_SVR_SESS);
|
||||
ssl_clnt_ctx = ssl_ctx_new(DEFAULT_CLNT_OPTION, SSL_DEFAULT_CLNT_SESS);
|
||||
|
||||
if (ssl_obj_load(ssl_clnt_ctx, SSL_OBJ_X509_CACERT,
|
||||
"../ssl/test/axTLS.ca_x509.cer", NULL))
|
||||
goto error;
|
||||
|
||||
if ((server_fd = server_socket_init(&g_port)) < 0)
|
||||
goto error;
|
||||
|
||||
FD_SET(server_fd, &read_set);
|
||||
max_fd = server_fd;
|
||||
|
||||
ssl_server_ctx = ssl_ctx_new(DEFAULT_SVR_OPTION|SSL_SERVER_VERIFY_LATER,
|
||||
SSL_DEFAULT_SVR_SESS, NULL);
|
||||
|
||||
for (i = 0; i < NUM_THREADS; i++)
|
||||
{
|
||||
multi_t *multi_data = (multi_t *)malloc(sizeof(multi_t));
|
||||
multi_data->ssl_ctx = ssl_server_ctx;
|
||||
multi_data->ssl_clnt_ctx = ssl_clnt_ctx;
|
||||
multi_data->port = g_port;
|
||||
multi_data->thread_id = i+1;
|
||||
if (pthread_create(&threads[i], NULL,
|
||||
(void *(*)(void *))do_connect, (void *)multi_data) < 0)
|
||||
goto error;
|
||||
pthread_create(&clnt_threads[i], NULL,
|
||||
(void *(*)(void *))do_multi_clnt, (void *)multi_data);
|
||||
pthread_detach(clnt_threads[i]);
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
|
||||
for (;;)
|
||||
for (i = 0; i < NUM_THREADS; i++)
|
||||
{
|
||||
fd_set rdfs = read_set;
|
||||
int n;
|
||||
SSL *ssl_svr;
|
||||
int client_fd = accept(server_fd,
|
||||
(struct sockaddr *)&client_addr, &clnt_len);
|
||||
|
||||
if ((n = select(max_fd+1, &rdfs, NULL, NULL, 0)) > 0)
|
||||
{
|
||||
while (n)
|
||||
{
|
||||
/* check for server */
|
||||
if (FD_ISSET(server_fd, &rdfs))
|
||||
{
|
||||
int client_fd = accept(server_fd,
|
||||
(struct sockaddr *)&client_addr, &clnt_len);
|
||||
if (client_fd < 0)
|
||||
goto error;
|
||||
|
||||
if (client_fd < 0)
|
||||
goto error;
|
||||
ssl_svr = ssl_server_new(ssl_server_ctx, client_fd);
|
||||
|
||||
if (client_fd > max_fd) /* set max fd */
|
||||
{
|
||||
max_fd = client_fd;
|
||||
}
|
||||
|
||||
my_ssls[client_fd] = ssl_server_new(
|
||||
ssl_server_ctx, client_fd);
|
||||
FD_SET(client_fd, &read_set);
|
||||
|
||||
if (--n == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
i = server_fd;
|
||||
|
||||
while (++i <= max_fd && n)
|
||||
{
|
||||
if (FD_ISSET(i, &rdfs))
|
||||
{
|
||||
SSL *ssl;
|
||||
ssl = my_ssls[i];
|
||||
res = ssl_read(ssl, &read_buf);
|
||||
n--;
|
||||
|
||||
/* kill the client */
|
||||
if (res != SSL_OK)
|
||||
{
|
||||
if (res == SSL_ERROR_CONN_LOST)
|
||||
{
|
||||
ssl_free(ssl);
|
||||
my_ssls[i] = NULL;
|
||||
close(i);
|
||||
FD_CLR(i, &read_set);
|
||||
death_total++;
|
||||
}
|
||||
else if (res > 0)
|
||||
{
|
||||
if (strcmp(NUM_THREADS_STR "\n",
|
||||
(const char *)buf) == 0)
|
||||
{
|
||||
sleep(1); /* allow rest of data */
|
||||
goto all_ok;
|
||||
}
|
||||
}
|
||||
else /* some problem */
|
||||
{
|
||||
printf("Got some problem %d\n", res);
|
||||
goto error;
|
||||
}
|
||||
} /* if */
|
||||
} /* if */
|
||||
} /* for */
|
||||
}
|
||||
}
|
||||
pthread_create(&svr_threads[i], NULL,
|
||||
(void *(*)(void *))do_multi_svr, (void *)ssl_svr);
|
||||
}
|
||||
|
||||
all_ok:
|
||||
printf("Multi-thread test passed (%d)\n", death_total);
|
||||
res = 0;
|
||||
/* make sure we've run all of the threads */
|
||||
for (i = 0; i < NUM_THREADS; i++)
|
||||
{
|
||||
void *thread_res;
|
||||
pthread_join(svr_threads[i], &thread_res);
|
||||
if (*((int *)thread_res) != 0)
|
||||
res = 1;
|
||||
free(thread_res);
|
||||
}
|
||||
|
||||
if (res)
|
||||
goto error;
|
||||
|
||||
printf("Multi-thread test passed (%d)\n", NUM_THREADS);
|
||||
error:
|
||||
ssl_ctx_free(ssl_server_ctx);
|
||||
ssl_ctx_free(ssl_client_ctx);
|
||||
ssl_ctx_free(ssl_clnt_ctx);
|
||||
close(server_fd);
|
||||
return res;
|
||||
}
|
||||
@ -1705,6 +1795,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
TTY_FLUSH();
|
||||
|
||||
#if !defined(WIN32) && defined(CONFIG_SSL_CTX_MUTEXING)
|
||||
if (multi_thread_test())
|
||||
goto cleanup;
|
||||
#endif
|
||||
|
||||
if (SSL_basic_test())
|
||||
goto cleanup;
|
||||
|
||||
system("sh ../ssl/test/killopenssl.sh");
|
||||
|
||||
if (SSL_client_tests())
|
||||
|
232
ssl/tls1.c
232
ssl/tls1.c
@ -165,6 +165,8 @@ EXP_FUNC SSLCTX *STDCALL ssl_ctx_new(uint32_t options, int num_sessions)
|
||||
ssl_ctx->num_sessions = num_sessions;
|
||||
#endif
|
||||
|
||||
SSL_CTX_MUTEX_INIT(ssl_ctx->mutex);
|
||||
|
||||
#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
|
||||
if (~options & SSL_NO_DEFAULT_KEY)
|
||||
{
|
||||
@ -201,7 +203,7 @@ EXP_FUNC void STDCALL ssl_ctx_free(SSLCTX *ssl_ctx)
|
||||
if (ssl_ctx == NULL)
|
||||
return;
|
||||
|
||||
ssl = ssl_ctx->sess_head;
|
||||
ssl = ssl_ctx->head;
|
||||
|
||||
/* clear out all the ssl entries */
|
||||
while (ssl)
|
||||
@ -214,9 +216,7 @@ EXP_FUNC void STDCALL ssl_ctx_free(SSLCTX *ssl_ctx)
|
||||
#ifndef CONFIG_SSL_SKELETON_MODE
|
||||
/* clear out all the sessions */
|
||||
for (i = 0; i < ssl_ctx->num_sessions; i++)
|
||||
{
|
||||
session_free(ssl_ctx->ssl_sessions, i);
|
||||
}
|
||||
|
||||
free(ssl_ctx->ssl_sessions);
|
||||
#endif
|
||||
@ -232,6 +232,7 @@ EXP_FUNC void STDCALL ssl_ctx_free(SSLCTX *ssl_ctx)
|
||||
remove_ca_certs(ssl_ctx->ca_cert_ctx);
|
||||
#endif
|
||||
ssl_ctx->chain_length = 0;
|
||||
SSL_CTX_MUTEX_DESTROY(ssl_ctx->mutex);
|
||||
RSA_free(ssl_ctx->rsa_ctx);
|
||||
RNG_terminate();
|
||||
free(ssl_ctx);
|
||||
@ -252,24 +253,20 @@ EXP_FUNC void STDCALL ssl_free(SSL *ssl)
|
||||
|
||||
ssl_ctx = ssl->ssl_ctx;
|
||||
|
||||
SSL_CTX_LOCK(ssl_ctx->mutex);
|
||||
|
||||
/* adjust the server SSL list */
|
||||
if (ssl->prev)
|
||||
{
|
||||
ssl->prev->next = ssl->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
ssl_ctx->sess_head = ssl->next;
|
||||
}
|
||||
ssl_ctx->head = ssl->next;
|
||||
|
||||
if (ssl->next)
|
||||
{
|
||||
ssl->next->prev = ssl->prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
ssl_ctx->sess_tail = ssl->prev;
|
||||
}
|
||||
ssl_ctx->tail = ssl->prev;
|
||||
|
||||
SSL_CTX_UNLOCK(ssl_ctx->mutex);
|
||||
|
||||
/* may already be free - but be sure */
|
||||
free(ssl->all_pkts);
|
||||
@ -278,7 +275,6 @@ EXP_FUNC void STDCALL ssl_free(SSL *ssl)
|
||||
free(ssl->encrypt_ctx);
|
||||
free(ssl->decrypt_ctx);
|
||||
free(ssl->master_secret);
|
||||
buf_free(&ssl->bm_buf);
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
x509_free(ssl->x509_ctx);
|
||||
#endif
|
||||
@ -315,15 +311,28 @@ EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data)
|
||||
EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len)
|
||||
{
|
||||
|
||||
int ret = send_packet(ssl, PT_APP_PROTOCOL_DATA, out_data, out_len);
|
||||
int n = out_len, nw, i, tot = 0;
|
||||
|
||||
/* make sure there is no problem with overflow due to padding etc */
|
||||
if (ret > out_len)
|
||||
/* maximum size of a TLS packet is around 16kB, so fragment */
|
||||
do
|
||||
{
|
||||
ret = out_len;
|
||||
}
|
||||
nw = n;
|
||||
|
||||
return ret;
|
||||
if (nw > RT_MAX_PLAIN_LENGTH) /* fragment if necessary */
|
||||
nw = RT_MAX_PLAIN_LENGTH;
|
||||
|
||||
if ((i = send_packet(ssl, PT_APP_PROTOCOL_DATA,
|
||||
&out_data[tot], nw)) <= 0)
|
||||
{
|
||||
out_len = i; /* an error */
|
||||
break;
|
||||
}
|
||||
|
||||
tot += i;
|
||||
n -= i;
|
||||
} while (n > 0);
|
||||
|
||||
return out_len;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -411,9 +420,7 @@ int add_cert_auth(SSLCTX *ssl_ctx, const uint8_t *buf, int len)
|
||||
|
||||
/* recurse? */
|
||||
if (len > 0)
|
||||
{
|
||||
ret = add_cert_auth(ssl_ctx, &buf[offset], len);
|
||||
}
|
||||
|
||||
error:
|
||||
return ret;
|
||||
@ -459,17 +466,24 @@ EXP_FUNC const char * STDCALL ssl_get_cert_dn(SSL *ssl, int component)
|
||||
*/
|
||||
EXP_FUNC SSL * STDCALL ssl_find(SSLCTX *ssl_ctx, int client_fd)
|
||||
{
|
||||
SSL *ssl = ssl_ctx->sess_head;
|
||||
SSL *ssl;
|
||||
|
||||
SSL_CTX_LOCK(ssl_ctx->mutex);
|
||||
ssl = ssl_ctx->head;
|
||||
|
||||
/* search through all the ssl entries */
|
||||
while (ssl)
|
||||
{
|
||||
if (ssl->client_fd == client_fd)
|
||||
{
|
||||
SSL_CTX_UNLOCK(ssl_ctx->mutex);
|
||||
return ssl;
|
||||
}
|
||||
|
||||
ssl = ssl->next;
|
||||
}
|
||||
|
||||
SSL_CTX_UNLOCK(ssl_ctx->mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -526,31 +540,33 @@ SSL *ssl_new(SSLCTX *ssl_ctx, int client_fd)
|
||||
SSL *ssl = (SSL *)calloc(1, sizeof(SSL));
|
||||
ssl->ssl_ctx = ssl_ctx;
|
||||
ssl->need_bytes = SSL_RECORD_SIZE; /* need a record */
|
||||
ssl->bm_buf = buf_new();
|
||||
ssl->client_fd = client_fd;
|
||||
ssl->flag = SSL_NEED_RECORD;
|
||||
ssl->certs = ssl_ctx->certs;
|
||||
ssl->chain_length = ssl_ctx->chain_length;
|
||||
ssl->bm_data = ssl->bm_all_data+BM_RECORD_OFFSET; /* space at the start */
|
||||
#ifdef CONFIG_ENABLE_VERIFICATION
|
||||
ssl->ca_cert_ctx = ssl_ctx->ca_cert_ctx;
|
||||
#endif
|
||||
|
||||
/* a bit hacky but saves a few bytes of memory */
|
||||
ssl->flag |= ssl_ctx->options;
|
||||
SSL_CTX_LOCK(ssl_ctx->mutex);
|
||||
|
||||
/* build up a linked list, so we can remove it all later */
|
||||
if (ssl_ctx->sess_head == NULL)
|
||||
if (ssl_ctx->head == NULL)
|
||||
{
|
||||
ssl_ctx->sess_head = ssl;
|
||||
ssl_ctx->sess_tail = ssl;
|
||||
ssl_ctx->head = ssl;
|
||||
ssl_ctx->tail = ssl;
|
||||
}
|
||||
else
|
||||
{
|
||||
ssl->prev = ssl_ctx->sess_tail;
|
||||
ssl_ctx->sess_tail->next = ssl;
|
||||
ssl_ctx->sess_tail = ssl;
|
||||
ssl->prev = ssl_ctx->tail;
|
||||
ssl_ctx->tail->next = ssl;
|
||||
ssl_ctx->tail = ssl;
|
||||
}
|
||||
|
||||
SSL_CTX_UNLOCK(ssl_ctx->mutex);
|
||||
|
||||
return ssl;
|
||||
}
|
||||
|
||||
@ -905,32 +921,30 @@ static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt)
|
||||
*/
|
||||
static int send_raw_packet(SSL *ssl, uint8_t protocol)
|
||||
{
|
||||
uint8_t *rec_buf = ssl->bm_buf.pre_data;
|
||||
int pkt_size = SSL_RECORD_SIZE+ssl->bm_buf.index;
|
||||
uint8_t *rec_buf = ssl->bm_all_data;
|
||||
int pkt_size = SSL_RECORD_SIZE+ssl->bm_index;
|
||||
int ret;
|
||||
|
||||
rec_buf[0] = protocol;
|
||||
rec_buf[1] = 0x03; /* version = 3.1 (TLS) */
|
||||
rec_buf[2] = 0x01;
|
||||
rec_buf[3] = ssl->bm_buf.index >> 8;
|
||||
rec_buf[4] = ssl->bm_buf.index & 0xff;
|
||||
rec_buf[3] = ssl->bm_index >> 8;
|
||||
rec_buf[4] = ssl->bm_index & 0xff;
|
||||
|
||||
DISPLAY_BYTES(ssl, "sending %d bytes", ssl->bm_buf.pre_data,
|
||||
DISPLAY_BYTES(ssl, "sending %d bytes", ssl->bm_all_data,
|
||||
pkt_size, pkt_size);
|
||||
|
||||
ret = SOCKET_WRITE(ssl->client_fd, ssl->bm_buf.pre_data, pkt_size);
|
||||
if ((ret = SOCKET_WRITE(ssl->client_fd,
|
||||
ssl->bm_all_data, pkt_size)) < 0)
|
||||
ret = SSL_ERROR_CONN_LOST;
|
||||
|
||||
SET_SSL_FLAG(SSL_NEED_RECORD); /* reset for next time */
|
||||
ssl->bm_buf.index = 0;
|
||||
ssl->bm_index = 0;
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = SSL_ERROR_CONN_LOST;
|
||||
}
|
||||
else if (protocol != PT_APP_PROTOCOL_DATA)
|
||||
if (protocol != PT_APP_PROTOCOL_DATA)
|
||||
{
|
||||
/* always return SSL_OK during handshake */
|
||||
return ret = SSL_OK;
|
||||
ret = SSL_OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -942,18 +956,16 @@ 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;
|
||||
ssl->bm_buf.index = msg_length;
|
||||
buf_grow(&ssl->bm_buf, msg_length+32);
|
||||
int ret, pad_bytes = 0;
|
||||
ssl->bm_index = msg_length;
|
||||
|
||||
/* if our state is bad, don't bother */
|
||||
if (ssl->hs_status == SSL_ERROR_DEAD)
|
||||
{
|
||||
return SSL_ERROR_CONN_LOST;
|
||||
}
|
||||
|
||||
if (in) /* has the buffer already been initialised? */
|
||||
{
|
||||
memcpy(ssl->bm_buf.data, in, length);
|
||||
memcpy(ssl->bm_data, in, length);
|
||||
}
|
||||
|
||||
if (IS_SET_SSL_FLAG(SSL_TX_ENCRYPTED))
|
||||
@ -966,55 +978,56 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length)
|
||||
|
||||
if (protocol == PT_HANDSHAKE_PROTOCOL)
|
||||
{
|
||||
DISPLAY_STATE(ssl, 1, ssl->bm_buf.data[0], 0);
|
||||
DISPLAY_STATE(ssl, 1, ssl->bm_data[0], 0);
|
||||
|
||||
if (ssl->bm_buf.data[0] != HS_HELLO_REQUEST)
|
||||
if (ssl->bm_data[0] != HS_HELLO_REQUEST)
|
||||
{
|
||||
add_packet(ssl, ssl->bm_buf.data, ssl->bm_buf.index);
|
||||
add_packet(ssl, ssl->bm_data, ssl->bm_index);
|
||||
}
|
||||
}
|
||||
|
||||
/* add the packet digest */
|
||||
msg_length += ssl->cipher_info->digest_size;
|
||||
ssl->bm_buf.index = msg_length;
|
||||
add_hmac_digest(ssl, mode, ssl->bm_buf.data, length,
|
||||
&ssl->bm_buf.data[length]);
|
||||
ssl->bm_index = msg_length;
|
||||
add_hmac_digest(ssl, mode, 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;
|
||||
int pad_bytes = ssl->cipher_info->padding_size - last_blk_size;
|
||||
pad_bytes = ssl->cipher_info->padding_size - last_blk_size;
|
||||
|
||||
/* ensure we always have at least 1 padding byte */
|
||||
if (pad_bytes == 0)
|
||||
{
|
||||
pad_bytes += ssl->cipher_info->padding_size;
|
||||
}
|
||||
|
||||
memset(&ssl->bm_buf.data[msg_length], pad_bytes-1, pad_bytes);
|
||||
memset(&ssl->bm_data[msg_length], pad_bytes-1, pad_bytes);
|
||||
msg_length += pad_bytes;
|
||||
ssl->bm_buf.index = msg_length;
|
||||
ssl->bm_index = msg_length;
|
||||
}
|
||||
|
||||
DISPLAY_BYTES(ssl, "unencrypted write", ssl->bm_buf.data, msg_length);
|
||||
DISPLAY_BYTES(ssl, "unencrypted write", ssl->bm_data, msg_length);
|
||||
increment_write_sequence(ssl);
|
||||
|
||||
/* now encrypt the packet */
|
||||
ssl->cipher_info->encrypt(ssl->encrypt_ctx, ssl->bm_buf.data,
|
||||
ssl->bm_buf.data, msg_length);
|
||||
ssl->cipher_info->encrypt(ssl->encrypt_ctx, ssl->bm_data,
|
||||
ssl->bm_data, msg_length);
|
||||
}
|
||||
else if (protocol == PT_HANDSHAKE_PROTOCOL)
|
||||
{
|
||||
DISPLAY_STATE(ssl, 1, ssl->bm_buf.data[0], 0);
|
||||
DISPLAY_STATE(ssl, 1, ssl->bm_data[0], 0);
|
||||
|
||||
if (ssl->bm_buf.data[0] != HS_HELLO_REQUEST)
|
||||
if (ssl->bm_data[0] != HS_HELLO_REQUEST)
|
||||
{
|
||||
add_packet(ssl, ssl->bm_buf.data, ssl->bm_buf.index);
|
||||
add_packet(ssl, ssl->bm_data, ssl->bm_index);
|
||||
}
|
||||
}
|
||||
|
||||
return send_raw_packet(ssl, protocol);
|
||||
if ((ret = send_raw_packet(ssl, protocol)) <= 0)
|
||||
return ret;
|
||||
|
||||
return length; /* just return what we wanted to send */
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1125,9 +1138,8 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
||||
int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
|
||||
uint8_t *buf;
|
||||
|
||||
buf_grow(&ssl->bm_buf, ssl->need_bytes);
|
||||
buf = ssl->bm_buf.data;
|
||||
read_len = SOCKET_READ(ssl->client_fd, &buf[ssl->bm_buf.index],
|
||||
buf = ssl->bm_data;
|
||||
read_len = SOCKET_READ(ssl->client_fd, &buf[ssl->bm_index],
|
||||
ssl->need_bytes-ssl->got_bytes);
|
||||
|
||||
/* connection has gone, so die */
|
||||
@ -1139,17 +1151,16 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
||||
}
|
||||
|
||||
DISPLAY_BYTES(ssl, "received %d bytes",
|
||||
&ssl->bm_buf.data[ssl->bm_buf.index], read_len, read_len);
|
||||
&ssl->bm_data[ssl->bm_index], read_len, read_len);
|
||||
|
||||
ssl->got_bytes += read_len;
|
||||
ssl->bm_buf.index += read_len;
|
||||
ssl->bm_index += read_len;
|
||||
|
||||
/* haven't quite got what we want, so try again later */
|
||||
if (ssl->got_bytes < ssl->need_bytes)
|
||||
{
|
||||
return SSL_OK;
|
||||
}
|
||||
|
||||
read_len = ssl->got_bytes;
|
||||
ssl->got_bytes = 0;
|
||||
|
||||
if (IS_SET_SSL_FLAG(SSL_NEED_RECORD))
|
||||
@ -1162,14 +1173,21 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
||||
add_packet(ssl, &buf[2], 3);
|
||||
ret = process_sslv23_client_hello(ssl);
|
||||
#else
|
||||
printf("Error: no SSLv23 handshaking allowed\n");
|
||||
TTY_FLUSH();
|
||||
printf("Error: no SSLv23 handshaking allowed\n"); TTY_FLUSH();
|
||||
ret = SSL_ERROR_NOT_SUPPORTED;
|
||||
#endif
|
||||
goto error; /* not an error - just get out of here */
|
||||
}
|
||||
|
||||
ssl->need_bytes = (buf[3] << 8) + buf[4];
|
||||
|
||||
/* do we violate the spec with the message size? */
|
||||
if (ssl->need_bytes > RT_MAX_PLAIN_LENGTH+RT_EXTRA-BM_RECORD_OFFSET)
|
||||
{
|
||||
ret = SSL_ERROR_INVALID_PROT_MSG;
|
||||
goto error;
|
||||
}
|
||||
|
||||
CLR_SSL_FLAG(SSL_NEED_RECORD);
|
||||
memcpy(ssl->record_buf, buf, 3); /* store for hmac */
|
||||
is_record = 1;
|
||||
@ -1182,9 +1200,7 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
||||
}
|
||||
|
||||
if (is_record)
|
||||
{
|
||||
ssl->record_type = buf[0];
|
||||
}
|
||||
else if (IS_SET_SSL_FLAG(SSL_RX_ENCRYPTED))
|
||||
{
|
||||
ssl->cipher_info->decrypt(ssl->decrypt_ctx, buf, buf, read_len);
|
||||
@ -1224,8 +1240,8 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
||||
break;
|
||||
|
||||
case PT_APP_PROTOCOL_DATA:
|
||||
*in_data = ssl->bm_buf.data; /* point to the work buffer */
|
||||
(*in_data)[read_len] = 0; /* null terminate just in case */
|
||||
*in_data = ssl->bm_data; /* point to the work buffer */
|
||||
(*in_data)[read_len] = 0; /* null terminate just in case */
|
||||
ret = read_len;
|
||||
break;
|
||||
|
||||
@ -1242,12 +1258,10 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
||||
}
|
||||
|
||||
error:
|
||||
ssl->bm_buf.index = 0; /* reset to go again */
|
||||
ssl->bm_index = 0; /* reset to go again */
|
||||
|
||||
if (ret < SSL_OK && in_data) /* if all wrong, then clear this buffer ptr */
|
||||
{
|
||||
*in_data = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1277,13 +1291,11 @@ static int do_handshake(SSL *ssl, uint8_t *buf, int read_len)
|
||||
}
|
||||
|
||||
hs_len += SSL_HS_HDR_SIZE; /* adjust for when adding packets */
|
||||
ssl->bm_buf.index = hs_len; /* store the size and check later */
|
||||
ssl->bm_index = hs_len; /* store the size and check later */
|
||||
DISPLAY_STATE(ssl, 0, handshake_type, 0);
|
||||
|
||||
if (handshake_type != HS_CERT_VERIFY && handshake_type != HS_HELLO_REQUEST)
|
||||
{
|
||||
add_packet(ssl, buf, hs_len);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SSL_ENABLE_CLIENT)
|
||||
ret = is_client ?
|
||||
@ -1295,9 +1307,7 @@ static int do_handshake(SSL *ssl, uint8_t *buf, int read_len)
|
||||
|
||||
/* just use recursion to get the rest */
|
||||
if (hs_len < read_len && ret == SSL_OK)
|
||||
{
|
||||
ret = do_handshake(ssl, &buf[hs_len], read_len-hs_len);
|
||||
}
|
||||
|
||||
error:
|
||||
return ret;
|
||||
@ -1322,7 +1332,7 @@ int send_change_cipher_spec(SSL *ssl)
|
||||
*/
|
||||
int send_finished(SSL *ssl)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
|
||||
buf[0] = HS_FINISHED;
|
||||
buf[1] = 0;
|
||||
@ -1365,9 +1375,7 @@ int send_alert(SSL *ssl, int error_code)
|
||||
|
||||
#ifdef CONFIG_SSL_FULL_MODE
|
||||
if (IS_SET_SSL_FLAG(SSL_DISPLAY_STATES))
|
||||
{
|
||||
ssl_display_error(error_code);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (error_code)
|
||||
@ -1424,25 +1432,21 @@ int send_alert(SSL *ssl, int error_code)
|
||||
*/
|
||||
int process_finished(SSL *ssl, int hs_len)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
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);
|
||||
|
||||
PARANOIA_CHECK(ssl->bm_buf.index, SSL_FINISHED_HASH_SIZE+4);
|
||||
PARANOIA_CHECK(ssl->bm_index, SSL_FINISHED_HASH_SIZE+4);
|
||||
|
||||
/* check that we all work before we continue */
|
||||
if (memcmp(ssl->final_finish_mac, &buf[4], SSL_FINISHED_HASH_SIZE))
|
||||
{
|
||||
return SSL_ERROR_FINISHED_INVALID;
|
||||
}
|
||||
|
||||
if ((!is_client && !resume) || (is_client && resume))
|
||||
{
|
||||
if ((ret = send_change_cipher_spec(ssl)) == SSL_OK)
|
||||
{
|
||||
ret = send_finished(ssl);
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't need this stuff anymore */
|
||||
@ -1470,7 +1474,7 @@ error:
|
||||
int send_certificate(SSL *ssl)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
int offset = 7;
|
||||
int chain_length;
|
||||
|
||||
@ -1485,7 +1489,6 @@ int send_certificate(SSL *ssl)
|
||||
buf[offset++] = 0;
|
||||
buf[offset++] = cert->size >> 8; /* cert 1 length */
|
||||
buf[offset++] = cert->size & 0xff;
|
||||
buf_grow(&ssl->bm_buf, offset + cert->size);
|
||||
memcpy(&buf[offset], cert->buf, cert->size);
|
||||
offset += cert->size;
|
||||
i++;
|
||||
@ -1497,7 +1500,7 @@ int send_certificate(SSL *ssl)
|
||||
chain_length += 3;
|
||||
buf[2] = chain_length >> 8; /* handshake length */
|
||||
buf[3] = chain_length & 0xff;
|
||||
ssl->bm_buf.index = offset;
|
||||
ssl->bm_index = offset;
|
||||
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
|
||||
}
|
||||
|
||||
@ -1516,10 +1519,9 @@ SSL_SESS *ssl_session_update(int max_sessions,
|
||||
|
||||
/* no sessions? Then bail */
|
||||
if (max_sessions == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
|
||||
if (session_id)
|
||||
{
|
||||
for (i = 0; i < max_sessions; i++)
|
||||
@ -1543,6 +1545,7 @@ SSL_SESS *ssl_session_update(int max_sessions,
|
||||
memcpy(ssl->master_secret,
|
||||
ssl_sessions[i]->master_secret, SSL_SECRET_SIZE);
|
||||
SET_SSL_FLAG(SSL_SESSION_RESUME);
|
||||
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
|
||||
return ssl_sessions[i]; /* a session was found */
|
||||
}
|
||||
}
|
||||
@ -1558,6 +1561,7 @@ SSL_SESS *ssl_session_update(int max_sessions,
|
||||
ssl_sessions[i] = (SSL_SESS *)calloc(1, sizeof(SSL_SESS));
|
||||
ssl_sessions[i]->conn_time = tm;
|
||||
ssl->session_index = i;
|
||||
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
|
||||
return ssl_sessions[i]; /* return the session object */
|
||||
}
|
||||
else if (ssl_sessions[i]->conn_time <= oldest_sess_time)
|
||||
@ -1573,6 +1577,7 @@ SSL_SESS *ssl_session_update(int max_sessions,
|
||||
oldest_sess->conn_time = tm;
|
||||
memset(oldest_sess->session_id, 0, sizeof(SSL_SESSION_ID_SIZE));
|
||||
memset(oldest_sess->master_secret, 0, sizeof(SSL_SECRET_SIZE));
|
||||
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
|
||||
return oldest_sess;
|
||||
}
|
||||
|
||||
@ -1593,11 +1598,15 @@ static void session_free(SSL_SESS *ssl_sessions[], int sess_index)
|
||||
*/
|
||||
void kill_ssl_session(SSL_SESS **ssl_sessions, SSL *ssl)
|
||||
{
|
||||
SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
|
||||
|
||||
if (ssl->ssl_ctx->num_sessions)
|
||||
{
|
||||
session_free(ssl_sessions, ssl->session_index);
|
||||
ssl->session = NULL;
|
||||
}
|
||||
|
||||
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
|
||||
}
|
||||
#endif /* CONFIG_SSL_SKELETON_MODE */
|
||||
|
||||
@ -1684,10 +1693,10 @@ EXP_FUNC int STDCALL ssl_verify_cert(SSL *ssl)
|
||||
int process_certificate(SSL *ssl, X509_CTX **x509_ctx)
|
||||
{
|
||||
int ret = SSL_OK;
|
||||
int pkt_size = ssl->bm_buf.index;
|
||||
int pkt_size = ssl->bm_index;
|
||||
int cert_size, offset = 5;
|
||||
int total_cert_size = (ssl->bm_buf.data[offset]<<8) +
|
||||
ssl->bm_buf.data[offset+1];
|
||||
int total_cert_size = (ssl->bm_data[offset]<<8) +
|
||||
ssl->bm_data[offset+1];
|
||||
int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
|
||||
X509_CTX **chain = x509_ctx;
|
||||
offset += 2;
|
||||
@ -1697,10 +1706,10 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx)
|
||||
while (offset < total_cert_size)
|
||||
{
|
||||
offset++; /* skip empty char */
|
||||
cert_size = (ssl->bm_buf.data[offset]<<8) + ssl->bm_buf.data[offset+1];
|
||||
cert_size = (ssl->bm_data[offset]<<8) + ssl->bm_data[offset+1];
|
||||
offset += 2;
|
||||
|
||||
if (x509_new(&ssl->bm_buf.data[offset], NULL, chain))
|
||||
if (x509_new(&ssl->bm_data[offset], NULL, chain))
|
||||
{
|
||||
ret = SSL_ERROR_BAD_CERTIFICATE;
|
||||
goto error;
|
||||
@ -1983,6 +1992,15 @@ void DISPLAY_ALERT(SSL *ssl, int alert)
|
||||
|
||||
#endif /* CONFIG_SSL_FULL_MODE */
|
||||
|
||||
/**
|
||||
* Return the version of this library.
|
||||
*/
|
||||
EXP_FUNC const char * STDCALL ssl_version()
|
||||
{
|
||||
static const char * axtls_version = AXTLS_VERSION " " __DATE__;
|
||||
return axtls_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the various language bindings to work regardless of the
|
||||
* configuration - they just return an error statement and a bad return code.
|
||||
|
41
ssl/tls1.h
41
ssl/tls1.h
@ -28,6 +28,31 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "version.h"
|
||||
|
||||
/* Mutexing definitions */
|
||||
#if defined(CONFIG_SSLCTX_MUTEXING)
|
||||
#if defined(WIN32)
|
||||
#define SSL_CTX_MUTEX_TYPE HANDLE
|
||||
#define SSL_CTX_MUTEX_INIT(A) A=CreateMutex(0, FALSE, 0)
|
||||
#define SSL_CTX_MUTEX_DESTROY(A) CloseHandle(A)
|
||||
#define SSL_CTX_LOCK(A) WaitForSingleObject(A, INFINITE)
|
||||
#define SSL_CTX_UNLOCK(A) ReleaseMutex(A)
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#define SSL_CTX_MUTEX_TYPE pthread_mutex_t
|
||||
#define SSL_CTX_MUTEX_INIT(A) pthread_mutex_init(&A, NULL)
|
||||
#define SSL_CTX_MUTEX_DESTROY(A) pthread_mutex_destroy(&A)
|
||||
#define SSL_CTX_LOCK(A) pthread_mutex_lock(&A)
|
||||
#define SSL_CTX_UNLOCK(A) pthread_mutex_unlock(&A)
|
||||
#endif
|
||||
#else /* no mutexing */
|
||||
#define SSL_CTX_MUTEX_INIT(A)
|
||||
#define SSL_CTX_MUTEX_DESTROY(A)
|
||||
#define SSL_CTX_LOCK(A)
|
||||
#define SSL_CTX_UNLOCK(A)
|
||||
#endif
|
||||
|
||||
#define SSL_RANDOM_SIZE 32
|
||||
#define SSL_SECRET_SIZE 48
|
||||
#define SSL_FINISHED_HASH_SIZE 12
|
||||
@ -52,6 +77,9 @@ extern "C" {
|
||||
#define IS_SET_SSL_FLAG(A) (ssl->flag & A)
|
||||
|
||||
#define MAX_KEY_BYTE_SIZE 512 /* for a 4096 bit key */
|
||||
#define RT_MAX_PLAIN_LENGTH 16384
|
||||
#define RT_EXTRA 1024
|
||||
#define BM_RECORD_OFFSET 5
|
||||
|
||||
#ifdef CONFIG_SSL_SKELETON_MODE
|
||||
#define NUM_PROTOCOLS 1
|
||||
@ -138,11 +166,13 @@ struct _SSL
|
||||
uint8_t *key_block;
|
||||
void *encrypt_ctx;
|
||||
void *decrypt_ctx;
|
||||
BUF_MEM bm_buf;
|
||||
uint8_t bm_all_data[RT_MAX_PLAIN_LENGTH+RT_EXTRA];
|
||||
uint8_t *bm_data;
|
||||
int bm_index;
|
||||
struct _SSL *next; /* doubly linked list */
|
||||
struct _SSL *prev;
|
||||
SSL_CERT *certs;
|
||||
struct _SSLCTX *ssl_ctx; /* back reference to a clnt/svr ctx */
|
||||
struct _SSLCTX *ssl_ctx; /* back reference to a clnt/svr ctx */
|
||||
#ifndef CONFIG_SSL_SKELETON_MODE
|
||||
uint16_t session_index;
|
||||
SSL_SESS *session;
|
||||
@ -172,13 +202,16 @@ struct _SSLCTX
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
CA_CERT_CTX *ca_cert_ctx;
|
||||
#endif
|
||||
SSL *sess_head;
|
||||
SSL *sess_tail;
|
||||
SSL *head;
|
||||
SSL *tail;
|
||||
SSL_CERT certs[CONFIG_SSL_MAX_CERTS];
|
||||
#ifndef CONFIG_SSL_SKELETON_MODE
|
||||
uint16_t num_sessions;
|
||||
SSL_SESS **ssl_sessions;
|
||||
#endif
|
||||
#ifdef CONFIG_SSLCTX_MUTEXING
|
||||
SSL_CTX_MUTEX_TYPE mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct _SSLCTX SSLCTX;
|
||||
|
@ -117,7 +117,7 @@ int do_client_connect(SSL *ssl)
|
||||
int ret = SSL_OK;
|
||||
|
||||
send_client_hello(ssl); /* send the client hello */
|
||||
ssl->bm_buf.index = 0;
|
||||
ssl->bm_index = 0;
|
||||
ssl->next_state = HS_SERVER_HELLO;
|
||||
ssl->hs_status = SSL_NOT_OK; /* not connected */
|
||||
|
||||
@ -151,7 +151,7 @@ int do_client_connect(SSL *ssl)
|
||||
*/
|
||||
static int send_client_hello(SSL *ssl)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
time_t tm = time(NULL);
|
||||
uint8_t *tm_ptr = &buf[6]; /* time will go here */
|
||||
int i, offset;
|
||||
@ -186,19 +186,19 @@ static int send_client_hello(SSL *ssl)
|
||||
buf[offset++] = 0;
|
||||
}
|
||||
|
||||
buf[offset++] = 0; /* number of ciphers */
|
||||
buf[offset++] = NUM_PROTOCOLS*2; /* number of ciphers */
|
||||
buf[offset++] = 0; /* number of ciphers */
|
||||
buf[offset++] = NUM_PROTOCOLS*2;/* number of ciphers */
|
||||
|
||||
/* put all our supported protocols in our request */
|
||||
for (i = 0; i < NUM_PROTOCOLS; i++)
|
||||
{
|
||||
buf[offset++] = 0; /* cipher we are using */
|
||||
buf[offset++] = 0; /* cipher we are using */
|
||||
buf[offset++] = ssl_prot_prefs[i];
|
||||
}
|
||||
|
||||
buf[offset++] = 1; /* no compression */
|
||||
buf[offset++] = 1; /* no compression */
|
||||
buf[offset++] = 0;
|
||||
buf[3] = offset - 4; /* handshake size */
|
||||
buf[3] = offset - 4; /* handshake size */
|
||||
|
||||
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
|
||||
}
|
||||
@ -208,8 +208,8 @@ static int send_client_hello(SSL *ssl)
|
||||
*/
|
||||
static int process_server_hello(SSL *ssl)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
int pkt_size = ssl->bm_buf.index;
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
int pkt_size = ssl->bm_index;
|
||||
int offset;
|
||||
int version = (buf[4] << 4) + buf[5];
|
||||
int num_sessions = ssl->ssl_ctx->num_sessions;
|
||||
@ -217,9 +217,7 @@ static int process_server_hello(SSL *ssl)
|
||||
|
||||
/* check that we are talking to a TLSv1 server */
|
||||
if (version != 0x31)
|
||||
{
|
||||
return SSL_ERROR_INVALID_VERSION;
|
||||
}
|
||||
|
||||
/* get the server random value */
|
||||
memcpy(ssl->server_random, &buf[6], SSL_RANDOM_SIZE);
|
||||
@ -260,7 +258,7 @@ static int process_server_hello_done(SSL *ssl)
|
||||
*/
|
||||
static int send_client_key_xchg(SSL *ssl)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
uint8_t premaster_secret[SSL_SECRET_SIZE];
|
||||
int enc_secret_size = -1;
|
||||
|
||||
@ -271,8 +269,13 @@ static int send_client_key_xchg(SSL *ssl)
|
||||
premaster_secret[1] = 0x01;
|
||||
get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]);
|
||||
DISPLAY_RSA(ssl, "send_client_key_xchg", ssl->x509_ctx->rsa_ctx);
|
||||
|
||||
/* rsa_ctx->bi_ctx is not thread-safe */
|
||||
SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
|
||||
enc_secret_size = RSA_encrypt(ssl->x509_ctx->rsa_ctx, premaster_secret,
|
||||
SSL_SECRET_SIZE, &buf[6], 0);
|
||||
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
|
||||
|
||||
buf[2] = (enc_secret_size + 2) >> 8;
|
||||
buf[3] = (enc_secret_size + 2) & 0xff;
|
||||
buf[4] = enc_secret_size >> 8;
|
||||
@ -298,7 +301,7 @@ static int process_cert_req(SSL *ssl)
|
||||
*/
|
||||
static int send_cert_verify(SSL *ssl)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
uint8_t dgst[MD5_SIZE+SHA1_SIZE];
|
||||
RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx;
|
||||
int n, ret;
|
||||
@ -309,7 +312,11 @@ static int send_cert_verify(SSL *ssl)
|
||||
buf[1] = 0;
|
||||
|
||||
finished_digest(ssl, NULL, dgst); /* calculate the digest */
|
||||
|
||||
/* rsa_ctx->bi_ctx is not thread-safe */
|
||||
SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
|
||||
n = RSA_encrypt(rsa_ctx, dgst, sizeof(dgst), &buf[6], 1);
|
||||
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
|
@ -45,10 +45,7 @@ EXP_FUNC SSL * STDCALL ssl_server_new(SSLCTX *ssl_ctx, int client_fd)
|
||||
|
||||
#ifdef CONFIG_SSL_FULL_MODE
|
||||
if (ssl_ctx->chain_length == 0)
|
||||
{
|
||||
printf("Warning - no server certificate defined\n");
|
||||
TTY_FLUSH();
|
||||
}
|
||||
printf("Warning - no server certificate defined\n"); TTY_FLUSH();
|
||||
#endif
|
||||
|
||||
return ssl;
|
||||
@ -67,9 +64,7 @@ int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
|
||||
{
|
||||
case HS_CLIENT_HELLO:
|
||||
if ((ret = process_client_hello(ssl)) == SSL_OK)
|
||||
{
|
||||
ret = send_server_hello_sequence(ssl);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
@ -107,9 +102,9 @@ int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
|
||||
*/
|
||||
static int process_client_hello(SSL *ssl)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
uint8_t *record_buf = ssl->record_buf;
|
||||
int pkt_size = ssl->bm_buf.index;
|
||||
int pkt_size = ssl->bm_index;
|
||||
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;
|
||||
@ -169,7 +164,7 @@ error:
|
||||
*/
|
||||
int process_sslv23_client_hello(SSL *ssl)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
int bytes_needed = ((buf[0] & 0x7f) << 8) + buf[1];
|
||||
int version = (buf[3] << 4) + buf[4];
|
||||
int ret = SSL_OK;
|
||||
@ -291,7 +286,7 @@ static int send_server_hello_sequence(SSL *ssl)
|
||||
*/
|
||||
static int send_server_hello(SSL *ssl)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
int offset = 0;
|
||||
|
||||
buf[0] = HS_SERVER_HELLO;
|
||||
@ -358,8 +353,8 @@ static int send_server_hello_done(SSL *ssl)
|
||||
*/
|
||||
static int process_client_key_xchg(SSL *ssl)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
int pkt_size = ssl->bm_buf.index;
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
int pkt_size = ssl->bm_index;
|
||||
int premaster_size, secret_length = (buf[2] << 8) + buf[3];
|
||||
uint8_t premaster_secret[MAX_KEY_BYTE_SIZE];
|
||||
RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx;
|
||||
@ -370,12 +365,14 @@ static int process_client_key_xchg(SSL *ssl)
|
||||
|
||||
/* is there an extra size field? */
|
||||
if ((secret_length - 2) == rsa_ctx->num_octets)
|
||||
{
|
||||
offset += 2;
|
||||
}
|
||||
|
||||
PARANOIA_CHECK(pkt_size, rsa_ctx->num_octets+offset);
|
||||
|
||||
/* rsa_ctx->bi_ctx is not thread-safe */
|
||||
SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
|
||||
premaster_size = RSA_decrypt(rsa_ctx, &buf[offset], premaster_secret, 1);
|
||||
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
|
||||
|
||||
if (premaster_size != SSL_SECRET_SIZE ||
|
||||
premaster_secret[0] != 0x03 || /* check version is 3.1 (TLS) */
|
||||
@ -420,8 +417,8 @@ static int send_certificate_request(SSL *ssl)
|
||||
*/
|
||||
static int process_cert_verify(SSL *ssl)
|
||||
{
|
||||
uint8_t *buf = ssl->bm_buf.data;
|
||||
int pkt_size = ssl->bm_buf.index;
|
||||
uint8_t *buf = ssl->bm_data;
|
||||
int pkt_size = ssl->bm_index;
|
||||
uint8_t dgst_buf[MAX_KEY_BYTE_SIZE];
|
||||
uint8_t dgst[MD5_SIZE+SHA1_SIZE];
|
||||
X509_CTX *x509_ctx = ssl->x509_ctx;
|
||||
|
Reference in New Issue
Block a user