diff --git a/crypto/aes.c b/crypto/aes.c index 9b07e27ea..d573f7790 100644 --- a/crypto/aes.c +++ b/crypto/aes.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * All rights reserved. * @@ -38,9 +38,6 @@ #include "os_port.h" #include "crypto.h" -/* all commented out in skeleton mode */ -#ifndef CONFIG_SSL_SKELETON_MODE - #define rot1(x) (((x) << 24) | ((x) >> 8)) #define rot2(x) (((x) << 16) | ((x) >> 16)) #define rot3(x) (((x) << 8) | ((x) >> 24)) @@ -453,5 +450,3 @@ static void AES_decrypt(const AES_CTX *ctx, uint32_t *data) data[row-1] = tmp[row-1] ^ *(--k); } } - -#endif diff --git a/crypto/crypto.h b/crypto/crypto.h index fcf32c703..9914afeec 100644 --- a/crypto/crypto.h +++ b/crypto/crypto.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2015, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * 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); void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key, 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 diff --git a/crypto/crypto_misc.c b/crypto/crypto_misc.c index 621b1f6dc..dfd5e7642 100644 --- a/crypto/crypto_misc.c +++ b/crypto/crypto_misc.c @@ -53,7 +53,7 @@ static int rng_fd = -1; static HCRYPTPROV gCryptProv; #endif -#if (!defined(CONFIG_USE_DEV_URANDOM) && !defined(CONFIG_WIN32_USE_CRYPTO_LIB)) +#if (!defined(ESP8266) && !defined(CONFIG_USE_DEV_URANDOM) && !defined(CONFIG_WIN32_USE_CRYPTO_LIB)) /* change to processor registers as appropriate */ #define ENTROPY_POOL_SIZE 32 #define ENTROPY_COUNTER1 ((((uint64_t)tv.tv_sec)<<32) | tv.tv_usec) @@ -109,7 +109,7 @@ int get_file(const char *filename, uint8_t **buf) EXP_FUNC void STDCALL RNG_initialize() { #if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM) - rng_fd = ax_open("/dev/urandom", O_RDONLY); + rng_fd = open("/dev/urandom", O_RDONLY); #elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB) if (!CryptAcquireContext(&gCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) @@ -130,7 +130,7 @@ EXP_FUNC void STDCALL RNG_initialize() /* start of with a stack to copy across */ int i; memcpy(entropy_pool, &i, ENTROPY_POOL_SIZE); - srand((unsigned int)&i); + rand_r((unsigned int *)entropy_pool); #endif } @@ -181,7 +181,7 @@ EXP_FUNC int STDCALL get_random(int num_rand_bytes, uint8_t *rand_data) #else /* nothing else to use, so use a custom RNG */ /* The method we use when we've got nothing better. Use RC4, time and a couple of random seeds to generate a random sequence */ - RC4_CTX rng_ctx; + AES_CTX rng_ctx; struct timeval tv; MD5_CTX rng_digest_ctx; uint8_t digest[MD5_SIZE]; @@ -200,10 +200,10 @@ EXP_FUNC int STDCALL get_random(int num_rand_bytes, uint8_t *rand_data) MD5_Final(digest, &rng_digest_ctx); /* come up with the random sequence */ - RC4_setup(&rng_ctx, digest, MD5_SIZE); /* use as a key */ + AES_set_key(&rng_ctx, digest, (const uint8_t *)ep, AES_MODE_128); /* use as a key */ memcpy(rand_data, entropy_pool, num_rand_bytes < ENTROPY_POOL_SIZE ? num_rand_bytes : ENTROPY_POOL_SIZE); - RC4_crypt(&rng_ctx, rand_data, rand_data, num_rand_bytes); + AES_cbc_encrypt(&rng_ctx, rand_data, rand_data, num_rand_bytes); /* move things along */ for (i = ENTROPY_POOL_SIZE-1; i >= MD5_SIZE ; i--) diff --git a/crypto/hmac.c b/crypto/hmac.c index 24a04d77a..e618ee2eb 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * 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_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); +} + diff --git a/crypto/os_int.h b/crypto/os_int.h index 69e06c50e..a849e5b1a 100644 --- a/crypto/os_int.h +++ b/crypto/os_int.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Cameron Rich + * Copyright (c) 2012-2016, Cameron Rich * * All rights reserved. * @@ -56,7 +56,6 @@ typedef INT64 int64_t; #include #else #include -#include #endif /* Not Solaris */ #endif /* Not Win32 */ diff --git a/ssl/crypto_misc.h b/ssl/crypto_misc.h index 2129422f6..92494b605 100644 --- a/ssl/crypto_misc.h +++ b/ssl/crypto_misc.h @@ -125,7 +125,6 @@ const char * x509_display_error(int error); #define ASN1_EXPLICIT_TAG 0xa0 #define ASN1_V3_DATA 0xa3 -#define SIG_TYPE_MD2 0x02 #define SIG_TYPE_MD5 0x04 #define SIG_TYPE_SHA1 0x05 #define SIG_TYPE_SHA256 0x0b diff --git a/ssl/loader.c b/ssl/loader.c index 34ee3248d..3d0732390 100644 --- a/ssl/loader.c +++ b/ssl/loader.c @@ -82,7 +82,9 @@ EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, #ifdef CONFIG_SSL_HAS_PEM ret = ssl_obj_PEM_load(ssl_ctx, obj_type, ssl_obj, password); #else +#ifdef CONFIG_SSL_FULL_MODE printf("%s", unsupported_str); +#endif ret = SSL_ERROR_NOT_SUPPORTED; #endif } @@ -93,7 +95,9 @@ error: ssl_obj_free(ssl_obj); return ret; #else +#ifdef CONFIG_SSL_FULL_MODE printf("%s", unsupported_str); +#endif return SSL_ERROR_NOT_SUPPORTED; #endif /* CONFIG_SSL_SKELETON_MODE */ } @@ -150,7 +154,9 @@ static int do_obj(SSL_CTX *ssl_ctx, int obj_type, break; #endif default: +#ifdef CONFIG_SSL_FULL_MODE printf("%s", unsupported_str); +#endif ret = SSL_ERROR_NOT_SUPPORTED; break; } @@ -223,7 +229,7 @@ static int pem_decrypt(const char *where, const char *end, if (password == NULL || strlen(password) == 0) { #ifdef CONFIG_SSL_FULL_MODE - printf("Error: Need a password for this PEM file\n"); TTY_FLUSH(); + printf("Error: Need a password for this PEM file\n"); #endif goto error; } @@ -240,7 +246,7 @@ static int pem_decrypt(const char *where, const char *end, else { #ifdef CONFIG_SSL_FULL_MODE - printf("Error: Unsupported password cipher\n"); TTY_FLUSH(); + printf("Error: Unsupported password cipher\n"); #endif goto error; } @@ -475,7 +481,7 @@ error: #ifdef CONFIG_SSL_FULL_MODE if (ret) { - printf("Error: Certificate or key not loaded\n"); TTY_FLUSH(); + printf("Error: Certificate or key not loaded\n"); } #endif diff --git a/ssl/openssl.c b/ssl/openssl.c index 6b5c4d8ee..d0343e568 100644 --- a/ssl/openssl.c +++ b/ssl/openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * All rights reserved. * @@ -49,10 +49,8 @@ static char *key_password = NULL; -void *SSLv23_server_method(void) { return NULL; } void *SSLv3_server_method(void) { return NULL; } void *TLSv1_server_method(void) { return NULL; } -void *SSLv23_client_method(void) { return NULL; } void *SSLv3_client_method(void) { return NULL; } void *TLSv1_client_method(void) { return NULL; } @@ -81,14 +79,13 @@ void SSL_CTX_free(SSL_CTX * ssl_ctx) SSL * SSL_new(SSL_CTX *ssl_ctx) { SSL *ssl; - ssl_func_type_t ssl_func_type; +#ifdef CONFIG_SSL_ENABLE_CLIENT + ssl_func_type_t ssl_func_type = OPENSSL_CTX_ATTR->ssl_func_type; +#endif ssl = ssl_new(ssl_ctx, -1); /* fd is set later */ - ssl_func_type = OPENSSL_CTX_ATTR->ssl_func_type; - #ifdef CONFIG_SSL_ENABLE_CLIENT - if (ssl_func_type == SSLv23_client_method || - ssl_func_type == SSLv3_client_method || + if (ssl_func_type == SSLv3_client_method || ssl_func_type == TLSv1_client_method) { SET_SSL_FLAG(SSL_IS_CLIENT); @@ -231,8 +228,6 @@ void SSL_CTX_set_client_CA_list(SSL_CTX *ssl_ctx, void *file) ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, (const char *)file, NULL); } -void SSLv23_method(void) { } - void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, void *cb) { } void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) diff --git a/ssl/os_port.c b/ssl/os_port.c index b8a2b19a8..060bc073a 100644 --- a/ssl/os_port.c +++ b/ssl/os_port.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2007, Cameron Rich - * + * Copyright (c) 2007-2016, Cameron Rich + * * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -91,9 +91,3 @@ EXP_FUNC int STDCALL getdomainname(char *buf, int buf_size) } #endif -#undef malloc -#undef realloc -#undef calloc - -static const char * out_of_mem_str = "out of memory"; -static const char * file_open_str = "Could not open file \"%s\""; diff --git a/ssl/os_port.h b/ssl/os_port.h index 791c10af2..efda6b5a4 100644 --- a/ssl/os_port.h +++ b/ssl/os_port.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2015, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * All rights reserved. * @@ -62,7 +62,7 @@ extern "C" { #include "util/time.h" #include -// #define alloca(size) __builtin_alloca(size) +#define alloca(size) __builtin_alloca(size) #define TTY_FLUSH() #ifdef putc #undef putc @@ -80,6 +80,7 @@ extern "C" { #define EWOULDBLOCK EAGAIN #define hmac_sha1 ax_hmac_sha1 +#define hmac_sha256 ax_hmac_sha256 #define hmac_md5 ax_hmac_md5 #ifndef be64toh @@ -189,19 +190,6 @@ EXP_FUNC int STDCALL getdomainname(char *buf, int buf_size); #endif /* Not Win32 */ /* some functions to mutate the way these work */ -#define malloc(A) ax_port_malloc(A, __FILE__, __LINE__) -#ifndef realloc -#define realloc(A,B) ax_port_realloc(A,B, __FILE__, __LINE__) -#endif -#define calloc(A,B) ax_port_calloc(A,B, __FILE__, __LINE__) -#define free(x) ax_port_free(x) - -EXP_FUNC void * STDCALL ax_port_malloc(size_t s, const char*, int); -EXP_FUNC void * STDCALL ax_port_realloc(void *y, size_t s, const char*, int); -EXP_FUNC void * STDCALL ax_port_calloc(size_t n, size_t s, const char*, int); -EXP_FUNC void * STDCALL ax_port_free(void*); -EXP_FUNC int STDCALL ax_open(const char *pathname, int flags); - inline uint32_t htonl(uint32_t n){ return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | @@ -211,6 +199,8 @@ inline uint32_t htonl(uint32_t n){ #define ntohl htonl +EXP_FUNC int STDCALL ax_open(const char *pathname, int flags); + #ifdef CONFIG_PLATFORM_LINUX void exit_now(const char *format, ...) __attribute((noreturn)); #else diff --git a/ssl/ssl.h b/ssl/ssl.h index 11debcb94..fb91602f9 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * All rights reserved. * @@ -91,13 +91,16 @@ extern "C" { #define SSL_ERROR_DEAD -2 #define SSL_CLOSE_NOTIFY -3 #define SSL_ERROR_CONN_LOST -256 +#define SSL_ERROR_RECORD_OVERFLOW -257 #define SSL_ERROR_SOCK_SETUP_FAILURE -258 #define SSL_ERROR_INVALID_HANDSHAKE -260 #define SSL_ERROR_INVALID_PROT_MSG -261 #define SSL_ERROR_INVALID_HMAC -262 #define SSL_ERROR_INVALID_VERSION -263 +#define SSL_ERROR_UNSUPPORTED_EXTENSION -264 #define SSL_ERROR_INVALID_SESSION -265 #define SSL_ERROR_NO_CIPHER -266 +#define SSL_ERROR_INVALID_CERT_HASH_ALG -267 #define SSL_ERROR_BAD_CERTIFICATE -268 #define SSL_ERROR_INVALID_KEY -269 #define SSL_ERROR_FINISHED_INVALID -271 @@ -115,19 +118,25 @@ extern "C" { #define SSL_ALERT_CLOSE_NOTIFY 0 #define SSL_ALERT_UNEXPECTED_MESSAGE 10 #define SSL_ALERT_BAD_RECORD_MAC 20 +#define SSL_ALERT_RECORD_OVERFLOW 22 #define SSL_ALERT_HANDSHAKE_FAILURE 40 #define SSL_ALERT_BAD_CERTIFICATE 42 +#define SSL_ALERT_UNSUPPORTED_CERTIFICATE 43 +#define SSL_ALERT_CERTIFICATE_EXPIRED 45 +#define SSL_ALERT_CERTIFICATE_UNKNOWN 46 #define SSL_ALERT_ILLEGAL_PARAMETER 47 +#define SSL_ALERT_UNKNOWN_CA 48 #define SSL_ALERT_DECODE_ERROR 50 #define SSL_ALERT_DECRYPT_ERROR 51 #define SSL_ALERT_INVALID_VERSION 70 #define SSL_ALERT_NO_RENEGOTIATION 100 +#define SSL_ALERT_UNSUPPORTED_EXTENSION 110 /* The ciphers that are supported */ #define SSL_AES128_SHA 0x2f #define SSL_AES256_SHA 0x35 -#define SSL_RC4_128_SHA 0x05 -#define SSL_RC4_128_MD5 0x04 +#define SSL_AES128_SHA256 0x3c +#define SSL_AES256_SHA256 0x3d /* build mode ids' */ #define SSL_BUILD_SKELETON_MODE 0x01 diff --git a/ssl/test/axTLS.ca_x509_sha256.pem b/ssl/test/axTLS.ca_x509_sha256.pem new file mode 100644 index 000000000..f50a47583 --- /dev/null +++ b/ssl/test/axTLS.ca_x509_sha256.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5DCCAcwCCQDGL4Ul/VVK0TANBgkqhkiG9w0BAQsFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA4 +MTUxMDIwNTZaFw0zMDA0MjQxMDIwNTZaMDQxMjAwBgNVBAoTKWF4VExTIFByb2pl +Y3QgRG9kZ3kgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA6d9BDlOJo6fdmSkUdAkMYFnlAK4Q5qwE/vYX8umY0Gz1 +CEIwEyKJq+rCpl2vmlwEETGcphlRsiybOMwVfdRDQv51ZfTJnz1WQZBKdsYb55xy +JWOZFHSpuZa+THW1TOImpvxXoK3OMh/dcuaQG5G7QoWMWRK5aZvpl27rRx033dik +U8lO12oaUtCD3AgNttU7zTLiIQjeIZ9JbES74mx1s4lT22nmXoL5/AdJa3yGjDjG +J1RX8hQ7/pbcC2s4+0XIjGthB2ClJWyvv8bY96POZ+Kc5XLFFjxYoGHtRzQbw2gx +rx7r5/a+d7XgWedMnwf1M1/v9vNA14kgjg2pwuFD4QIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQBW9MtGYroXnu8id8rDvjki8Vk8lDBD0AkOq5QYbXB322Wbg2C+cmHP +zQAJ9YZU/NjnRZiEX1QVoZAXdSXXScbUbSlBQweEvGZmailTGPhJ/wtmNtK6P7ZP +YIJ6XaQdALvteULFMhEQKM9UUkrsbqh41wtoTjOsMlWcRvq9FHLujXxyzjvFPdEI +kz26d7F2yqtgzxW4YLAlclZu6vex/MzNmbjhHenMWp6LNWVWofdIv9jRS1tOSyK+ +hg2sV7CL75nzQ/A22ql8X3SZLAZNR/V7DF+MSBrIcHBzgFZ8QEGlNam29WseuC2C +51+ZXtv0DZ1bPmX+Pz1E06wMGlBTpC4z +-----END CERTIFICATE----- diff --git a/ssl/test/axTLS.x509_1024_sha256.pem b/ssl/test/axTLS.x509_1024_sha256.pem new file mode 100644 index 000000000..aba66956e --- /dev/null +++ b/ssl/test/axTLS.x509_1024_sha256.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWDCCAUACCQCMs+C6AhuzaTANBgkqhkiG9w0BAQsFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA4 +MTUxMDIwNTZaFw0zMDA0MjQxMDIwNTZaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAq9P2gjL8e0OgMrA81JoZeqaZMRmSaTH8xIHf7MkbGYW1ZyBWW+n+017itYgH +pu61CiYcyAfuUACTL2VBhrakCb+j53OF0V+9uEH/BkftUUcu+6ppBB4XI5KbYmTH +JjhBW8N1OHadHLCG4dkQLjnaFgekpM8xZzvd4kkbM4mZqtECAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAG/SBHWYNVf5drxN1aLx9UqTpryjmzDP9/gckKpuNEiDCmp38 +MIKBJYamL9hTwmtf1k4vHB2sxXfv9AVULwMa7+RcgUc3fhTWWoqf1LvYvzMrx9W9 +yU6bfXQh5zb6TOrq/j4fliA2NeDvAzq8tzhBVhiyvy0GhhU1C9eBRVFr4D9l/B2z +odWvCZ4ljLjtmoOhrSSf0OHFuk/eqFJ/SS1jo3ugl7wEmMzphOjmwgK7CLyACBSn +6Bzlh/A16AgqznniMHZ9p99zopMSqPUkCCHPEUiqs8hoy6Pc7O6FrTKfkeiAnY1u +SfKiOf4ODmDcLb5gVtDx+zp59Q/khBX+6IT+BA== +-----END CERTIFICATE----- diff --git a/ssl/test/axTLS.x509_1024_sha384.pem b/ssl/test/axTLS.x509_1024_sha384.pem new file mode 100644 index 000000000..a3adbb044 --- /dev/null +++ b/ssl/test/axTLS.x509_1024_sha384.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWDCCAUACCQCMs+C6AhuzajANBgkqhkiG9w0BAQwFADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA4 +MTUxMDIwNTZaFw0zMDA0MjQxMDIwNTZaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAq9P2gjL8e0OgMrA81JoZeqaZMRmSaTH8xIHf7MkbGYW1ZyBWW+n+017itYgH +pu61CiYcyAfuUACTL2VBhrakCb+j53OF0V+9uEH/BkftUUcu+6ppBB4XI5KbYmTH +JjhBW8N1OHadHLCG4dkQLjnaFgekpM8xZzvd4kkbM4mZqtECAwEAATANBgkqhkiG +9w0BAQwFAAOCAQEA151mqDTC1YPiFq4t7J2UK84jYlGriW0z6KhfmtecLm18Uu07 +vDh+cvWoFRf/fgSlO7c6td0Jb4NGjPBwpV4UmoYND65d1+EkrP+Bl+2DndUi/xka +h4bwfmPrKAjDbUZaNnRi1zQdyPU9tta9b0MamHQVHFOIAyLQXDf1/Tz+wRaFPCIH +PfJEqjD4Nr15O41aMJOaM170rOtbQ9uH4Vlotpt+xJsHufmHFMf1fJtgBXayCzmS +1927ajoKNyDA/QQ+e+60uba6UN6CQnoMzmkMypMxD4JBUt6TEgB46uQ7nkkf3raS +tMAyMnytSc+O7EbhZSWWBSTUkeI+YWjLAtI42Q== +-----END CERTIFICATE----- diff --git a/ssl/test/axTLS.x509_1024_sha512.pem b/ssl/test/axTLS.x509_1024_sha512.pem new file mode 100644 index 000000000..cc369005e --- /dev/null +++ b/ssl/test/axTLS.x509_1024_sha512.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWDCCAUACCQCMs+C6AhuzazANBgkqhkiG9w0BAQ0FADA0MTIwMAYDVQQKEylh +eFRMUyBQcm9qZWN0IERvZGd5IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA4 +MTUxMDIwNTZaFw0zMDA0MjQxMDIwNTZaMCwxFjAUBgNVBAoTDWF4VExTIFByb2pl +Y3QxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAq9P2gjL8e0OgMrA81JoZeqaZMRmSaTH8xIHf7MkbGYW1ZyBWW+n+017itYgH +pu61CiYcyAfuUACTL2VBhrakCb+j53OF0V+9uEH/BkftUUcu+6ppBB4XI5KbYmTH +JjhBW8N1OHadHLCG4dkQLjnaFgekpM8xZzvd4kkbM4mZqtECAwEAATANBgkqhkiG +9w0BAQ0FAAOCAQEA51hsTX6DlE9WnI0XaNfx0hfWG74maMZK+GG1LQKi6JlaA6U4 +7aLpoluw4G7oZz39ROuNbOvTMrhN4kOXG16Zk2HGufzAQgqoegIsgI2BiaOtmBnn +vOchhiZ16JLmKB6ZMlESFubV1Ynyr6QacTLOipLGICGn3N65BrbwfaXD/nbJQd+a +YOwkJ9OHxbK9zqLMBG3kK/QKXqID3dI21+MDCGSSBAh/tVPhwTMcTzViF5vT4Mpq +81+Z9eg3vI++rOiBppdjRKH4CFcO74rEA6j9fNFHI0PiS142TtT4vXLf+D4PQLkI +tBuSq99ensRy5IvjYXpcx7/jixVd3MmwWrolbg== +-----END CERTIFICATE----- diff --git a/ssl/tls1.c b/ssl/tls1.c index 1a13fc579..c40a0691f 100644 --- a/ssl/tls1.c +++ b/ssl/tls1.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * All rights reserved. * @@ -54,55 +54,37 @@ static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt, void static int send_raw_packet(SSL *ssl, uint8_t protocol); static void certificate_free(SSL* ssl); static int increase_bm_data_size(SSL *ssl, size_t size); +static int check_certificate_chain(SSL *ssl); /** * The server will pick the cipher based on the order that the order that the * ciphers are listed. This order is defined at compile time. */ -#ifdef CONFIG_SSL_SKELETON_MODE -const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] = -{ SSL_RC4_128_SHA }; -#else +#ifndef CONFIG_SSL_SKELETON_MODE static void session_free(SSL_SESSION *ssl_sessions[], int sess_index); - -const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] = -#ifdef CONFIG_SSL_PROT_LOW /* low security, fast speed */ -{ SSL_AES128_SHA, SSL_AES256_SHA}; -#elif CONFIG_SSL_PROT_MEDIUM /* medium security, medium speed */ -{ SSL_AES128_SHA, SSL_AES256_SHA}; -#else /* CONFIG_SSL_PROT_HIGH */ /* high security, low speed */ -{ SSL_AES256_SHA, SSL_AES128_SHA}; #endif -#endif /* CONFIG_SSL_SKELETON_MODE */ + +const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] = +#ifdef CONFIG_SSL_PROT_LOW /* low security, fast speed */ +{ SSL_AES128_SHA, SSL_AES128_SHA256, SSL_AES256_SHA, SSL_AES256_SHA256 }; +#elif CONFIG_SSL_PROT_MEDIUM /* medium security, medium speed */ +{ SSL_AES128_SHA256, SSL_AES256_SHA256, SSL_AES256_SHA, SSL_AES128_SHA }; +#else /* CONFIG_SSL_PROT_HIGH */ /* high security, low speed */ +{ SSL_AES256_SHA256, SSL_AES128_SHA256, SSL_AES256_SHA, SSL_AES128_SHA }; +#endif /** * The cipher map containing all the essentials for each cipher. */ -#ifdef CONFIG_SSL_SKELETON_MODE -static const cipher_info_t cipher_info[NUM_PROTOCOLS] = -{ - { /* RC4-SHA */ - SSL_RC4_128_SHA, /* RC4-SHA */ - 16, /* key size */ - 0, /* iv size */ - 2*(SHA1_SIZE+16), /* key block size */ - 0, /* no padding */ - SHA1_SIZE, /* digest size */ - hmac_sha1, /* hmac algorithm */ - (crypt_func)RC4_crypt, /* encrypt */ - (crypt_func)RC4_crypt /* decrypt */ - }, -}; -#else static const cipher_info_t cipher_info[NUM_PROTOCOLS] = { { /* AES128-SHA */ SSL_AES128_SHA, /* AES128-SHA */ 16, /* key size */ 16, /* iv size */ - 2*(SHA1_SIZE+16+16), /* key block size */ 16, /* block padding size */ SHA1_SIZE, /* digest size */ + 2*(SHA1_SIZE+16+16), /* key block size */ hmac_sha1, /* hmac algorithm */ (crypt_func)AES_cbc_encrypt, /* encrypt */ (crypt_func)AES_cbc_decrypt /* decrypt */ @@ -110,18 +92,40 @@ static const cipher_info_t cipher_info[NUM_PROTOCOLS] = { /* AES256-SHA */ SSL_AES256_SHA, /* AES256-SHA */ 32, /* key size */ - 16, /* iv size */ - 2*(SHA1_SIZE+32+16), /* key block size */ + 16, /* iv size */ 16, /* block padding size */ SHA1_SIZE, /* digest size */ + 2*(SHA1_SIZE+32+16), /* key block size */ hmac_sha1, /* hmac algorithm */ (crypt_func)AES_cbc_encrypt, /* encrypt */ (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 */ } }; -#endif -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); static const cipher_info_t *get_cipher_info(uint8_t cipher); static void increment_read_sequence(SSL *ssl); @@ -226,7 +230,7 @@ EXP_FUNC void STDCALL ssl_free(SSL *ssl) /* only notify if we weren't notified first */ /* spec says we must notify when we are dying */ if (!IS_SET_SSL_FLAG(SSL_SENT_CLOSE_NOTIFY)) - send_alert(ssl, SSL_ALERT_CLOSE_NOTIFY); + send_alert(ssl, SSL_ALERT_CLOSE_NOTIFY); ssl_ctx = ssl->ssl_ctx; @@ -247,7 +251,9 @@ EXP_FUNC void STDCALL ssl_free(SSL *ssl) /* may already be free - but be sure */ free(ssl->encrypt_ctx); + ssl->encrypt_ctx = NULL; free(ssl->decrypt_ctx); + ssl->decrypt_ctx = NULL; disposable_free(ssl); certificate_free(ssl); free(ssl->bm_all_data); @@ -343,6 +349,26 @@ int add_cert(SSL_CTX *ssl_ctx, const uint8_t *buf, int len) ssl_cert = &ssl_ctx->certs[i]; ssl_cert->size = len; ssl_cert->buf = (uint8_t *)malloc(len); + + switch (cert->sig_type) + { + case SIG_TYPE_SHA1: + ssl_cert->hash_alg = SIG_ALG_SHA1; + break; + + case SIG_TYPE_SHA256: + ssl_cert->hash_alg = SIG_ALG_SHA256; + break; + + case SIG_TYPE_SHA384: + ssl_cert->hash_alg = SIG_ALG_SHA384; + break; + + case SIG_TYPE_SHA512: + ssl_cert->hash_alg = SIG_ALG_SHA512; + break; + } + memcpy(ssl_cert->buf, buf, len); ssl_ctx->chain_length++; len -= offset; @@ -634,36 +660,19 @@ static void increment_write_sequence(SSL *ssl) 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 size_t prefix_size = 8 + SSL_RECORD_SIZE; - bool hmac_inplace = (uint32_t)buf - (uint32_t)ssl->bm_data >= prefix_size; - 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); - } + int hmac_len = buf_len + 8 + SSL_RECORD_SIZE; + uint8_t *t_buf = (uint8_t *)alloca(buf_len+100); - 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); 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, - (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ) ? - ssl->server_mac : ssl->client_mac, + ssl->cipher_info->hmac(t_buf, hmac_len, + (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ) ? + ssl->server_mac : ssl->client_mac, ssl->cipher_info->digest_size, hmac_buf); - if (hmac_inplace) { - memcpy(t_buf, tmp, prefix_size); - } - else { - free(t_buf); - } #if 0 print_blob("record", hmac_header, SSL_RECORD_SIZE); print_blob("buf", buf, buf_len); @@ -686,7 +695,7 @@ static void add_hmac_digest(SSL *ssl, int mode, uint8_t *hmac_header, print_blob("client mac", 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 } @@ -695,39 +704,27 @@ 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) { - uint8_t hmac_buf[SHA1_SIZE]; + uint8_t hmac_buf[SHA256_SIZE]; // size of largest digest int hmac_offset; - if (ssl->cipher_info->padding_size) - { - int last_blk_size = buf[read_len-1], i; - hmac_offset = read_len-last_blk_size-ssl->cipher_info->digest_size-1; + int last_blk_size = buf[read_len-1], i; + hmac_offset = read_len-last_blk_size-ssl->cipher_info->digest_size-1; - /* guard against a timing attack - make sure we do the digest */ - if (hmac_offset < 0) - { - hmac_offset = 0; - } - else - { - /* already looked at last byte */ - for (i = 1; i < last_blk_size; i++) - { - if (buf[read_len-i] != last_blk_size) - { - hmac_offset = 0; - break; - } - } - } + /* guard against a timing attack - make sure we do the digest */ + if (hmac_offset < 0) + { + hmac_offset = 0; } - else /* stream cipher */ + else { - hmac_offset = read_len - ssl->cipher_info->digest_size; - - if (hmac_offset < 0) + /* already looked at last byte */ + for (i = 1; i < last_blk_size; i++) { - hmac_offset = 0; + if (buf[read_len-i] != last_blk_size) + { + hmac_offset = 0; + break; + } } } @@ -750,8 +747,19 @@ 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) { - MD5_Update(&ssl->dc->md5_ctx, pkt, len); - SHA1_Update(&ssl->dc->sha1_ctx, pkt, len); + // TLS1.2+ + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2 || ssl->version == 0) + { + SHA256_Update(&ssl->dc->sha256_ctx, pkt, len); + } + + if (ssl->version < SSL_PROTOCOL_VERSION_TLS1_2 || + ssl->next_state == HS_SERVER_HELLO || + ssl->next_state == 0) + { + MD5_Update(&ssl->dc->md5_ctx, pkt, len); + SHA1_Update(&ssl->dc->sha1_ctx, pkt, len); + } } /** @@ -760,7 +768,7 @@ void add_packet(SSL *ssl, const uint8_t *pkt, int len) static void p_hash_md5(const uint8_t *sec, int sec_len, uint8_t *seed, int seed_len, uint8_t *out, int olen) { - uint8_t a1[128]; + uint8_t a1[MD5_SIZE+77]; /* A(1) */ hmac_md5(seed, seed_len, sec, sec_len, a1); @@ -788,7 +796,7 @@ static void p_hash_md5(const uint8_t *sec, int sec_len, static void p_hash_sha1(const uint8_t *sec, int sec_len, uint8_t *seed, int seed_len, uint8_t *out, int olen) { - uint8_t a1[128]; + uint8_t a1[SHA1_SIZE+77]; /* A(1) */ hmac_sha1(seed, seed_len, sec, sec_len, a1); @@ -810,27 +818,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[SHA256_SIZE+77]; + + /* 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. */ -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) { - 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 */ + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + p_hash_sha256(sec, sec_len, seed, seed_len, out, olen); + } + 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; - S1 = sec; - S2 = &sec[len]; - len += (sec_len & 1); /* add for odd, make longer */ + len = sec_len/2; + S1 = sec; + S2 = &sec[len]; + len += (sec_len & 1); /* add for odd, make longer */ - p_hash_md5(S1, len, seed, seed_len, xbuf, olen); - p_hash_sha1(S2, len, seed, seed_len, ybuf, olen); + p_hash_md5(S1, len, seed, seed_len, xbuf, olen); + p_hash_sha1(S2, len, seed, seed_len, ybuf, olen); - for (i = 0; i < olen; i++) - out[i] = xbuf[i] ^ ybuf[i]; + for (i = 0; i < olen; i++) + out[i] = xbuf[i] ^ ybuf[i]; + } } /** @@ -839,37 +883,44 @@ 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) { - uint8_t buf[128]; /* needs to be > 13+32+32 in size */ + uint8_t buf[77]; +//print_blob("premaster secret", premaster_secret, 48); strcpy((char *)buf, "master secret"); memcpy(&buf[13], ssl->dc->client_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); +#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. */ -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 buf[128]; + uint8_t buf[77]; strcpy((char *)buf, "key expansion"); memcpy(&buf[13], server_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); } /** * Calculate the digest used in the finished message. This function also * doubles up as a certificate verify function. */ -void finished_digest(SSL *ssl, const char *label, uint8_t *digest) +int finished_digest(SSL *ssl, const char *label, uint8_t *digest) { - uint8_t mac_buf[128]; + uint8_t mac_buf[SHA1_SIZE+MD5_SIZE+15]; uint8_t *q = mac_buf; - MD5_CTX md5_ctx = ssl->dc->md5_ctx; - SHA1_CTX sha1_ctx = ssl->dc->sha1_ctx; + int dgst_len; if (label) { @@ -877,28 +928,43 @@ void finished_digest(SSL *ssl, const char *label, uint8_t *digest) q += strlen(label); } - MD5_Final(q, &md5_ctx); - q += MD5_SIZE; - - SHA1_Final(q, &sha1_ctx); - q += SHA1_SIZE; + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + SHA256_CTX sha256_ctx = ssl->dc->sha256_ctx; // interim copy + SHA256_Final(q, &sha256_ctx); + q += SHA256_SIZE; + dgst_len = (int)(q-mac_buf); + } + else // TLS1.0/1.1 + { + 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; + dgst_len = (int)(q-mac_buf); + } if (label) { - prf(ssl->dc->master_secret, SSL_SECRET_SIZE, mac_buf, (int)(q-mac_buf), - digest, SSL_FINISHED_HASH_SIZE); + prf(ssl, ssl->dc->master_secret, SSL_SECRET_SIZE, + mac_buf, dgst_len, digest, SSL_FINISHED_HASH_SIZE); } else /* for use in a certificate verify */ { - memcpy(digest, mac_buf, MD5_SIZE + SHA1_SIZE); + memcpy(digest, mac_buf, dgst_len); } #if 0 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, dgst_len); print_blob("finished digest", digest, SSL_FINISHED_HASH_SIZE); #endif + + return dgst_len; } /** @@ -908,8 +974,8 @@ static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt, void { switch (ssl->cipher) { -#ifndef CONFIG_SSL_SKELETON_MODE case SSL_AES128_SHA: + case SSL_AES128_SHA256: { AES_CTX *aes_ctx; if (cached) @@ -927,6 +993,7 @@ static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt, void } case SSL_AES256_SHA: + case SSL_AES256_SHA256: { AES_CTX *aes_ctx; if (cached) @@ -944,19 +1011,6 @@ static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt, void return (void *)aes_ctx; } - case SSL_RC4_128_MD5: -#endif - case SSL_RC4_128_SHA: - { - RC4_CTX* rc4_ctx; - if (cached) - rc4_ctx = (RC4_CTX*) cached; - else - rc4_ctx = (RC4_CTX*) malloc(sizeof(RC4_CTX)); - - RC4_setup(rc4_ctx, key, 16); - return (void *)rc4_ctx; - } } return NULL; /* its all gone wrong */ @@ -1036,6 +1090,9 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length) if (ssl->hs_status == SSL_ERROR_DEAD) return SSL_ERROR_CONN_LOST; + if (IS_SET_SSL_FLAG(SSL_SENT_CLOSE_NOTIFY)) + return SSL_CLOSE_NOTIFY; + if (in) /* has the buffer already been initialised? */ { memcpy(ssl->bm_data, in, length); @@ -1071,8 +1128,7 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length) &ssl->bm_data[msg_length]); msg_length += ssl->cipher_info->digest_size; - /* add padding? */ - if (ssl->cipher_info->padding_size) + /* add padding */ { int last_blk_size = msg_length%ssl->cipher_info->padding_size; int pad_bytes = ssl->cipher_info->padding_size - last_blk_size; @@ -1089,8 +1145,7 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length) increment_write_sequence(ssl); /* add the explicit IV for TLS1.1 */ - if (ssl->version >= SSL_PROTOCOL_VERSION1_1 && - ssl->cipher_info->iv_size) + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_1) { uint8_t iv_size = ssl->cipher_info->iv_size; uint8_t *t_buf = malloc(msg_length + iv_size); @@ -1140,21 +1195,18 @@ static int set_key_block(SSL *ssl, int is_write) return -1; /* only do once in a handshake */ - if (ssl->dc->key_block == NULL) + if (!ssl->dc->key_block_generated) { - ssl->dc->key_block = (uint8_t *)malloc(ciph_info->key_block_size); - -#if 0 - print_blob("client", ssl->dc->client_random, 32); - print_blob("server", ssl->dc->server_random, 32); - print_blob("master", ssl->dc->master_secret, SSL_SECRET_SIZE); -#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, ciph_info->key_block_size); #if 0 + print_blob("master", ssl->dc->master_secret, SSL_SECRET_SIZE); print_blob("keyblock", ssl->dc->key_block, ciph_info->key_block_size); + print_blob("client random", ssl->dc->client_random, 32); + print_blob("server random", ssl->dc->server_random, 32); #endif + ssl->dc->key_block_generated = 1; } q = ssl->dc->key_block; @@ -1177,14 +1229,15 @@ static int set_key_block(SSL *ssl, int is_write) memcpy(server_key, q, ciph_info->key_size); q += ciph_info->key_size; -#ifndef CONFIG_SSL_SKELETON_MODE - 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(server_iv, q, ciph_info->iv_size); - q += ciph_info->iv_size; - } + memcpy(client_iv, q, ciph_info->iv_size); + q += ciph_info->iv_size; + memcpy(server_iv, q, ciph_info->iv_size); + q += ciph_info->iv_size; +#if 0 + print_blob("client key", client_key, ciph_info->key_size); + print_blob("server key", server_key, ciph_info->key_size); + print_blob("client iv", client_iv, ciph_info->iv_size); + print_blob("server iv", server_iv, ciph_info->iv_size); #endif // free(is_write ? ssl->encrypt_ctx : ssl->decrypt_ctx); @@ -1222,6 +1275,9 @@ int basic_read(SSL *ssl, uint8_t **in_data) int read_len, is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT); uint8_t *buf = ssl->bm_data; + if (IS_SET_SSL_FLAG(SSL_SENT_CLOSE_NOTIFY)) + return SSL_CLOSE_NOTIFY; + read_len = SOCKET_READ(ssl->client_fd, &buf[ssl->bm_read_index], ssl->need_bytes-ssl->got_bytes); @@ -1261,31 +1317,10 @@ int basic_read(SSL *ssl, uint8_t **in_data) /* check for sslv2 "client hello" */ if (buf[0] & 0x80 && buf[2] == 1) { -#ifdef CONFIG_SSL_ENABLE_V23_HANDSHAKE - uint8_t version = (buf[3] << 4) + buf[4]; - DISPLAY_BYTES(ssl, "ssl2 record", buf, 5); - - /* should be v3.1 (TLSv1) or better */ - ssl->version = ssl->client_version = version; - - if (version > SSL_PROTOCOL_VERSION_MAX) - { - /* use client's version */ - ssl->version = SSL_PROTOCOL_VERSION_MAX; - } - else if (version < SSL_PROTOCOL_MIN_VERSION) - { - ret = SSL_ERROR_INVALID_VERSION; - ssl_display_error(ret); - return ret; - } - - add_packet(ssl, &buf[2], 3); - ret = process_sslv23_client_hello(ssl); -#else - printf("Error: no SSLv23 handshaking allowed\n"); TTY_FLUSH(); - ret = SSL_ERROR_NOT_SUPPORTED; +#ifdef CONFIG_SSL_FULL_MODE + printf("Error: no SSLv23 handshaking allowed\n"); #endif + ret = SSL_ERROR_NOT_SUPPORTED; goto error; /* not an error - just get out of here */ } @@ -1294,8 +1329,7 @@ int basic_read(SSL *ssl, uint8_t **in_data) /* do we violate the spec with the message size? */ if (ssl->need_bytes > RT_MAX_PLAIN_LENGTH+RT_EXTRA-BM_RECORD_OFFSET) { - printf("ssl->need_bytes=%d violates spec\r\n", ssl->need_bytes, RT_MAX_PLAIN_LENGTH+RT_EXTRA-BM_RECORD_OFFSET); - ret = SSL_ERROR_INVALID_PROT_MSG; + ret = SSL_ERROR_RECORD_OVERFLOW; goto error; } @@ -1326,8 +1360,7 @@ int basic_read(SSL *ssl, uint8_t **in_data) { ssl->cipher_info->decrypt(ssl->decrypt_ctx, buf, buf, read_len); - if (ssl->version >= SSL_PROTOCOL_VERSION1_1 && - ssl->cipher_info->iv_size) + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_1) { buf += ssl->cipher_info->iv_size; read_len -= ssl->cipher_info->iv_size; @@ -1394,7 +1427,7 @@ int basic_read(SSL *ssl, uint8_t **in_data) case PT_ALERT_PROTOCOL: /* return the alert # with alert bit set */ - if(buf[0] == SSL_ALERT_TYPE_WARNING && + if (buf[0] == SSL_ALERT_TYPE_WARNING && buf[1] == SSL_ALERT_CLOSE_NOTIFY) { ret = SSL_CLOSE_NOTIFY; @@ -1516,7 +1549,7 @@ int send_change_cipher_spec(SSL *ssl) */ int send_finished(SSL *ssl) { - uint8_t buf[SSL_FINISHED_HASH_SIZE+4] = { + uint8_t buf[SHA1_SIZE+MD5_SIZE+15+4] = { HS_FINISHED, 0, 0, SSL_FINISHED_HASH_SIZE }; /* now add the finished digest mac (12 bytes) */ @@ -1547,7 +1580,7 @@ int send_alert(SSL *ssl, int error_code) int is_warning = 0; uint8_t buf[2]; - /* Don't bother we're already dead */ + /* Don't bother, we're already dead */ if (ssl->hs_status == SSL_ERROR_DEAD) { return SSL_ERROR_CONN_LOST; @@ -1569,38 +1602,60 @@ int send_alert(SSL *ssl, int error_code) is_warning = 1; break; - case SSL_ERROR_INVALID_HANDSHAKE: - case SSL_ERROR_INVALID_PROT_MSG: + case SSL_ERROR_NO_CIPHER: alert_num = SSL_ALERT_HANDSHAKE_FAILURE; break; case SSL_ERROR_INVALID_HMAC: - case SSL_ERROR_FINISHED_INVALID: alert_num = SSL_ALERT_BAD_RECORD_MAC; break; + case SSL_ERROR_FINISHED_INVALID: + case SSL_ERROR_INVALID_KEY: + alert_num = SSL_ALERT_DECRYPT_ERROR; + break; + case SSL_ERROR_INVALID_VERSION: alert_num = SSL_ALERT_INVALID_VERSION; break; case SSL_ERROR_INVALID_SESSION: - case SSL_ERROR_NO_CIPHER: - case SSL_ERROR_INVALID_KEY: alert_num = SSL_ALERT_ILLEGAL_PARAMETER; break; - case SSL_ERROR_BAD_CERTIFICATE: - alert_num = SSL_ALERT_BAD_CERTIFICATE; - break; - case SSL_ERROR_NO_CLIENT_RENOG: alert_num = SSL_ALERT_NO_RENEGOTIATION; break; + case SSL_ERROR_RECORD_OVERFLOW: + alert_num = SSL_ALERT_RECORD_OVERFLOW; + break; + + case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED): + case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID): + alert_num = SSL_ALERT_CERTIFICATE_EXPIRED; + break; + + case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT): + alert_num = SSL_ALERT_UNKNOWN_CA; + break; + + case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST): + case SSL_ERROR_INVALID_CERT_HASH_ALG: + alert_num = SSL_ALERT_UNSUPPORTED_CERTIFICATE; + break; + + case SSL_ERROR_BAD_CERTIFICATE: + case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE): + alert_num = SSL_ALERT_BAD_CERTIFICATE; + break; + + case SSL_ERROR_INVALID_HANDSHAKE: + case SSL_ERROR_INVALID_PROT_MSG: default: - /* a catch-all for any badly verified certificates */ + /* a catch-all for anything bad */ alert_num = (error_code <= SSL_X509_OFFSET) ? - SSL_ALERT_BAD_CERTIFICATE : SSL_ALERT_UNEXPECTED_MESSAGE; + SSL_ALERT_CERTIFICATE_UNKNOWN: SSL_ALERT_UNEXPECTED_MESSAGE; break; } @@ -1645,6 +1700,7 @@ error: */ int send_certificate(SSL *ssl) { + int ret = SSL_OK; int i = 0; uint8_t *buf = ssl->bm_data; int offset = 7; @@ -1654,6 +1710,14 @@ int send_certificate(SSL *ssl) buf[1] = 0; buf[4] = 0; + /* spec says we must check if the hash/sig algorithm is OK */ + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2 && + ((ret = check_certificate_chain(ssl)) != SSL_OK)) + { + ret = SSL_ERROR_INVALID_CERT_HASH_ALG; + goto error; + } + while (i < ssl->ssl_ctx->chain_length) { SSL_CERT *cert = &ssl->ssl_ctx->certs[i]; @@ -1672,7 +1736,10 @@ int send_certificate(SSL *ssl) buf[2] = chain_length >> 8; /* handshake length */ buf[3] = chain_length & 0xff; ssl->bm_index = offset; - return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); + ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); + +error: + return ret; } /** @@ -1684,6 +1751,7 @@ void disposable_new(SSL *ssl) if (ssl->dc == NULL) { ssl->dc = (DISPOSABLE_CTX *)calloc(1, sizeof(DISPOSABLE_CTX)); + SHA256_Init(&ssl->dc->sha256_ctx); MD5_Init(&ssl->dc->md5_ctx); SHA1_Init(&ssl->dc->sha1_ctx); } @@ -1696,7 +1764,6 @@ void disposable_free(SSL *ssl) { if (ssl->dc) { - free(ssl->dc->key_block); memset(ssl->dc, 0, sizeof(DISPOSABLE_CTX)); free(ssl->dc); ssl->dc = NULL; @@ -1891,6 +1958,43 @@ EXP_FUNC int STDCALL ssl_get_config(int offset) } } +/** + * Check the certificate chain to see if the certs are supported + */ +static int check_certificate_chain(SSL *ssl) +{ + int i = 0; + int ret = SSL_OK; + + while (i < ssl->ssl_ctx->chain_length) + { + int j = 0; + uint8_t found = 0; + SSL_CERT *cert = &ssl->ssl_ctx->certs[i]; + + while (j < ssl->num_sig_algs) + { + if (ssl->sig_algs[j++] == cert->hash_alg) + { + found = 1; + break; + } + } + + if (!found) + { + + ret = SSL_ERROR_INVALID_CERT_HASH_ALG; + goto error; + } + + i++; + } + +error: + return ret; +} + #ifdef CONFIG_SSL_CERT_VERIFICATION /** * Authenticate a received certificate. @@ -1918,32 +2022,97 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx) int ret = SSL_OK; uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index]; int pkt_size = ssl->bm_index; - int cert_size, offset = 5; - int total_cert_size = (buf[offset]<<8) + buf[offset+1]; + int cert_size, offset = 5, offset_start; + int total_cert_len = (buf[offset]<<8) + buf[offset+1]; int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT); - X509_CTX **chain = x509_ctx; + X509_CTX *chain = 0; + X509_CTX **certs = 0; + int *cert_used = 0; + int num_certs = 0; + int i = 0; offset += 2; - PARANOIA_CHECK(total_cert_size, offset); + PARANOIA_CHECK(pkt_size, total_cert_len + offset); - while (offset < total_cert_size) + // record the start point for the second pass + offset_start = offset; + + // first pass - count the certificates + while (offset < total_cert_len) + { + offset++; /* skip empty char */ + cert_size = (buf[offset]<<8) + buf[offset+1]; + offset += 2; + offset += cert_size; + num_certs++; + } + + PARANOIA_CHECK(pkt_size, offset); + + certs = (X509_CTX**) calloc(num_certs, sizeof(void*)); + cert_used = (int*) calloc(num_certs, sizeof(int)); + num_certs = 0; + + // restore the offset from the saved value + offset = offset_start; + + // second pass - load the certificates + while (offset < total_cert_len) { offset++; /* skip empty char */ cert_size = (buf[offset]<<8) + buf[offset+1]; offset += 2; - if (x509_new(&buf[offset], NULL, chain)) + if (x509_new(&buf[offset], NULL, certs+num_certs)) { ret = SSL_ERROR_BAD_CERTIFICATE; goto error; } - chain = &((*chain)->next); + num_certs++; offset += cert_size; } PARANOIA_CHECK(pkt_size, offset); + // third pass - link certs together, assume server cert is the first + *x509_ctx = certs[0]; + chain = certs[0]; + cert_used[0] = 1; + + // repeat until the end of the chain is found + while (1) + { + // look for CA cert + for( i = 1; i < num_certs; i++ ) + { + if (certs[i] == chain) + continue; + if (cert_used[i]) + continue; // don't allow loops + + if (asn1_compare_dn(chain->ca_cert_dn, certs[i]->cert_dn) == 0) + { + // CA cert found, add it to the chain + cert_used[i] = 1; + chain->next = certs[i]; + chain = certs[i]; + break; + } + } + + // no CA cert found, reached the end of the chain + if (i >= num_certs) + break; + } + + // clean up any certs that aren't part of the chain + for (i = 1; i < num_certs; i++) + { + if (cert_used[i] == 0) + x509_free(certs[i]); + } + /* if we are client we can do the verify now or later */ if (is_client && !IS_SET_SSL_FLAG(SSL_SERVER_VERIFY_LATER)) { @@ -1953,6 +2122,13 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx) ssl->next_state = is_client ? HS_SERVER_HELLO_DONE : HS_CLIENT_KEY_XCHG; ssl->dc->bm_proc_index += offset; error: + // clean up arrays + if (certs) + free(certs); + + if (cert_used) + free(cert_used); + return ret; } @@ -2043,7 +2219,6 @@ void DISPLAY_STATE(SSL *ssl, int is_send, uint8_t state, int not_ok) } printf("%s\n", str); - TTY_FLUSH(); } /** @@ -2105,6 +2280,10 @@ EXP_FUNC void STDCALL ssl_display_error(int error_code) printf("connection dead"); break; + case SSL_ERROR_RECORD_OVERFLOW: + printf("record overflow"); + break; + case SSL_ERROR_INVALID_HANDSHAKE: printf("invalid handshake"); break; @@ -2129,6 +2308,10 @@ EXP_FUNC void STDCALL ssl_display_error(int error_code) printf("no cipher"); break; + case SSL_ERROR_INVALID_CERT_HASH_ALG: + printf("invalid cert hash algorithm"); + break; + case SSL_ERROR_CONN_LOST: printf("connection lost"); break; @@ -2163,9 +2346,12 @@ EXP_FUNC void STDCALL ssl_display_error(int error_code) } printf("\n"); - TTY_FLUSH(); } +/** + * Debugging routine to display alerts. + */ + /** * Debugging routine to display alerts. */ @@ -2182,14 +2368,6 @@ void DISPLAY_ALERT(SSL *ssl, int alert) printf("close notify"); break; - case SSL_ALERT_INVALID_VERSION: - printf("invalid version"); - break; - - case SSL_ALERT_BAD_CERTIFICATE: - printf("bad certificate"); - break; - case SSL_ALERT_UNEXPECTED_MESSAGE: printf("unexpected message"); break; @@ -2198,14 +2376,38 @@ void DISPLAY_ALERT(SSL *ssl, int alert) printf("bad record mac"); break; + case SSL_ERROR_RECORD_OVERFLOW: + printf("record overlow"); + break; + case SSL_ALERT_HANDSHAKE_FAILURE: printf("handshake failure"); break; + case SSL_ALERT_BAD_CERTIFICATE: + printf("bad certificate"); + break; + + case SSL_ALERT_UNSUPPORTED_CERTIFICATE: + printf("unsupported certificate"); + break; + + case SSL_ALERT_CERTIFICATE_EXPIRED: + printf("certificate expired"); + break; + + case SSL_ALERT_CERTIFICATE_UNKNOWN: + printf("certificate unknown"); + break; + case SSL_ALERT_ILLEGAL_PARAMETER: printf("illegal parameter"); break; + case SSL_ALERT_UNKNOWN_CA: + printf("unknown ca"); + break; + case SSL_ALERT_DECODE_ERROR: printf("decode error"); break; @@ -2214,6 +2416,10 @@ void DISPLAY_ALERT(SSL *ssl, int alert) printf("decrypt error"); break; + case SSL_ALERT_INVALID_VERSION: + printf("invalid version"); + break; + case SSL_ALERT_NO_RENEGOTIATION: printf("no renegotiation"); break; @@ -2224,7 +2430,6 @@ void DISPLAY_ALERT(SSL *ssl, int alert) } printf("\n"); - TTY_FLUSH(); } #endif /* CONFIG_SSL_FULL_MODE */ diff --git a/ssl/tls1.h b/ssl/tls1.h index abbc93393..152c69ec3 100644 --- a/ssl/tls1.h +++ b/ssl/tls1.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2014, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * All rights reserved. * @@ -43,13 +43,14 @@ extern "C" { #include "version.h" #include "config.h" #include "os_int.h" +#include "os_port.h" #include "crypto.h" #include "crypto_misc.h" #define SSL_PROTOCOL_MIN_VERSION 0x31 /* TLS v1.0 */ -#define SSL_PROTOCOL_MINOR_VERSION 0x02 /* TLS v1.1 */ -#define SSL_PROTOCOL_VERSION_MAX 0x32 /* TLS v1.1 */ -#define SSL_PROTOCOL_VERSION1_1 0x32 /* TLS v1.1 */ +#define SSL_PROTOCOL_VERSION_MAX 0x33 /* TLS v1.3 */ +#define SSL_PROTOCOL_VERSION_TLS1_1 0x32 /* TLS v1.1 */ +#define SSL_PROTOCOL_VERSION_TLS1_2 0x33 /* TLS v1.2 */ #define SSL_RANDOM_SIZE 32 #define SSL_SECRET_SIZE 48 #define SSL_FINISHED_HASH_SIZE 12 @@ -79,11 +80,15 @@ extern "C" { #define RT_EXTRA 1024 #define BM_RECORD_OFFSET 5 -#ifdef CONFIG_SSL_SKELETON_MODE -#define NUM_PROTOCOLS 1 -#else -#define NUM_PROTOCOLS 2 -#endif +#define NUM_PROTOCOLS 4 + +#define MAX_SIG_ALGORITHMS 4 +#define SIG_ALG_EXTENSION 0x0d +#define SIG_ALG_SHA1 2 +#define SIG_ALG_SHA256 4 +#define SIG_ALG_SHA384 5 +#define SIG_ALG_SHA512 6 +#define SIG_ALG_RSA 1 #define PARANOIA_CHECK(A, B) if (A < B) { \ ret = SSL_ERROR_INVALID_HANDSHAKE; goto error; } @@ -117,9 +122,9 @@ typedef struct uint8_t cipher; uint8_t key_size; uint8_t iv_size; - uint8_t key_block_size; uint8_t padding_size; uint8_t digest_size; + uint8_t key_block_size; hmac_func hmac; crypt_func encrypt; crypt_func decrypt; @@ -144,18 +149,21 @@ typedef struct { uint8_t *buf; int size; + uint8_t hash_alg; } SSL_CERT; typedef struct { MD5_CTX md5_ctx; SHA1_CTX sha1_ctx; - uint8_t final_finish_mac[SSL_FINISHED_HASH_SIZE]; - uint8_t *key_block; - uint8_t master_secret[SSL_SECRET_SIZE]; + SHA256_CTX sha256_ctx; uint8_t client_random[SSL_RANDOM_SIZE]; /* client'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; + uint8_t key_block_generated; } DISPOSABLE_CTX; struct _SSL @@ -180,6 +188,8 @@ struct _SSL uint16_t bm_index; uint16_t bm_read_index; size_t max_plain_length; + uint8_t sig_algs[MAX_SIG_ALGORITHMS]; + uint8_t num_sig_algs; struct _SSL *next; /* doubly linked list */ struct _SSL *prev; struct _SSL_CTX *ssl_ctx; /* back reference to a clnt/svr ctx */ @@ -192,10 +202,10 @@ struct _SSL bool can_free_certificates; #endif uint8_t session_id[SSL_SESSION_ID_SIZE]; - uint8_t client_mac[SHA1_SIZE]; /* for HMAC verification */ - uint8_t server_mac[SHA1_SIZE]; /* for HMAC verification */ - uint8_t read_sequence[8]; /* 64 bit sequence number */ - uint8_t write_sequence[8]; /* 64 bit sequence number */ + uint8_t client_mac[SHA256_SIZE]; /* for HMAC verification */ + uint8_t server_mac[SHA256_SIZE]; /* for HMAC verification */ + uint8_t read_sequence[8]; /* 64 bit sequence number */ + uint8_t write_sequence[8]; /* 64 bit sequence number */ uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */ char *host_name; /* Needed for the SNI support */ }; @@ -246,7 +256,7 @@ int send_finished(SSL *ssl); int send_certificate(SSL *ssl); int basic_read(SSL *ssl, uint8_t **in_data); int send_change_cipher_spec(SSL *ssl); -void finished_digest(SSL *ssl, const char *label, uint8_t *digest); +int finished_digest(SSL *ssl, const char *label, uint8_t *digest); void generate_master_secret(SSL *ssl, const uint8_t *premaster_secret); void add_packet(SSL *ssl, const uint8_t *pkt, int len); int add_cert(SSL_CTX *ssl_ctx, const uint8_t *buf, int len); diff --git a/ssl/tls1_clnt.c b/ssl/tls1_clnt.c index 77f11780d..43efca305 100644 --- a/ssl/tls1_clnt.c +++ b/ssl/tls1_clnt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * All rights reserved. * @@ -37,6 +37,23 @@ #ifdef CONFIG_SSL_ENABLE_CLIENT /* all commented out if no client */ +/* support sha512/384/256/1 RSA */ +static const uint8_t g_sig_alg[] = { + 0x00, 0x0e, + 0x00, SIG_ALG_EXTENSION, + 0x00, 0x0a, 0x00, 0x08, + SIG_ALG_SHA512, SIG_ALG_RSA, + SIG_ALG_SHA384, SIG_ALG_RSA, + SIG_ALG_SHA256, SIG_ALG_RSA, + SIG_ALG_SHA1, SIG_ALG_RSA +}; + +static const uint8_t g_asn1_sha256[] = +{ + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 +}; + static int send_client_hello(SSL *ssl); static int process_server_hello(SSL *ssl); static int process_server_hello_done(SSL *ssl); @@ -227,27 +244,14 @@ static int send_client_hello(SSL *ssl) buf[offset++] = 1; /* no compression */ buf[offset++] = 0; - if (ssl->host_name != NULL) { - unsigned int host_len = strlen(ssl->host_name); - - buf[offset++] = 0; - 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; + /* send the signature algorithm extension for TLS 1.2+ */ + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) + { + memcpy(&buf[offset], g_sig_alg, sizeof(g_sig_alg)); + offset += sizeof(g_sig_alg); } buf[3] = offset - 4; /* handshake size */ - return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); } @@ -306,15 +310,18 @@ static int process_server_hello(SSL *ssl) ssl->sess_id_size = 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->next_state = IS_SET_SSL_FLAG(SSL_SESSION_RESUME) ? HS_FINISHED : HS_CERTIFICATE; - offset++; // skip the compr + offset += 2; // ignore compression PARANOIA_CHECK(pkt_size, offset); - ssl->dc->bm_proc_index = offset+1; + ssl->dc->bm_proc_index = offset+1; + PARANOIA_CHECK(pkt_size, offset); + + // no extensions error: return ret; } @@ -340,8 +347,10 @@ static int send_client_key_xchg(SSL *ssl) buf[0] = HS_CLIENT_KEY_XCHG; buf[1] = 0; - premaster_secret[0] = 0x03; /* encode the version number */ - premaster_secret[1] = SSL_PROTOCOL_MINOR_VERSION; /* must be TLS 1.1 */ + // spec says client must use the what is initially negotiated - + // 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) return SSL_NOT_OK; @@ -369,14 +378,47 @@ static int process_cert_req(SSL *ssl) { uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index]; int ret = SSL_OK; - int offset = (buf[2] << 4) + buf[3]; + int cert_req_size = (buf[2]<<8) + buf[3]; + int offset = 4; int pkt_size = ssl->bm_index; + uint8_t cert_type_len, sig_alg_len; + + PARANOIA_CHECK(pkt_size, offset + cert_req_size); + ssl->dc->bm_proc_index = cert_req_size; /* don't do any processing - we will send back an RSA certificate anyway */ ssl->next_state = HS_SERVER_HELLO_DONE; SET_SSL_FLAG(SSL_HAS_CERT_REQ); - ssl->dc->bm_proc_index += offset; - PARANOIA_CHECK(pkt_size, offset); + + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + // supported certificate types + cert_type_len = buf[offset++]; + PARANOIA_CHECK(pkt_size, offset + cert_type_len); + offset += cert_type_len; + + // supported signature algorithms + sig_alg_len = buf[offset++] << 8; + sig_alg_len += buf[offset++]; + PARANOIA_CHECK(pkt_size, offset + sig_alg_len); + + while (sig_alg_len > 0) + { + uint8_t hash_alg = buf[offset++]; + uint8_t sig_alg = buf[offset++]; + sig_alg_len -= 2; + + if (sig_alg == SIG_ALG_RSA && + (hash_alg == SIG_ALG_SHA1 || + hash_alg == SIG_ALG_SHA256 || + hash_alg == SIG_ALG_SHA384 || + hash_alg == SIG_ALG_SHA512)) + { + ssl->sig_algs[ssl->num_sig_algs++] = hash_alg; + } + } + } + error: return ret; } @@ -387,9 +429,11 @@ error: static int send_cert_verify(SSL *ssl) { uint8_t *buf = ssl->bm_data; - uint8_t dgst[MD5_SIZE+SHA1_SIZE]; + uint8_t dgst[SHA1_SIZE+MD5_SIZE+15]; RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx; int n = 0, ret; + int offset = 0; + int dgst_len; if (rsa_ctx == NULL) return SSL_OK; @@ -399,13 +443,26 @@ static int send_cert_verify(SSL *ssl) buf[0] = HS_CERT_VERIFY; buf[1] = 0; - finished_digest(ssl, NULL, dgst); /* calculate the digest */ + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + buf[4] = SIG_ALG_SHA256; + buf[5] = SIG_ALG_RSA; + offset = 6; + memcpy(dgst, g_asn1_sha256, sizeof(g_asn1_sha256)); + dgst_len = finished_digest(ssl, NULL, &dgst[sizeof(g_asn1_sha256)]) + + sizeof(g_asn1_sha256); + } + else + { + offset = 4; + dgst_len = finished_digest(ssl, NULL, dgst); + } /* rsa_ctx->bi_ctx is not thread-safe */ if (rsa_ctx) { SSL_CTX_LOCK(ssl->ssl_ctx->mutex); - n = RSA_encrypt(rsa_ctx, dgst, sizeof(dgst), &buf[6], 1); + n = RSA_encrypt(rsa_ctx, dgst, dgst_len, &buf[offset + 2], 1); SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); if (n == 0) @@ -415,12 +472,19 @@ static int send_cert_verify(SSL *ssl) } } - buf[4] = n >> 8; /* add the RSA size (not officially documented) */ - buf[5] = n & 0xff; + buf[offset] = n >> 8; /* add the RSA size */ + buf[offset+1] = n & 0xff; n += 2; + + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + n += 2; // sig/alg + offset -= 2; + } + buf[2] = n >> 8; buf[3] = n & 0xff; - ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, n+4); + ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, n + offset); error: return ret; diff --git a/ssl/tls1_svr.c b/ssl/tls1_svr.c index b4b0f648d..48c664ef9 100644 --- a/ssl/tls1_svr.c +++ b/ssl/tls1_svr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * All rights reserved. * @@ -35,6 +35,11 @@ #include "ssl.h" static const uint8_t g_hello_done[] = { HS_SERVER_HELLO_DONE, 0, 0, 0 }; +static const uint8_t g_asn1_sha256[] = +{ + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 +}; static int process_client_hello(SSL *ssl); static int send_server_hello_sequence(SSL *ssl); @@ -154,7 +159,7 @@ static int process_client_hello(SSL *ssl) cs_len = (buf[offset]<<8) + buf[offset+1]; offset += 3; /* add 1 due to all cipher suites being 8 bit */ - PARANOIA_CHECK(pkt_size, offset); + PARANOIA_CHECK(pkt_size, offset + cs_len); /* work out what cipher suite we are going to use - client defines the preference */ @@ -165,89 +170,75 @@ static int process_client_hello(SSL *ssl) if (ssl_prot_prefs[j] == buf[offset+i]) /* got a match? */ { ssl->cipher = ssl_prot_prefs[j]; - goto do_state; + goto do_compression; } } } /* ouch! protocol is not supported */ - ret = SSL_ERROR_NO_CIPHER; + return SSL_ERROR_NO_CIPHER; -do_state: -error: - return ret; -} - -#ifdef CONFIG_SSL_ENABLE_V23_HANDSHAKE -/* - * Some browsers use a hybrid SSLv2 "client hello" - */ -int process_sslv23_client_hello(SSL *ssl) -{ - uint8_t *buf = ssl->bm_data; - int bytes_needed = ((buf[0] & 0x7f) << 8) + buf[1]; - int ret = SSL_OK; - - /* we have already read 3 extra bytes so far */ - int read_len = SOCKET_READ(ssl->client_fd, buf, bytes_needed-3); - int cs_len = buf[1]; - int id_len = buf[3]; - int ch_len = buf[5]; - int i, j, offset = 8; /* start at first cipher */ - int random_offset = 0; - - DISPLAY_BYTES(ssl, "received %d bytes", buf, read_len, read_len); - - /* connection has gone, so die */ - if (read_len < 0) - { - return SSL_ERROR_CONN_LOST; - } - - add_packet(ssl, buf, read_len); - - /* now work out what cipher suite we are going to use */ - for (j = 0; j < NUM_PROTOCOLS; j++) - { - for (i = 0; i < cs_len; i += 3) - { - if (ssl_prot_prefs[j] == buf[offset+i]) - { - ssl->cipher = ssl_prot_prefs[j]; - goto server_hello; - } - } - } - - /* ouch! protocol is not supported */ - ret = SSL_ERROR_NO_CIPHER; - goto error; - -server_hello: - /* get the session id */ - offset += cs_len - 2; /* we've gone 2 bytes past the end */ -#ifndef CONFIG_SSL_SKELETON_MODE - ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions, - ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL); -#endif - - /* get the client random data */ + /* completely ignore compression */ +do_compression: + offset += cs_len; + id_len = buf[offset++]; offset += id_len; + PARANOIA_CHECK(pkt_size, offset + id_len); - /* random can be anywhere between 16 and 32 bytes long - so it is padded - * with 0's to the left */ - if (ch_len == 0x10) + if (offset == pkt_size) { - random_offset += 0x10; + /* no extensions */ + goto error; } - memcpy(&ssl->dc->client_random[random_offset], &buf[offset], ch_len); - ret = send_server_hello_sequence(ssl); + /* extension size */ + id_len = buf[offset++] << 8; + id_len += buf[offset++]; + PARANOIA_CHECK(pkt_size, offset + id_len); + + // Check for extensions from the client - only the signature algorithm + // is supported + while (offset < pkt_size) + { + int ext = buf[offset++] << 8; + ext += buf[offset++]; + int ext_len = buf[offset++] << 8; + ext_len += buf[offset++]; + PARANOIA_CHECK(pkt_size, offset + ext_len); + + if (ext == SIG_ALG_EXTENSION) + { + while (ext_len > 0) + { + uint8_t hash_alg = buf[offset++]; + uint8_t sig_alg = buf[offset++]; + ext_len -= 2; + + if (sig_alg == SIG_ALG_RSA && + (hash_alg == SIG_ALG_SHA1 || + hash_alg == SIG_ALG_SHA256 || + hash_alg == SIG_ALG_SHA384 || + hash_alg == SIG_ALG_SHA512)) + { + ssl->sig_algs[ssl->num_sig_algs++] = hash_alg; + } + } + } + else + { + offset += ext_len; + } + } + + /* default is RSA/SHA1 */ + if (ssl->num_sig_algs == 0) + { + ssl->sig_algs[ssl->num_sig_algs++] = SIG_ALG_SHA1; + } error: return ret; } -#endif /* * Send the entire server hello sequence @@ -350,7 +341,7 @@ static int send_server_hello(SSL *ssl) buf[offset++] = 0; /* cipher we are using */ buf[offset++] = ssl->cipher; - buf[offset++] = 0; /* no compression */ + buf[offset++] = 0; /* no compression and no extensions supported */ buf[3] = offset - 4; /* handshake size */ return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); } @@ -409,10 +400,6 @@ static int process_client_key_xchg(SSL *ssl) /* and continue - will die eventually when checking the mac */ } -#if 0 - print_blob("pre-master", premaster_secret, SSL_SECRET_SIZE); -#endif - generate_master_secret(ssl, premaster_secret); #ifdef CONFIG_SSL_CERT_VERIFICATION @@ -428,15 +415,34 @@ error: } #ifdef CONFIG_SSL_CERT_VERIFICATION -static const uint8_t g_cert_request[] = { HS_CERT_REQ, 0, 0, 4, 1, 0, 0, 0 }; +static const uint8_t g_cert_request[] = { HS_CERT_REQ, 0, + 0, 0x0e, + 1, 1, // rsa sign + 0x00, 0x08, + SIG_ALG_SHA256, SIG_ALG_RSA, + SIG_ALG_SHA512, SIG_ALG_RSA, + SIG_ALG_SHA384, SIG_ALG_RSA, + SIG_ALG_SHA1, SIG_ALG_RSA, + 0, 0 +}; + +static const uint8_t g_cert_request_v1[] = { HS_CERT_REQ, 0, 0, 4, 1, 0, 0, 0 }; /* * Send the certificate request message. */ static int send_certificate_request(SSL *ssl) { - return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, g_cert_request, sizeof(g_cert_request)); + } + else + { + return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, + g_cert_request_v1, sizeof(g_cert_request_v1)); + } } /* @@ -448,29 +454,65 @@ static int process_cert_verify(SSL *ssl) uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index]; int pkt_size = ssl->bm_index; uint8_t dgst_buf[MAX_KEY_BYTE_SIZE]; - uint8_t dgst[MD5_SIZE+SHA1_SIZE]; + uint8_t dgst[MD5_SIZE + SHA1_SIZE]; X509_CTX *x509_ctx = ssl->x509_ctx; int ret = SSL_OK; + int offset = 6; + int rsa_len; int n; - PARANOIA_CHECK(pkt_size, x509_ctx->rsa_ctx->num_octets+6); DISPLAY_RSA(ssl, x509_ctx->rsa_ctx); + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ + { + // TODO: should really need to be able to handle other algorihms. An + // assumption is made on RSA/SHA256 and appears to be OK. + //uint8_t hash_alg = buf[4]; + //uint8_t sig_alg = buf[5]; + offset = 8; + rsa_len = (buf[6] << 8) + buf[7]; + } + else + { + rsa_len = (buf[4] << 8) + buf[5]; + } + + PARANOIA_CHECK(pkt_size, offset + rsa_len); + /* rsa_ctx->bi_ctx is not thread-safe */ SSL_CTX_LOCK(ssl->ssl_ctx->mutex); - n = RSA_decrypt(x509_ctx->rsa_ctx, &buf[6], dgst_buf, sizeof(dgst_buf), 0); + n = RSA_decrypt(x509_ctx->rsa_ctx, &buf[offset], dgst_buf, + sizeof(dgst_buf), 0); SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); - if (n != SHA1_SIZE + MD5_SIZE) + if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+ { - ret = SSL_ERROR_INVALID_KEY; - goto end_cert_vfy; - } + if (memcmp(dgst_buf, g_asn1_sha256, sizeof(g_asn1_sha256))) + { + ret = SSL_ERROR_INVALID_KEY; + goto error; + } - finished_digest(ssl, NULL, dgst); /* calculate the digest */ - if (memcmp(dgst_buf, dgst, MD5_SIZE + SHA1_SIZE)) + finished_digest(ssl, NULL, dgst); /* calculate the digest */ + if (memcmp(&dgst_buf[sizeof(g_asn1_sha256)], dgst, SHA256_SIZE)) + { + ret = SSL_ERROR_INVALID_KEY; + goto error; + } + } + else // TLS1.0/1.1 { - ret = SSL_ERROR_INVALID_KEY; + if (n != SHA1_SIZE + MD5_SIZE) + { + ret = SSL_ERROR_INVALID_KEY; + goto end_cert_vfy; + } + + finished_digest(ssl, NULL, dgst); /* calculate the digest */ + if (memcmp(dgst_buf, dgst, MD5_SIZE + SHA1_SIZE)) + { + ret = SSL_ERROR_INVALID_KEY; + } } end_cert_vfy: diff --git a/ssl/x509.c b/ssl/x509.c index da0706288..862d897fb 100644 --- a/ssl/x509.c +++ b/ssl/x509.c @@ -74,7 +74,9 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx) int begin_tbs, end_tbs; int ret = X509_NOT_OK, offset = 0, cert_size = 0; X509_CTX *x509_ctx; +#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */ BI_CTX *bi_ctx; +#endif *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX)); x509_ctx = *ctx; @@ -117,7 +119,6 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx) goto end_cert; } - bi_ctx = x509_ctx->rsa_ctx->bi_ctx; x509_ctx->fingerprint = malloc(SHA1_SIZE); SHA1_CTX sha_fp_ctx; @@ -126,6 +127,8 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx) SHA1_Final(x509_ctx->fingerprint, &sha_fp_ctx); #ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */ + bi_ctx = x509_ctx->rsa_ctx->bi_ctx; + /* use the appropriate signature algorithm */ switch (x509_ctx->sig_type) { @@ -524,9 +527,6 @@ void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx) printf("Sig Type:\t\t\t"); switch (cert->sig_type) { - case SIG_TYPE_MD2: - printf("MD2\n"); - break; case SIG_TYPE_MD5: printf("MD5\n"); break; diff --git a/tools/make_certs.sh b/tools/make_certs.sh index d521e9218..dc577e74e 100644 --- a/tools/make_certs.sh +++ b/tools/make_certs.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2007, Cameron Rich +# Copyright (c) 2007-2016, Cameron Rich # # All rights reserved. # @@ -56,7 +56,7 @@ prompt = no [ req_distinguished_name ] O = $PROJECT_NAME - CN = 127.0.0.1 + CN = localhost EOF cat > device_cert.conf << EOF @@ -69,21 +69,16 @@ prompt = no EOF # private key generation -openssl genrsa -out axTLS.ca_key.pem 1024 -openssl genrsa -out axTLS.key_512.pem 512 +openssl genrsa -out axTLS.ca_key.pem 2048 openssl genrsa -out axTLS.key_1024.pem 1024 -openssl genrsa -out axTLS.key_1042.pem 1042 openssl genrsa -out axTLS.key_2048.pem 2048 openssl genrsa -out axTLS.key_4096.pem 4096 openssl genrsa -out axTLS.device_key.pem 1024 -openssl genrsa -aes128 -passout pass:abcd -out axTLS.key_aes128.pem 512 -openssl genrsa -aes256 -passout pass:abcd -out axTLS.key_aes256.pem 512 - +openssl genrsa -aes128 -passout pass:abcd -out axTLS.key_aes128.pem 1024 +openssl genrsa -aes256 -passout pass:abcd -out axTLS.key_aes256.pem 1024 # convert private keys into DER format -openssl rsa -in axTLS.key_512.pem -out axTLS.key_512 -outform DER openssl rsa -in axTLS.key_1024.pem -out axTLS.key_1024 -outform DER -openssl rsa -in axTLS.key_1042.pem -out axTLS.key_1042 -outform DER openssl rsa -in axTLS.key_2048.pem -out axTLS.key_2048 -outform DER openssl rsa -in axTLS.key_4096.pem -out axTLS.key_4096 -outform DER openssl rsa -in axTLS.device_key.pem -out axTLS.device_key -outform DER @@ -91,12 +86,8 @@ openssl rsa -in axTLS.device_key.pem -out axTLS.device_key -outform DER # cert requests openssl req -out axTLS.ca_x509.req -key axTLS.ca_key.pem -new \ -config ./ca_cert.conf -openssl req -out axTLS.x509_512.req -key axTLS.key_512.pem -new \ - -config ./certs.conf openssl req -out axTLS.x509_1024.req -key axTLS.key_1024.pem -new \ -config ./certs.conf -openssl req -out axTLS.x509_1042.req -key axTLS.key_1042.pem -new \ - -config ./certs.conf openssl req -out axTLS.x509_2048.req -key axTLS.key_2048.pem -new \ -config ./certs.conf openssl req -out axTLS.x509_4096.req -key axTLS.key_4096.pem -new \ @@ -110,25 +101,32 @@ openssl req -out axTLS.x509_aes256.req -key axTLS.key_aes256.pem \ # generate the actual certs. openssl x509 -req -in axTLS.ca_x509.req -out axTLS.ca_x509.pem \ - -sha1 -days 5000 -signkey axTLS.ca_key.pem -openssl x509 -req -in axTLS.x509_512.req -out axTLS.x509_512.pem \ - -sha1 -CAcreateserial -days 5000 \ - -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem + -sha1 -days 5000 -signkey axTLS.ca_key.pem \ + -CAkey axTLS.ca_key.pem +openssl x509 -req -in axTLS.ca_x509.req -out axTLS.ca_x509_sha256.pem \ + -sha256 -days 5000 -signkey axTLS.ca_key.pem \ + -CAkey axTLS.ca_key.pem openssl x509 -req -in axTLS.x509_1024.req -out axTLS.x509_1024.pem \ -sha1 -CAcreateserial -days 5000 \ -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem -openssl x509 -req -in axTLS.x509_1042.req -out axTLS.x509_1042.pem \ +openssl x509 -req -in axTLS.x509_1024.req -out axTLS.x509_1024_sha256.pem \ + -sha256 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509_sha256.pem -CAkey axTLS.ca_key.pem +openssl x509 -req -in axTLS.x509_1024.req -out axTLS.x509_1024_sha384.pem \ + -sha384 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509_sha256.pem -CAkey axTLS.ca_key.pem +openssl x509 -req -in axTLS.x509_1024.req -out axTLS.x509_1024_sha512.pem \ + -sha512 -CAcreateserial -days 5000 \ + -CA axTLS.ca_x509_sha256.pem -CAkey axTLS.ca_key.pem +openssl x509 -req -in axTLS.x509_2048.req -out axTLS.x509_2048.pem \ -sha1 -CAcreateserial -days 5000 \ -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem -openssl x509 -req -in axTLS.x509_2048.req -out axTLS.x509_2048.pem \ - -md5 -CAcreateserial -days 5000 \ - -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem openssl x509 -req -in axTLS.x509_4096.req -out axTLS.x509_4096.pem \ - -md5 -CAcreateserial -days 5000 \ + -sha1 -CAcreateserial -days 5000 \ -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem openssl x509 -req -in axTLS.x509_device.req -out axTLS.x509_device.pem \ -sha1 -CAcreateserial -days 5000 \ - -CA axTLS.x509_512.pem -CAkey axTLS.key_512.pem + -CA axTLS.x509_1024.pem -CAkey axTLS.key_1024.pem openssl x509 -req -in axTLS.x509_aes128.req \ -out axTLS.x509_aes128.pem \ -sha1 -CAcreateserial -days 5000 \ @@ -141,35 +139,33 @@ openssl x509 -req -in axTLS.x509_aes256.req \ # note: must be root to do this DATE_NOW=`date` if date -s "Jan 1 2025"; then -openssl x509 -req -in axTLS.x509_512.req -out axTLS.x509_bad_before.pem \ +openssl x509 -req -in axTLS.x509_1024.req -out axTLS.x509_bad_before.pem \ -sha1 -CAcreateserial -days 365 \ -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem date -s "$DATE_NOW" touch axTLS.x509_bad_before.pem fi -openssl x509 -req -in axTLS.x509_512.req -out axTLS.x509_bad_after.pem \ +openssl x509 -req -in axTLS.x509_1024.req -out axTLS.x509_bad_after.pem \ -sha1 -CAcreateserial -days -365 \ -CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem # some cleanup rm axTLS*.req -rm axTLS.srl +rm *.srl rm *.conf # need this for the client tests openssl x509 -in axTLS.ca_x509.pem -outform DER -out axTLS.ca_x509.cer -openssl x509 -in axTLS.x509_512.pem -outform DER -out axTLS.x509_512.cer openssl x509 -in axTLS.x509_1024.pem -outform DER -out axTLS.x509_1024.cer -openssl x509 -in axTLS.x509_1042.pem -outform DER -out axTLS.x509_1042.cer openssl x509 -in axTLS.x509_2048.pem -outform DER -out axTLS.x509_2048.cer openssl x509 -in axTLS.x509_4096.pem -outform DER -out axTLS.x509_4096.cer openssl x509 -in axTLS.x509_device.pem -outform DER -out axTLS.x509_device.cer # generate pkcs8 files (use RC4-128 for encryption) -openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8 -openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -outform DER -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8 -openssl pkcs8 -in axTLS.key_512.pem -nocrypt -topk8 -out axTLS.unencrypted_pem.p8 -openssl pkcs8 -in axTLS.key_512.pem -nocrypt -topk8 -outform DER -out axTLS.unencrypted.p8 +openssl pkcs8 -in axTLS.key_1024.pem -passout pass:abcd -topk8 -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8 +openssl pkcs8 -in axTLS.key_1024.pem -passout pass:abcd -topk8 -outform DER -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8 +openssl pkcs8 -in axTLS.key_1024.pem -nocrypt -topk8 -out axTLS.unencrypted_pem.p8 +openssl pkcs8 -in axTLS.key_1024.pem -nocrypt -topk8 -outform DER -out axTLS.unencrypted.p8 # generate pkcs12 files (use RC4-128 for encryption) openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem -certfile axTLS.ca_x509.pem -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128 -name "p12_with_CA" -out axTLS.withCA.p12 -password pass:abcd