diff --git a/ChangeLog b/ChangeLog index 505d90a3c..1a94b45fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,8 @@ Features * Support for session tickets (RFC 5077) Changes + * Ability to enable / disable SSL v3 / TLS 1.0 / TLS 1.1 / TLS 1.2 + individually * Introduced separate SSL Ciphersuites module that is based on Cipher and MD information * Internals for SSL module adapted to have separate IV pointer that is diff --git a/include/polarssl/config.h b/include/polarssl/config.h index 5aee16557..9fc5458a7 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -537,6 +537,54 @@ */ #define POLARSSL_SSL_MAX_FRAGMENT_LENGTH +/** + * \def POLARSSL_SSL_PROTO_SSL3 + * + * Enable support for SSL 3.0 + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for SSL 3.0 + */ +#define POLARSSL_SSL_PROTO_SSL3 + +/** + * \def POLARSSL_SSL_PROTO_TLS1 + * + * Enable support for TLS 1.0 + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for TLS 1.0 + */ +#define POLARSSL_SSL_PROTO_TLS1 + +/** + * \def POLARSSL_SSL_PROTO_TLS1_1 + * + * Enable support for TLS 1.1 + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for TLS 1.1 + */ +#define POLARSSL_SSL_PROTO_TLS1_1 + +/** + * \def POLARSSL_SSL_PROTO_TLS1_2 + * + * Enable support for TLS 1.2 + * + * Requires: POLARSSL_SHA256_C or POLARSSL_SHA512_C + * (Depends on ciphersuites) + * + * Comment this macro to disable support for TLS 1.2 + */ +#define POLARSSL_SSL_PROTO_TLS1_2 + /** * \def POLARSSL_SSL_SESSION_TICKETS * @@ -1226,7 +1274,8 @@ * Caller: library/ssl_cli.c * library/ssl_srv.c * - * Requires: POLARSSL_MD5_C, POLARSSL_SHA1_C, POLARSSL_CIPHER_C + * Requires: POLARSSL_CIPHER_C and at least one of the + * POLARSSL_SSL_PROTO_* defines * * This module is required for SSL/TLS. */ @@ -1454,8 +1503,7 @@ #error "POLARSSL_SSL_CLI_C defined, but not all prerequisites" #endif -#if defined(POLARSSL_SSL_TLS_C) && ( !defined(POLARSSL_MD5_C) || \ - !defined(POLARSSL_SHA1_C) || !defined(POLARSSL_CIPHER_C) ) +#if defined(POLARSSL_SSL_TLS_C) && !defined(POLARSSL_CIPHER_C) #error "POLARSSL_SSL_TLS_C defined, but not all prerequisites" #endif @@ -1463,6 +1511,28 @@ #error "POLARSSL_SSL_SRV_C defined, but not all prerequisites" #endif +#if defined(POLARSSL_SSL_TLS_C) && (!defined(POLARSSL_SSL_PROTO_SSL3) && \ + !defined(POLARSSL_SSL_PROTO_TLS1) && !defined(POLARSSL_SSL_PROTO_TLS1_1) && \ + !defined(POLARSSL_SSL_PROTO_TLS1_2)) +#error "POLARSSL_SSL_TLS_C defined, but no protocols are active" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_SSL3) && \ + defined(POLARSSL_SSL_PROTO_TLS1_1) && !defined(POLARSSL_SSL_PROTO_TLS1)) +#error "Illegal protocol selection" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_TLS1) && \ + defined(POLARSSL_SSL_PROTO_TLS1_2) && !defined(POLARSSL_SSL_PROTO_TLS1_1)) +#error "Illegal protocol selection" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_SSL3) && \ + defined(POLARSSL_SSL_PROTO_TLS1_2) && (!defined(POLARSSL_SSL_PROTO_TLS1) || \ + !defined(POLARSSL_SSL_PROTO_TLS1_1))) +#error "Illegal protocol selection" +#endif + #if defined(POLARSSL_SSL_SESSION_TICKETS) && defined(POLARSSL_SSL_TLS_C) && \ ( !defined(POLARSSL_AES_C) || !defined(POLARSSL_SHA256_C) ) #error "POLARSSL_SSL_SESSION_TICKETS_C defined, but not all prerequisites" diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 8383b7fdb..1576fcb2f 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -31,14 +31,28 @@ #include "net.h" #include "bignum.h" -#include "md5.h" -#include "sha1.h" -#include "sha256.h" -#include "sha512.h" -#include "aes.h" - #include "ssl_ciphersuites.h" +#if defined(POLARSSL_MD5_C) +#include "md5.h" +#endif + +#if defined(POLARSSL_SHA1_C) +#include "sha1.h" +#endif + +#if defined(POLARSSL_SHA256_C) +#include "sha256.h" +#endif + +#if defined(POLARSSL_SHA512_C) +#include "sha512.h" +#endif + +#if defined(POLARSSL_AES_C) +#include "aes.h" +#endif + #if defined(POLARSSL_X509_PARSE_C) #include "x509.h" #endif @@ -121,6 +135,44 @@ #define SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */ #define SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */ +/* Determine minimum supported version */ +#define SSL_MIN_MAJOR_VERSION SSL_MAJOR_VERSION_3 + +#if defined(POLARSSL_SSL_PROTO_SSL3) +#define SSL_MIN_MINOR_VERSION SSL_MINOR_VERSION_0 +#else +#if defined(POLARSSL_SSL_PROTO_TLS1) +#define SSL_MIN_MINOR_VERSION SSL_MINOR_VERSION_1 +#else +#if defined(POLARSSL_SSL_PROTO_TLS1_1) +#define SSL_MIN_MINOR_VERSION SSL_MINOR_VERSION_2 +#else +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#define SSL_MIN_MINOR_VERSION SSL_MINOR_VERSION_3 +#endif +#endif +#endif +#endif + +/* Determine maximum supported version */ +#define SSL_MAX_MAJOR_VERSION SSL_MAJOR_VERSION_3 + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#define SSL_MAX_MINOR_VERSION SSL_MINOR_VERSION_3 +#else +#if defined(POLARSSL_SSL_PROTO_TLS1_1) +#define SSL_MAX_MINOR_VERSION SSL_MINOR_VERSION_2 +#else +#if defined(POLARSSL_SSL_PROTO_TLS1) +#define SSL_MAX_MINOR_VERSION SSL_MINOR_VERSION_1 +#else +#if defined(POLARSSL_SSL_PROTO_SSL3) +#define SSL_MAX_MINOR_VERSION SSL_MINOR_VERSION_0 +#endif +#endif +#endif +#endif + /* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c * NONE must be zero so that memset()ing structure to zero works */ #define SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */ @@ -392,9 +444,11 @@ struct _ssl_transform unsigned char iv_enc[16]; /*!< IV (encryption) */ unsigned char iv_dec[16]; /*!< IV (decryption) */ +#if defined(POLARSSL_SSL_PROTO_SSL3) /* Needed only for SSL v3.0 secret */ unsigned char mac_enc[32]; /*!< SSL v3.0 secret (enc) */ unsigned char mac_dec[32]; /*!< SSL v3.0 secret (dec) */ +#endif /* POLARSSL_SSL_PROTO_SSL3 */ md_context_t md_ctx_enc; /*!< MAC (encryption) */ md_context_t md_ctx_dec; /*!< MAC (decryption) */ @@ -436,12 +490,19 @@ struct _ssl_handshake_params /* * Checksum contexts */ +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) md5_context fin_md5; sha1_context fin_sha1; +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) sha256_context fin_sha256; +#endif #if defined(POLARSSL_SHA512_C) sha512_context fin_sha512; #endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ void (*update_checksum)(ssl_context *, const unsigned char *, size_t); void (*calc_verify)(ssl_context *, unsigned char *); @@ -1010,11 +1071,12 @@ void ssl_set_sni( ssl_context *ssl, /** * \brief Set the maximum supported version sent from the client side * and/or accepted at the server side - * (Default: SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3) + * (Default: SSL_MAX_MAJOR_VERSION, SSL_MAX_MINOR_VERSION) + * + * Note: This ignores ciphersuites from 'higher' versions. + * Note: Input outside of the SSL_MAX_XXXXX_VERSION and + * SSL_MIN_XXXXX_VERSION range is ignored. * - * Note: This prevents ciphersuites from 'higher' versions to - * be ignored. - * * \param ssl SSL context * \param major Major version number (only SSL_MAJOR_VERSION_3 supported) * \param minor Minor version number (SSL_MINOR_VERSION_0, @@ -1026,7 +1088,10 @@ void ssl_set_max_version( ssl_context *ssl, int major, int minor ); /** * \brief Set the minimum accepted SSL/TLS protocol version - * (Default: SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0) + * (Default: SSL_MIN_MAJOR_VERSION, SSL_MIN_MINOR_VERSION) + * + * Note: Input outside of the SSL_MAX_XXXXX_VERSION and + * SSL_MIN_XXXXX_VERSION range is ignored. * * \param ssl SSL context * \param major Major version number (only SSL_MAJOR_VERSION_3 supported) diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 1c2c395db..99d3206e5 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -129,6 +129,7 @@ static void ssl_write_renegotiation_ext( ssl_context *ssl, *olen = 5 + ssl->verify_data_len; } +#if defined(POLARSSL_SSL_PROTO_TLS1_2) static void ssl_write_signature_algorithms_ext( ssl_context *ssl, unsigned char *buf, size_t *olen ) @@ -198,6 +199,7 @@ static void ssl_write_signature_algorithms_ext( ssl_context *ssl, *olen = 6 + sig_alg_len; } +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) static void ssl_write_supported_elliptic_curves_ext( ssl_context *ssl, @@ -384,8 +386,8 @@ static int ssl_write_client_hello( ssl_context *ssl ) if( ssl->max_major_ver == 0 && ssl->max_minor_ver == 0 ) { - ssl->max_major_ver = SSL_MAJOR_VERSION_3; - ssl->max_minor_ver = SSL_MINOR_VERSION_3; + ssl->max_major_ver = SSL_MAX_MAJOR_VERSION; + ssl->max_minor_ver = SSL_MAX_MINOR_VERSION; } /* @@ -538,8 +540,10 @@ static int ssl_write_client_hello( ssl_context *ssl ) ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; +#if defined(POLARSSL_SSL_PROTO_TLS1_2) ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; +#endif #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen ); @@ -1152,6 +1156,7 @@ static int ssl_parse_server_psk_hint( ssl_context *ssl, #endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED || POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) static int ssl_parse_signature_algorithm( ssl_context *ssl, @@ -1212,6 +1217,7 @@ static int ssl_parse_signature_algorithm( ssl_context *ssl, } #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED || POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ static int ssl_parse_server_key_exchange( ssl_context *ssl ) { @@ -1224,7 +1230,7 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) unsigned char hash[64]; md_type_t md_alg = POLARSSL_MD_NONE; unsigned int hashlen = 0; -#endif +#endif SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); @@ -1325,6 +1331,7 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA || ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ) { +#if defined(POLARSSL_SSL_PROTO_TLS1_2) /* * Handle the digitally-signed structure */ @@ -1336,6 +1343,7 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ n = ( p[0] << 8 ) | p[1]; p += 2; @@ -1360,6 +1368,8 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) if( ssl->minor_ver != SSL_MINOR_VERSION_3 ) { md5_context md5; @@ -1394,6 +1404,10 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) hashlen = 36; } else +#endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \ + POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) { md_context_t ctx; @@ -1418,6 +1432,10 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) md_finish( &ctx, hash ); md_free_ctx( &ctx ); } + else +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + /* Should never happen */ + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); @@ -1445,7 +1463,7 @@ static int ssl_parse_certificate_request( ssl_context *ssl ) int ret; unsigned char *buf, *p; size_t n = 0, m = 0; - size_t cert_type_len = 0, sig_alg_len = 0, dn_len = 0; + size_t cert_type_len = 0, dn_len = 0; SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); @@ -1527,10 +1545,11 @@ static int ssl_parse_certificate_request( ssl_context *ssl ) return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); } +#if defined(POLARSSL_SSL_PROTO_TLS1_2) if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) { - sig_alg_len = ( ( buf[5 + n] << 8 ) - | ( buf[6 + n] ) ); + size_t sig_alg_len = ( ( buf[5 + n] << 8 ) + | ( buf[6 + n] ) ); p = buf + 7 + n; m += 2; @@ -1542,6 +1561,7 @@ static int ssl_parse_certificate_request( ssl_context *ssl ) return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); } } +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ dn_len = ( ( buf[5 + m + n] << 8 ) | ( buf[6 + m + n] ) ); @@ -1808,12 +1828,15 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) i = 4; n = pk_get_size( &ssl->session_negotiate->peer_cert->pk ) / 8; +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) if( ssl->minor_ver != SSL_MINOR_VERSION_0 ) { i += 2; ssl->out_msg[4] = (unsigned char)( n >> 8 ); ssl->out_msg[5] = (unsigned char)( n ); } +#endif ret = rsa_pkcs1_encrypt( pk_rsa( ssl->session_negotiate->peer_cert->pk ), @@ -1914,6 +1937,8 @@ static int ssl_write_certificate_verify( ssl_context *ssl ) */ ssl->handshake->calc_verify( ssl, hash ); +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) if( ssl->minor_ver != SSL_MINOR_VERSION_3 ) { /* @@ -1932,6 +1957,10 @@ static int ssl_write_certificate_verify( ssl_context *ssl ) md_alg = POLARSSL_MD_NONE; } else +#endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \ + POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) { /* * digitally-signed struct { @@ -1964,6 +1993,10 @@ static int ssl_write_certificate_verify( ssl_context *ssl ) offset = 2; } + else +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + /* Should never happen */ + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); if ( ssl->rsa_key ) n = ssl->rsa_key_len ( ssl->rsa_key ); diff --git a/library/ssl_srv.c b/library/ssl_srv.c index bfbf2cbb7..4a7136775 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -424,6 +424,7 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl, return( 0 ); } +#if defined(POLARSSL_SSL_PROTO_TLS1_2) static int ssl_parse_signature_algorithms_ext( ssl_context *ssl, const unsigned char *buf, size_t len ) @@ -492,6 +493,7 @@ static int ssl_parse_signature_algorithms_ext( ssl_context *ssl, return( 0 ); } +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) static int ssl_parse_supported_elliptic_curves( ssl_context *ssl, @@ -1174,6 +1176,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) return( ret ); break; +#if defined(POLARSSL_SSL_PROTO_TLS1_2) case TLS_EXT_SIG_ALG: SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); if( ssl->renegotiation == SSL_RENEGOTIATION ) @@ -1183,6 +1186,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) if( ret != 0 ) return( ret ); break; +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) case TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: @@ -1713,6 +1717,7 @@ static int ssl_write_certificate_request( ssl_context *ssl ) *p++ = 1; *p++ = SSL_CERT_TYPE_RSA_SIGN; +#if defined(POLARSSL_SSL_PROTO_TLS1_2) /* * Add signature_algorithms for verify (TLS 1.2) * Only add current running algorithm that is already required for @@ -1738,6 +1743,7 @@ static int ssl_write_certificate_request( ssl_context *ssl ) n += 4; } +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ p += 2; crt = ssl->ca_chain; @@ -1908,6 +1914,8 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) { size_t rsa_key_len = 0; +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) if( ssl->minor_ver != SSL_MINOR_VERSION_3 ) { md5_context md5; @@ -1940,6 +1948,10 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) md_alg = POLARSSL_MD_NONE; } else +#endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \ + POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) { md_context_t ctx; @@ -2001,12 +2013,17 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) } } + else +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + /* Should never happen */ + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); if ( ssl->rsa_key ) rsa_key_len = ssl->rsa_key_len( ssl->rsa_key ); +#if defined(POLARSSL_SSL_PROTO_TLS1_2) if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) { *(p++) = ssl->handshake->sig_alg; @@ -2014,6 +2031,7 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) n += 2; } +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ *(p++) = (unsigned char)( rsa_key_len >> 8 ); *(p++) = (unsigned char)( rsa_key_len ); @@ -2170,6 +2188,8 @@ static int ssl_parse_encrypted_pms_secret( ssl_context *ssl ) n = ssl->rsa_key_len( ssl->rsa_key ); ssl->handshake->pmslen = 48; +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) if( ssl->minor_ver != SSL_MINOR_VERSION_0 ) { i += 2; @@ -2180,6 +2200,7 @@ static int ssl_parse_encrypted_pms_secret( ssl_context *ssl ) return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } } +#endif if( ssl->in_hslen != i + n ) { @@ -2513,6 +2534,7 @@ static int ssl_parse_certificate_verify( ssl_context *ssl ) return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); } +#if defined(POLARSSL_SSL_PROTO_TLS1_2) if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) { /* @@ -2534,10 +2556,18 @@ static int ssl_parse_certificate_verify( ssl_context *ssl ) n += 2; } else +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + if( ssl->minor_ver != SSL_MINOR_VERSION_3 ) { hashlen = 36; md_alg = POLARSSL_MD_NONE; } + else +#endif + /* Should never happen */ + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); /* EC NOT IMPLEMENTED YET */ if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk, diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 033c9faf6..06eeb7130 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -158,6 +158,7 @@ static size_t ssl_rsa_key_len( void *ctx ) /* * Key material generation */ +#if defined(POLARSSL_SSL_PROTO_SSL3) static int ssl3_prf( const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, @@ -202,7 +203,9 @@ static int ssl3_prf( const unsigned char *secret, size_t slen, return( 0 ); } +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) static int tls1_prf( const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, @@ -263,7 +266,10 @@ static int tls1_prf( const unsigned char *secret, size_t slen, return( 0 ); } +#endif /* POLARSSL_SSL_PROTO_TLS1) || POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) static int tls_prf_sha256( const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, @@ -303,6 +309,7 @@ static int tls_prf_sha256( const unsigned char *secret, size_t slen, return( 0 ); } +#endif /* POLARSSL_SHA256_C */ #if defined(POLARSSL_SHA512_C) static int tls_prf_sha384( const unsigned char *secret, size_t slen, @@ -344,25 +351,39 @@ static int tls_prf_sha384( const unsigned char *secret, size_t slen, return( 0 ); } -#endif +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ static void ssl_update_checksum_start(ssl_context *, const unsigned char *, size_t); + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) static void ssl_update_checksum_md5sha1(ssl_context *, const unsigned char *, size_t); -static void ssl_update_checksum_sha256(ssl_context *, const unsigned char *, size_t); +#endif +#if defined(POLARSSL_SSL_PROTO_SSL3) static void ssl_calc_verify_ssl(ssl_context *,unsigned char *); -static void ssl_calc_verify_tls(ssl_context *,unsigned char *); -static void ssl_calc_verify_tls_sha256(ssl_context *,unsigned char *); - static void ssl_calc_finished_ssl(ssl_context *,unsigned char *,int); +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) +static void ssl_calc_verify_tls(ssl_context *,unsigned char *); static void ssl_calc_finished_tls(ssl_context *,unsigned char *,int); +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) +static void ssl_update_checksum_sha256(ssl_context *, const unsigned char *, size_t); +static void ssl_calc_verify_tls_sha256(ssl_context *,unsigned char *); static void ssl_calc_finished_tls_sha256(ssl_context *,unsigned char *,int); +#endif #if defined(POLARSSL_SHA512_C) static void ssl_update_checksum_sha384(ssl_context *, const unsigned char *, size_t); static void ssl_calc_verify_tls_sha384(ssl_context *,unsigned char *); static void ssl_calc_finished_tls_sha384(ssl_context *,unsigned char *,int); #endif +#endif int ssl_derive_keys( ssl_context *ssl ) { @@ -375,7 +396,6 @@ int ssl_derive_keys( ssl_context *ssl ) unsigned int iv_copy_len; const cipher_info_t *cipher_info; const md_info_t *md_info; - int ret; ssl_session *session = ssl->session_negotiate; ssl_transform *transform = ssl->transform_negotiate; @@ -402,33 +422,47 @@ int ssl_derive_keys( ssl_context *ssl ) /* * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions */ +#if defined(POLARSSL_SSL_PROTO_SSL3) if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) { handshake->tls_prf = ssl3_prf; handshake->calc_verify = ssl_calc_verify_ssl; handshake->calc_finished = ssl_calc_finished_ssl; } - else if( ssl->minor_ver < SSL_MINOR_VERSION_3 ) + else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) + if( ssl->minor_ver < SSL_MINOR_VERSION_3 ) { handshake->tls_prf = tls1_prf; handshake->calc_verify = ssl_calc_verify_tls; handshake->calc_finished = ssl_calc_finished_tls; } + else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) #if defined(POLARSSL_SHA512_C) - else if( transform->ciphersuite_info->mac == - POLARSSL_MD_SHA384 ) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 && + transform->ciphersuite_info->mac == POLARSSL_MD_SHA384 ) { handshake->tls_prf = tls_prf_sha384; handshake->calc_verify = ssl_calc_verify_tls_sha384; handshake->calc_finished = ssl_calc_finished_tls_sha384; } -#endif else +#endif +#if defined(POLARSSL_SHA256_C) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) { handshake->tls_prf = tls_prf_sha256; handshake->calc_verify = ssl_calc_verify_tls_sha256; handshake->calc_finished = ssl_calc_finished_tls_sha256; } + else +#endif +#endif + /* Should never happen */ + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); /* * SSLv3: @@ -437,7 +471,7 @@ int ssl_derive_keys( ssl_context *ssl ) * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) + * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) ) * - * TLSv1: + * TLSv1+: * master = PRF( premaster, "master secret", randbytes )[0..47] */ if( handshake->resume == 0 ) @@ -502,6 +536,8 @@ int ssl_derive_keys( ssl_context *ssl ) { if( md_info->type != POLARSSL_MD_NONE ) { + int ret; + if( ( ret = md_init_ctx( &transform->md_ctx_enc, md_info ) ) != 0 ) { SSL_DEBUG_RET( 1, "md_init_ctx", ret ); @@ -583,16 +619,25 @@ int ssl_derive_keys( ssl_context *ssl ) iv_copy_len ); } +#if defined(POLARSSL_SSL_PROTO_SSL3) if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) { memcpy( transform->mac_enc, mac_enc, transform->maclen ); memcpy( transform->mac_dec, mac_dec, transform->maclen ); } else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver >= SSL_MINOR_VERSION_1 ) { md_hmac_starts( &transform->md_ctx_enc, mac_enc, transform->maclen ); md_hmac_starts( &transform->md_ctx_dec, mac_dec, transform->maclen ); } + else +#endif + /* Should never happen */ + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); #if defined(POLARSSL_SSL_HW_RECORD_ACCEL) if( ssl_hw_record_init != NULL) @@ -701,6 +746,7 @@ int ssl_derive_keys( ssl_context *ssl ) return( 0 ); } +#if defined(POLARSSL_SSL_PROTO_SSL3) void ssl_calc_verify_ssl( ssl_context *ssl, unsigned char hash[36] ) { md5_context md5; @@ -741,7 +787,9 @@ void ssl_calc_verify_ssl( ssl_context *ssl, unsigned char hash[36] ) return; } +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) void ssl_calc_verify_tls( ssl_context *ssl, unsigned char hash[36] ) { md5_context md5; @@ -760,7 +808,10 @@ void ssl_calc_verify_tls( ssl_context *ssl, unsigned char hash[36] ) return; } +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) void ssl_calc_verify_tls_sha256( ssl_context *ssl, unsigned char hash[32] ) { sha256_context sha256; @@ -775,6 +826,7 @@ void ssl_calc_verify_tls_sha256( ssl_context *ssl, unsigned char hash[32] ) return; } +#endif /* POLARSSL_SHA256_C */ #if defined(POLARSSL_SHA512_C) void ssl_calc_verify_tls_sha384( ssl_context *ssl, unsigned char hash[48] ) @@ -791,8 +843,10 @@ void ssl_calc_verify_tls_sha384( ssl_context *ssl, unsigned char hash[48] ) return; } -#endif +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ +#if defined(POLARSSL_SSL_PROTO_SSL3) /* * SSLv3.0 MAC functions */ @@ -833,6 +887,7 @@ static void ssl_mac( md_context_t *md_ctx, unsigned char *secret, md_update( md_ctx, buf + len, md_size ); md_finish( md_ctx, buf + len ); } +#endif /* POLARSSL_SSL_PROTO_SSL3 */ /* * Encryption/decryption functions @@ -846,6 +901,7 @@ static int ssl_encrypt_buf( ssl_context *ssl ) /* * Add MAC then encrypt */ +#if defined(POLARSSL_SSL_PROTO_SSL3) if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) { ssl_mac( &ssl->transform_out->md_ctx_enc, @@ -854,6 +910,10 @@ static int ssl_encrypt_buf( ssl_context *ssl ) ssl->out_ctr, ssl->out_msgtype ); } else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver >= SSL_MINOR_VERSION_1 ) { md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 13 ); md_hmac_update( &ssl->transform_out->md_ctx_enc, @@ -862,6 +922,10 @@ static int ssl_encrypt_buf( ssl_context *ssl ) ssl->out_msg + ssl->out_msglen ); md_hmac_reset( &ssl->transform_out->md_ctx_enc ); } + else +#endif + /* Should never happen */ + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); SSL_DEBUG_BUF( 4, "computed mac", ssl->out_msg + ssl->out_msglen, ssl->transform_out->maclen ); @@ -977,6 +1041,7 @@ static int ssl_encrypt_buf( ssl_context *ssl ) enc_msglen = ssl->out_msglen; enc_msg = ssl->out_msg; +#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2) /* * Prepend per-record IV for block cipher in TLS v1.1 and up as per * Method 1 (6.2.3.2. in RFC4346 and RFC5246) @@ -1001,6 +1066,7 @@ static int ssl_encrypt_buf( ssl_context *ssl ) enc_msglen = ssl->out_msglen; ssl->out_msglen += ssl->transform_out->ivlen; } +#endif /* POLARSSL_SSL_PROTO_TLS1_1 || POLARSSL_SSL_PROTO_TLS1_2 */ SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " "including %d bytes of IV and %d bytes of padding", @@ -1165,8 +1231,10 @@ static int ssl_decrypt_buf( ssl_context *ssl ) return( POLARSSL_ERR_SSL_INVALID_MAC ); } +#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2) if( ssl->minor_ver >= SSL_MINOR_VERSION_2 ) minlen += ssl->transform_in->ivlen; +#endif if( ssl->in_msglen < minlen + ssl->transform_in->ivlen || ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 ) @@ -1180,6 +1248,7 @@ static int ssl_decrypt_buf( ssl_context *ssl ) dec_msg = ssl->in_msg; dec_msg_result = ssl->in_msg; +#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2) /* * Initialize for prepended IV for block cipher in TLS v1.1 and up */ @@ -1191,6 +1260,7 @@ static int ssl_decrypt_buf( ssl_context *ssl ) for( i = 0; i < ssl->transform_in->ivlen; i++ ) ssl->transform_in->iv_dec[i] = ssl->in_iv[i]; } +#endif /* POLARSSL_SSL_PROTO_TLS1_1 || POLARSSL_SSL_PROTO_TLS1_2 */ switch( ssl->transform_in->ciphersuite_info->cipher ) { @@ -1242,6 +1312,7 @@ static int ssl_decrypt_buf( ssl_context *ssl ) correct = 0; } +#if defined(POLARSSL_SSL_PROTO_SSL3) if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) { if( padlen > ssl->transform_in->ivlen ) @@ -1255,6 +1326,10 @@ static int ssl_decrypt_buf( ssl_context *ssl ) } } else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver > SSL_MINOR_VERSION_0 ) { /* * TLSv1+: always check the padding up to the first failure @@ -1278,6 +1353,11 @@ static int ssl_decrypt_buf( ssl_context *ssl ) #endif padlen &= correct * 0x1FF; } + else +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \ + POLARSSL_SSL_PROTO_TLS1_2 */ + /* Should never happen */ + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); } SSL_DEBUG_BUF( 4, "raw buffer after decryption", @@ -1293,6 +1373,7 @@ static int ssl_decrypt_buf( ssl_context *ssl ) memcpy( tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen ); +#if defined(POLARSSL_SSL_PROTO_SSL3) if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) { ssl_mac( &ssl->transform_in->md_ctx_dec, @@ -1301,6 +1382,10 @@ static int ssl_decrypt_buf( ssl_context *ssl ) ssl->in_ctr, ssl->in_msgtype ); } else +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver > SSL_MINOR_VERSION_0 ) { /* * Process MAC and always update for padlen afterwards to make @@ -1331,6 +1416,11 @@ static int ssl_decrypt_buf( ssl_context *ssl ) md_hmac_reset( &ssl->transform_in->md_ctx_dec ); } + else +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \ + POLARSSL_SSL_PROTO_TLS1_2 */ + /* Should never happen */ + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); SSL_DEBUG_BUF( 4, "message mac", tmp, ssl->transform_in->maclen ); SSL_DEBUG_BUF( 4, "computed mac", ssl->in_msg + ssl->in_msglen, @@ -1742,13 +1832,17 @@ int ssl_read_record( ssl_context *ssl ) return( POLARSSL_ERR_SSL_INVALID_RECORD ); } +#if defined(POLARSSL_SSL_PROTO_SSL3) if( ssl->minor_ver == SSL_MINOR_VERSION_0 && ssl->in_msglen > ssl->transform_in->minlen + SSL_MAX_CONTENT_LEN ) { SSL_DEBUG_MSG( 1, ( "bad message length" ) ); return( POLARSSL_ERR_SSL_INVALID_RECORD ); } +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) /* * TLS encrypted messages can have up to 256 bytes of padding */ @@ -1758,6 +1852,7 @@ int ssl_read_record( ssl_context *ssl ) SSL_DEBUG_MSG( 1, ( "bad message length" ) ); return( POLARSSL_ERR_SSL_INVALID_RECORD ); } +#endif } /* @@ -2014,6 +2109,7 @@ int ssl_write_certificate( ssl_context *ssl ) return( 0 ); } +#if defined(POLARSSL_SSL_PROTO_SSL3) /* * If using SSLv3 and got no cert, send an Alert message * (otherwise an empty Certificate message will be sent). @@ -2029,6 +2125,7 @@ int ssl_write_certificate( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) ); goto write_msg; } +#endif /* POLARSSL_SSL_PROTO_SSL3 */ } else /* SSL_IS_SERVER */ { @@ -2079,7 +2176,9 @@ int ssl_write_certificate( ssl_context *ssl ) ssl->out_msgtype = SSL_MSG_HANDSHAKE; ssl->out_msg[0] = SSL_HS_CERTIFICATE; +#if defined(POLARSSL_SSL_PROTO_SSL3) write_msg: +#endif ssl->state++; @@ -2127,6 +2226,7 @@ int ssl_parse_certificate( ssl_context *ssl ) ssl->state++; +#if defined(POLARSSL_SSL_PROTO_SSL3) /* * Check if the client sent an empty certificate */ @@ -2147,7 +2247,10 @@ int ssl_parse_certificate( ssl_context *ssl ) return( POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE ); } } +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) if( ssl->endpoint == SSL_IS_SERVER && ssl->minor_ver != SSL_MINOR_VERSION_0 ) { @@ -2165,6 +2268,8 @@ int ssl_parse_certificate( ssl_context *ssl ) return( 0 ); } } +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \ + POLARSSL_SSL_PROTO_TLS1_2 */ if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) { @@ -2317,45 +2422,66 @@ int ssl_parse_change_cipher_spec( ssl_context *ssl ) void ssl_optimize_checksum( ssl_context *ssl, const ssl_ciphersuite_t *ciphersuite_info ) { -#if !defined(POLARSSL_SHA512_C) ((void) ciphersuite_info); -#endif +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) if( ssl->minor_ver < SSL_MINOR_VERSION_3 ) ssl->handshake->update_checksum = ssl_update_checksum_md5sha1; -#if defined(POLARSSL_SHA512_C) - else if( ciphersuite_info->mac == POLARSSL_MD_SHA384 ) - { - ssl->handshake->update_checksum = ssl_update_checksum_sha384; - } -#endif else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA512_C) + if( ciphersuite_info->mac == POLARSSL_MD_SHA384 ) + ssl->handshake->update_checksum = ssl_update_checksum_sha384; + else +#endif +#if defined(POLARSSL_SHA256_C) + if( ciphersuite_info->mac != POLARSSL_MD_SHA384 ) ssl->handshake->update_checksum = ssl_update_checksum_sha256; + else +#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + /* Should never happen */ + return; } static void ssl_update_checksum_start( ssl_context *ssl, const unsigned char *buf, size_t len ) { +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) md5_update( &ssl->handshake->fin_md5 , buf, len ); sha1_update( &ssl->handshake->fin_sha1, buf, len ); +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) sha256_update( &ssl->handshake->fin_sha256, buf, len ); +#endif #if defined(POLARSSL_SHA512_C) sha512_update( &ssl->handshake->fin_sha512, buf, len ); #endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ } +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) static void ssl_update_checksum_md5sha1( ssl_context *ssl, const unsigned char *buf, size_t len ) { md5_update( &ssl->handshake->fin_md5 , buf, len ); sha1_update( &ssl->handshake->fin_sha1, buf, len ); } +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) static void ssl_update_checksum_sha256( ssl_context *ssl, const unsigned char *buf, size_t len ) { sha256_update( &ssl->handshake->fin_sha256, buf, len ); } +#endif #if defined(POLARSSL_SHA512_C) static void ssl_update_checksum_sha384( ssl_context *ssl, @@ -2364,7 +2490,9 @@ static void ssl_update_checksum_sha384( ssl_context *ssl, sha512_update( &ssl->handshake->fin_sha512, buf, len ); } #endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ +#if defined(POLARSSL_SSL_PROTO_SSL3) static void ssl_calc_finished_ssl( ssl_context *ssl, unsigned char *buf, int from ) { @@ -2444,7 +2572,9 @@ static void ssl_calc_finished_ssl( SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); } +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) static void ssl_calc_finished_tls( ssl_context *ssl, unsigned char *buf, int from ) { @@ -2498,7 +2628,10 @@ static void ssl_calc_finished_tls( SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); } +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) static void ssl_calc_finished_tls_sha256( ssl_context *ssl, unsigned char *buf, int from ) { @@ -2543,6 +2676,7 @@ static void ssl_calc_finished_tls_sha256( SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); } +#endif /* POLARSSL_SHA256_C */ #if defined(POLARSSL_SHA512_C) static void ssl_calc_finished_tls_sha384( @@ -2589,7 +2723,8 @@ static void ssl_calc_finished_tls_sha384( SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); } -#endif +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ void ssl_handshake_wrapup( ssl_context *ssl ) { @@ -2828,12 +2963,19 @@ static int ssl_handshake_init( ssl_context *ssl ) memset( ssl->transform_negotiate, 0, sizeof(ssl_transform) ); memset( ssl->session_negotiate, 0, sizeof(ssl_session) ); +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) md5_starts( &ssl->handshake->fin_md5 ); sha1_starts( &ssl->handshake->fin_sha1 ); +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) sha256_starts( &ssl->handshake->fin_sha256, 0 ); +#endif #if defined(POLARSSL_SHA512_C) sha512_starts( &ssl->handshake->fin_sha512, 1 ); #endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ ssl->handshake->update_checksum = ssl_update_checksum_start; ssl->handshake->sig_alg = SSL_HASH_SHA1; @@ -2864,10 +3006,10 @@ int ssl_init( ssl_context *ssl ) ssl->rsa_key_len = ssl_rsa_key_len; #endif - ssl->min_major_ver = SSL_MAJOR_VERSION_3; - ssl->min_minor_ver = SSL_MINOR_VERSION_0; - ssl->max_major_ver = SSL_MAJOR_VERSION_3; - ssl->max_minor_ver = SSL_MINOR_VERSION_3; + ssl->min_major_ver = SSL_MIN_MAJOR_VERSION; + ssl->min_minor_ver = SSL_MIN_MINOR_VERSION; + ssl->max_major_ver = SSL_MAX_MAJOR_VERSION; + ssl->max_minor_ver = SSL_MAX_MINOR_VERSION; ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() ); @@ -3248,14 +3390,22 @@ void ssl_set_sni( ssl_context *ssl, void ssl_set_max_version( ssl_context *ssl, int major, int minor ) { - ssl->max_major_ver = major; - ssl->max_minor_ver = minor; + if( major >= SSL_MIN_MAJOR_VERSION && major <= SSL_MAX_MAJOR_VERSION && + minor >= SSL_MIN_MINOR_VERSION && minor <= SSL_MAX_MINOR_VERSION ) + { + ssl->max_major_ver = major; + ssl->max_minor_ver = minor; + } } void ssl_set_min_version( ssl_context *ssl, int major, int minor ) { - ssl->min_major_ver = major; - ssl->min_minor_ver = minor; + if( major >= SSL_MIN_MAJOR_VERSION && major <= SSL_MAX_MAJOR_VERSION && + minor >= SSL_MIN_MINOR_VERSION && minor <= SSL_MAX_MINOR_VERSION ) + { + ssl->min_major_ver = major; + ssl->min_minor_ver = minor; + } } #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) @@ -3516,6 +3666,7 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len ) { SSL_DEBUG_MSG( 3, ( "ignoring renegotiation, sending alert" ) ); +#if defined(POLARSSL_SSL_PROTO_SSL3) if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) { /* @@ -3525,6 +3676,10 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len ) return( ret ); } else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver >= SSL_MINOR_VERSION_1 ) { if( ( ret = ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_WARNING, @@ -3533,6 +3688,10 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len ) return( ret ); } } + else +#endif + /* Should never happen */ + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); } else {