Ability to enable / disable SSL v3 / TLS 1.0 / TLS 1.1 / TLS 1.2 individually

This commit is contained in:
Paul Bakker 2013-08-27 21:19:20 +02:00
parent fb08fd2e23
commit d2f068e071
6 changed files with 408 additions and 49 deletions

View File

@ -20,6 +20,8 @@ Features
* Support for session tickets (RFC 5077) * Support for session tickets (RFC 5077)
Changes 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 * Introduced separate SSL Ciphersuites module that is based on
Cipher and MD information Cipher and MD information
* Internals for SSL module adapted to have separate IV pointer that is * Internals for SSL module adapted to have separate IV pointer that is

View File

@ -537,6 +537,54 @@
*/ */
#define POLARSSL_SSL_MAX_FRAGMENT_LENGTH #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 * \def POLARSSL_SSL_SESSION_TICKETS
* *
@ -1226,7 +1274,8 @@
* Caller: library/ssl_cli.c * Caller: library/ssl_cli.c
* library/ssl_srv.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. * This module is required for SSL/TLS.
*/ */
@ -1454,8 +1503,7 @@
#error "POLARSSL_SSL_CLI_C defined, but not all prerequisites" #error "POLARSSL_SSL_CLI_C defined, but not all prerequisites"
#endif #endif
#if defined(POLARSSL_SSL_TLS_C) && ( !defined(POLARSSL_MD5_C) || \ #if defined(POLARSSL_SSL_TLS_C) && !defined(POLARSSL_CIPHER_C)
!defined(POLARSSL_SHA1_C) || !defined(POLARSSL_CIPHER_C) )
#error "POLARSSL_SSL_TLS_C defined, but not all prerequisites" #error "POLARSSL_SSL_TLS_C defined, but not all prerequisites"
#endif #endif
@ -1463,6 +1511,28 @@
#error "POLARSSL_SSL_SRV_C defined, but not all prerequisites" #error "POLARSSL_SSL_SRV_C defined, but not all prerequisites"
#endif #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) && \ #if defined(POLARSSL_SSL_SESSION_TICKETS) && defined(POLARSSL_SSL_TLS_C) && \
( !defined(POLARSSL_AES_C) || !defined(POLARSSL_SHA256_C) ) ( !defined(POLARSSL_AES_C) || !defined(POLARSSL_SHA256_C) )
#error "POLARSSL_SSL_SESSION_TICKETS_C defined, but not all prerequisites" #error "POLARSSL_SSL_SESSION_TICKETS_C defined, but not all prerequisites"

View File

@ -31,14 +31,28 @@
#include "net.h" #include "net.h"
#include "bignum.h" #include "bignum.h"
#include "md5.h"
#include "sha1.h"
#include "sha256.h"
#include "sha512.h"
#include "aes.h"
#include "ssl_ciphersuites.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) #if defined(POLARSSL_X509_PARSE_C)
#include "x509.h" #include "x509.h"
#endif #endif
@ -121,6 +135,44 @@
#define SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */ #define SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */
#define SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */ #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 /* 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 */ * NONE must be zero so that memset()ing structure to zero works */
#define SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */ #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_enc[16]; /*!< IV (encryption) */
unsigned char iv_dec[16]; /*!< IV (decryption) */ unsigned char iv_dec[16]; /*!< IV (decryption) */
#if defined(POLARSSL_SSL_PROTO_SSL3)
/* Needed only for SSL v3.0 secret */ /* Needed only for SSL v3.0 secret */
unsigned char mac_enc[32]; /*!< SSL v3.0 secret (enc) */ unsigned char mac_enc[32]; /*!< SSL v3.0 secret (enc) */
unsigned char mac_dec[32]; /*!< SSL v3.0 secret (dec) */ 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_enc; /*!< MAC (encryption) */
md_context_t md_ctx_dec; /*!< MAC (decryption) */ md_context_t md_ctx_dec; /*!< MAC (decryption) */
@ -436,12 +490,19 @@ struct _ssl_handshake_params
/* /*
* Checksum contexts * Checksum contexts
*/ */
#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
defined(POLARSSL_SSL_PROTO_TLS1_1)
md5_context fin_md5; md5_context fin_md5;
sha1_context fin_sha1; sha1_context fin_sha1;
#endif
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
#if defined(POLARSSL_SHA256_C)
sha256_context fin_sha256; sha256_context fin_sha256;
#endif
#if defined(POLARSSL_SHA512_C) #if defined(POLARSSL_SHA512_C)
sha512_context fin_sha512; sha512_context fin_sha512;
#endif #endif
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
void (*update_checksum)(ssl_context *, const unsigned char *, size_t); void (*update_checksum)(ssl_context *, const unsigned char *, size_t);
void (*calc_verify)(ssl_context *, unsigned char *); void (*calc_verify)(ssl_context *, unsigned char *);
@ -1010,10 +1071,11 @@ void ssl_set_sni( ssl_context *ssl,
/** /**
* \brief Set the maximum supported version sent from the client side * \brief Set the maximum supported version sent from the client side
* and/or accepted at the server 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 prevents ciphersuites from 'higher' versions to * Note: This ignores ciphersuites from 'higher' versions.
* be ignored. * Note: Input outside of the SSL_MAX_XXXXX_VERSION and
* SSL_MIN_XXXXX_VERSION range is ignored.
* *
* \param ssl SSL context * \param ssl SSL context
* \param major Major version number (only SSL_MAJOR_VERSION_3 supported) * \param major Major version number (only SSL_MAJOR_VERSION_3 supported)
@ -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 * \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 ssl SSL context
* \param major Major version number (only SSL_MAJOR_VERSION_3 supported) * \param major Major version number (only SSL_MAJOR_VERSION_3 supported)

View File

@ -129,6 +129,7 @@ static void ssl_write_renegotiation_ext( ssl_context *ssl,
*olen = 5 + ssl->verify_data_len; *olen = 5 + ssl->verify_data_len;
} }
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
static void ssl_write_signature_algorithms_ext( ssl_context *ssl, static void ssl_write_signature_algorithms_ext( ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
size_t *olen ) size_t *olen )
@ -198,6 +199,7 @@ static void ssl_write_signature_algorithms_ext( ssl_context *ssl,
*olen = 6 + sig_alg_len; *olen = 6 + sig_alg_len;
} }
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
static void ssl_write_supported_elliptic_curves_ext( ssl_context *ssl, 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 ) if( ssl->max_major_ver == 0 && ssl->max_minor_ver == 0 )
{ {
ssl->max_major_ver = SSL_MAJOR_VERSION_3; ssl->max_major_ver = SSL_MAX_MAJOR_VERSION;
ssl->max_minor_ver = SSL_MINOR_VERSION_3; 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 ); ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
#endif
#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen ); 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 || #endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
static int ssl_parse_signature_algorithm( ssl_context *ssl, 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 || #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED ||
POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
static int ssl_parse_server_key_exchange( ssl_context *ssl ) static int ssl_parse_server_key_exchange( ssl_context *ssl )
{ {
@ -1325,6 +1331,7 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA || if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ||
ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ) ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
{ {
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
/* /*
* Handle the digitally-signed structure * 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 ); return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
} }
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
n = ( p[0] << 8 ) | p[1]; n = ( p[0] << 8 ) | p[1];
p += 2; 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 ); 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 ) if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
{ {
md5_context md5; md5_context md5;
@ -1394,6 +1404,10 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
hashlen = 36; hashlen = 36;
} }
else 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; md_context_t ctx;
@ -1418,6 +1432,10 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
md_finish( &ctx, hash ); md_finish( &ctx, hash );
md_free_ctx( &ctx ); 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 ); SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
@ -1445,7 +1463,7 @@ static int ssl_parse_certificate_request( ssl_context *ssl )
int ret; int ret;
unsigned char *buf, *p; unsigned char *buf, *p;
size_t n = 0, m = 0; 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" ) ); SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
@ -1527,9 +1545,10 @@ static int ssl_parse_certificate_request( ssl_context *ssl )
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
} }
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
{ {
sig_alg_len = ( ( buf[5 + n] << 8 ) size_t sig_alg_len = ( ( buf[5 + n] << 8 )
| ( buf[6 + n] ) ); | ( buf[6 + n] ) );
p = buf + 7 + n; p = buf + 7 + n;
@ -1542,6 +1561,7 @@ static int ssl_parse_certificate_request( ssl_context *ssl )
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
} }
} }
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
dn_len = ( ( buf[5 + m + n] << 8 ) dn_len = ( ( buf[5 + m + n] << 8 )
| ( buf[6 + m + n] ) ); | ( buf[6 + m + n] ) );
@ -1808,12 +1828,15 @@ static int ssl_write_client_key_exchange( ssl_context *ssl )
i = 4; i = 4;
n = pk_get_size( &ssl->session_negotiate->peer_cert->pk ) / 8; 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 ) if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
{ {
i += 2; i += 2;
ssl->out_msg[4] = (unsigned char)( n >> 8 ); ssl->out_msg[4] = (unsigned char)( n >> 8 );
ssl->out_msg[5] = (unsigned char)( n ); ssl->out_msg[5] = (unsigned char)( n );
} }
#endif
ret = rsa_pkcs1_encrypt( ret = rsa_pkcs1_encrypt(
pk_rsa( ssl->session_negotiate->peer_cert->pk ), 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 ); 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 ) 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; md_alg = POLARSSL_MD_NONE;
} }
else 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 { * digitally-signed struct {
@ -1964,6 +1993,10 @@ static int ssl_write_certificate_verify( ssl_context *ssl )
offset = 2; offset = 2;
} }
else
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
/* Should never happen */
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
if ( ssl->rsa_key ) if ( ssl->rsa_key )
n = ssl->rsa_key_len ( ssl->rsa_key ); n = ssl->rsa_key_len ( ssl->rsa_key );

View File

@ -424,6 +424,7 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
return( 0 ); return( 0 );
} }
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
static int ssl_parse_signature_algorithms_ext( ssl_context *ssl, static int ssl_parse_signature_algorithms_ext( ssl_context *ssl,
const unsigned char *buf, const unsigned char *buf,
size_t len ) size_t len )
@ -492,6 +493,7 @@ static int ssl_parse_signature_algorithms_ext( ssl_context *ssl,
return( 0 ); return( 0 );
} }
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
static int ssl_parse_supported_elliptic_curves( ssl_context *ssl, 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 ); return( ret );
break; break;
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
case TLS_EXT_SIG_ALG: case TLS_EXT_SIG_ALG:
SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
if( ssl->renegotiation == SSL_RENEGOTIATION ) if( ssl->renegotiation == SSL_RENEGOTIATION )
@ -1183,6 +1186,7 @@ static int ssl_parse_client_hello( ssl_context *ssl )
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
case TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: case TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
@ -1713,6 +1717,7 @@ static int ssl_write_certificate_request( ssl_context *ssl )
*p++ = 1; *p++ = 1;
*p++ = SSL_CERT_TYPE_RSA_SIGN; *p++ = SSL_CERT_TYPE_RSA_SIGN;
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
/* /*
* Add signature_algorithms for verify (TLS 1.2) * Add signature_algorithms for verify (TLS 1.2)
* Only add current running algorithm that is already required for * 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; n += 4;
} }
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
p += 2; p += 2;
crt = ssl->ca_chain; crt = ssl->ca_chain;
@ -1908,6 +1914,8 @@ static int ssl_write_server_key_exchange( ssl_context *ssl )
{ {
size_t rsa_key_len = 0; 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 ) if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
{ {
md5_context md5; md5_context md5;
@ -1940,6 +1948,10 @@ static int ssl_write_server_key_exchange( ssl_context *ssl )
md_alg = POLARSSL_MD_NONE; md_alg = POLARSSL_MD_NONE;
} }
else 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; 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 ); SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
if ( ssl->rsa_key ) if ( ssl->rsa_key )
rsa_key_len = ssl->rsa_key_len( 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 ) if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
{ {
*(p++) = ssl->handshake->sig_alg; *(p++) = ssl->handshake->sig_alg;
@ -2014,6 +2031,7 @@ static int ssl_write_server_key_exchange( ssl_context *ssl )
n += 2; n += 2;
} }
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
*(p++) = (unsigned char)( rsa_key_len >> 8 ); *(p++) = (unsigned char)( rsa_key_len >> 8 );
*(p++) = (unsigned char)( rsa_key_len ); *(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 ); n = ssl->rsa_key_len( ssl->rsa_key );
ssl->handshake->pmslen = 48; 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 ) if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
{ {
i += 2; 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 ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
} }
} }
#endif
if( ssl->in_hslen != i + n ) 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 ); return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
} }
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
{ {
/* /*
@ -2534,10 +2556,18 @@ static int ssl_parse_certificate_verify( ssl_context *ssl )
n += 2; n += 2;
} }
else 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; hashlen = 36;
md_alg = POLARSSL_MD_NONE; md_alg = POLARSSL_MD_NONE;
} }
else
#endif
/* Should never happen */
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
/* EC NOT IMPLEMENTED YET */ /* EC NOT IMPLEMENTED YET */
if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk, if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,

View File

@ -158,6 +158,7 @@ static size_t ssl_rsa_key_len( void *ctx )
/* /*
* Key material generation * Key material generation
*/ */
#if defined(POLARSSL_SSL_PROTO_SSL3)
static int ssl3_prf( const unsigned char *secret, size_t slen, static int ssl3_prf( const unsigned char *secret, size_t slen,
const char *label, const char *label,
const unsigned char *random, size_t rlen, const unsigned char *random, size_t rlen,
@ -202,7 +203,9 @@ static int ssl3_prf( const unsigned char *secret, size_t slen,
return( 0 ); 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, static int tls1_prf( const unsigned char *secret, size_t slen,
const char *label, const char *label,
const unsigned char *random, size_t rlen, const unsigned char *random, size_t rlen,
@ -263,7 +266,10 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
return( 0 ); 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, static int tls_prf_sha256( const unsigned char *secret, size_t slen,
const char *label, const char *label,
const unsigned char *random, size_t rlen, 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 ); return( 0 );
} }
#endif /* POLARSSL_SHA256_C */
#if defined(POLARSSL_SHA512_C) #if defined(POLARSSL_SHA512_C)
static int tls_prf_sha384( const unsigned char *secret, size_t slen, 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 ); 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); 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_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_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); 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); 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); static void ssl_calc_finished_tls_sha256(ssl_context *,unsigned char *,int);
#endif
#if defined(POLARSSL_SHA512_C) #if defined(POLARSSL_SHA512_C)
static void ssl_update_checksum_sha384(ssl_context *, const unsigned char *, size_t); 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_verify_tls_sha384(ssl_context *,unsigned char *);
static void ssl_calc_finished_tls_sha384(ssl_context *,unsigned char *,int); static void ssl_calc_finished_tls_sha384(ssl_context *,unsigned char *,int);
#endif #endif
#endif
int ssl_derive_keys( ssl_context *ssl ) int ssl_derive_keys( ssl_context *ssl )
{ {
@ -375,7 +396,6 @@ int ssl_derive_keys( ssl_context *ssl )
unsigned int iv_copy_len; unsigned int iv_copy_len;
const cipher_info_t *cipher_info; const cipher_info_t *cipher_info;
const md_info_t *md_info; const md_info_t *md_info;
int ret;
ssl_session *session = ssl->session_negotiate; ssl_session *session = ssl->session_negotiate;
ssl_transform *transform = ssl->transform_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 * 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 ) if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
{ {
handshake->tls_prf = ssl3_prf; handshake->tls_prf = ssl3_prf;
handshake->calc_verify = ssl_calc_verify_ssl; handshake->calc_verify = ssl_calc_verify_ssl;
handshake->calc_finished = ssl_calc_finished_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->tls_prf = tls1_prf;
handshake->calc_verify = ssl_calc_verify_tls; handshake->calc_verify = ssl_calc_verify_tls;
handshake->calc_finished = ssl_calc_finished_tls; handshake->calc_finished = ssl_calc_finished_tls;
} }
else
#endif
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
#if defined(POLARSSL_SHA512_C) #if defined(POLARSSL_SHA512_C)
else if( transform->ciphersuite_info->mac == if( ssl->minor_ver == SSL_MINOR_VERSION_3 &&
POLARSSL_MD_SHA384 ) transform->ciphersuite_info->mac == POLARSSL_MD_SHA384 )
{ {
handshake->tls_prf = tls_prf_sha384; handshake->tls_prf = tls_prf_sha384;
handshake->calc_verify = ssl_calc_verify_tls_sha384; handshake->calc_verify = ssl_calc_verify_tls_sha384;
handshake->calc_finished = ssl_calc_finished_tls_sha384; handshake->calc_finished = ssl_calc_finished_tls_sha384;
} }
#endif
else else
#endif
#if defined(POLARSSL_SHA256_C)
if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
{ {
handshake->tls_prf = tls_prf_sha256; handshake->tls_prf = tls_prf_sha256;
handshake->calc_verify = ssl_calc_verify_tls_sha256; handshake->calc_verify = ssl_calc_verify_tls_sha256;
handshake->calc_finished = ssl_calc_finished_tls_sha256; handshake->calc_finished = ssl_calc_finished_tls_sha256;
} }
else
#endif
#endif
/* Should never happen */
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
/* /*
* SSLv3: * SSLv3:
@ -437,7 +471,7 @@ int ssl_derive_keys( ssl_context *ssl )
* MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) + * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) +
* MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) ) * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
* *
* TLSv1: * TLSv1+:
* master = PRF( premaster, "master secret", randbytes )[0..47] * master = PRF( premaster, "master secret", randbytes )[0..47]
*/ */
if( handshake->resume == 0 ) if( handshake->resume == 0 )
@ -502,6 +536,8 @@ int ssl_derive_keys( ssl_context *ssl )
{ {
if( md_info->type != POLARSSL_MD_NONE ) if( md_info->type != POLARSSL_MD_NONE )
{ {
int ret;
if( ( ret = md_init_ctx( &transform->md_ctx_enc, md_info ) ) != 0 ) if( ( ret = md_init_ctx( &transform->md_ctx_enc, md_info ) ) != 0 )
{ {
SSL_DEBUG_RET( 1, "md_init_ctx", ret ); SSL_DEBUG_RET( 1, "md_init_ctx", ret );
@ -583,16 +619,25 @@ int ssl_derive_keys( ssl_context *ssl )
iv_copy_len ); iv_copy_len );
} }
#if defined(POLARSSL_SSL_PROTO_SSL3)
if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
{ {
memcpy( transform->mac_enc, mac_enc, transform->maclen ); memcpy( transform->mac_enc, mac_enc, transform->maclen );
memcpy( transform->mac_dec, mac_dec, transform->maclen ); memcpy( transform->mac_dec, mac_dec, transform->maclen );
} }
else 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_enc, mac_enc, transform->maclen );
md_hmac_starts( &transform->md_ctx_dec, mac_dec, 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 defined(POLARSSL_SSL_HW_RECORD_ACCEL)
if( ssl_hw_record_init != NULL) if( ssl_hw_record_init != NULL)
@ -701,6 +746,7 @@ int ssl_derive_keys( ssl_context *ssl )
return( 0 ); return( 0 );
} }
#if defined(POLARSSL_SSL_PROTO_SSL3)
void ssl_calc_verify_ssl( ssl_context *ssl, unsigned char hash[36] ) void ssl_calc_verify_ssl( ssl_context *ssl, unsigned char hash[36] )
{ {
md5_context md5; md5_context md5;
@ -741,7 +787,9 @@ void ssl_calc_verify_ssl( ssl_context *ssl, unsigned char hash[36] )
return; 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] ) void ssl_calc_verify_tls( ssl_context *ssl, unsigned char hash[36] )
{ {
md5_context md5; md5_context md5;
@ -760,7 +808,10 @@ void ssl_calc_verify_tls( ssl_context *ssl, unsigned char hash[36] )
return; 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] ) void ssl_calc_verify_tls_sha256( ssl_context *ssl, unsigned char hash[32] )
{ {
sha256_context sha256; sha256_context sha256;
@ -775,6 +826,7 @@ void ssl_calc_verify_tls_sha256( ssl_context *ssl, unsigned char hash[32] )
return; return;
} }
#endif /* POLARSSL_SHA256_C */
#if defined(POLARSSL_SHA512_C) #if defined(POLARSSL_SHA512_C)
void ssl_calc_verify_tls_sha384( ssl_context *ssl, unsigned char hash[48] ) 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; return;
} }
#endif #endif /* POLARSSL_SHA512_C */
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
#if defined(POLARSSL_SSL_PROTO_SSL3)
/* /*
* SSLv3.0 MAC functions * 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_update( md_ctx, buf + len, md_size );
md_finish( md_ctx, buf + len ); md_finish( md_ctx, buf + len );
} }
#endif /* POLARSSL_SSL_PROTO_SSL3 */
/* /*
* Encryption/decryption functions * Encryption/decryption functions
@ -846,6 +901,7 @@ static int ssl_encrypt_buf( ssl_context *ssl )
/* /*
* Add MAC then encrypt * Add MAC then encrypt
*/ */
#if defined(POLARSSL_SSL_PROTO_SSL3)
if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
{ {
ssl_mac( &ssl->transform_out->md_ctx_enc, 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 ); ssl->out_ctr, ssl->out_msgtype );
} }
else 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, ssl->out_ctr, 13 );
md_hmac_update( &ssl->transform_out->md_ctx_enc, 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 ); ssl->out_msg + ssl->out_msglen );
md_hmac_reset( &ssl->transform_out->md_ctx_enc ); 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_DEBUG_BUF( 4, "computed mac",
ssl->out_msg + ssl->out_msglen, ssl->transform_out->maclen ); 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_msglen = ssl->out_msglen;
enc_msg = ssl->out_msg; 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 * 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) * 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; enc_msglen = ssl->out_msglen;
ssl->out_msglen += ssl->transform_out->ivlen; 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, " SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
"including %d bytes of IV and %d bytes of padding", "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 ); 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 ) if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
minlen += ssl->transform_in->ivlen; minlen += ssl->transform_in->ivlen;
#endif
if( ssl->in_msglen < minlen + ssl->transform_in->ivlen || if( ssl->in_msglen < minlen + ssl->transform_in->ivlen ||
ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 ) 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 = ssl->in_msg;
dec_msg_result = 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 * 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++ ) for( i = 0; i < ssl->transform_in->ivlen; i++ )
ssl->transform_in->iv_dec[i] = ssl->in_iv[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 ) switch( ssl->transform_in->ciphersuite_info->cipher )
{ {
@ -1242,6 +1312,7 @@ static int ssl_decrypt_buf( ssl_context *ssl )
correct = 0; correct = 0;
} }
#if defined(POLARSSL_SSL_PROTO_SSL3)
if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
{ {
if( padlen > ssl->transform_in->ivlen ) if( padlen > ssl->transform_in->ivlen )
@ -1255,6 +1326,10 @@ static int ssl_decrypt_buf( ssl_context *ssl )
} }
} }
else 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 * TLSv1+: always check the padding up to the first failure
@ -1278,6 +1353,11 @@ static int ssl_decrypt_buf( ssl_context *ssl )
#endif #endif
padlen &= correct * 0x1FF; 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", 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 ); 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 ) if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
{ {
ssl_mac( &ssl->transform_in->md_ctx_dec, 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 ); ssl->in_ctr, ssl->in_msgtype );
} }
else 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 * 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 ); 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, "message mac", tmp, ssl->transform_in->maclen );
SSL_DEBUG_BUF( 4, "computed mac", ssl->in_msg + ssl->in_msglen, 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 ); return( POLARSSL_ERR_SSL_INVALID_RECORD );
} }
#if defined(POLARSSL_SSL_PROTO_SSL3)
if( ssl->minor_ver == SSL_MINOR_VERSION_0 && if( ssl->minor_ver == SSL_MINOR_VERSION_0 &&
ssl->in_msglen > ssl->transform_in->minlen + SSL_MAX_CONTENT_LEN ) ssl->in_msglen > ssl->transform_in->minlen + SSL_MAX_CONTENT_LEN )
{ {
SSL_DEBUG_MSG( 1, ( "bad message length" ) ); SSL_DEBUG_MSG( 1, ( "bad message length" ) );
return( POLARSSL_ERR_SSL_INVALID_RECORD ); 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 * 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" ) ); SSL_DEBUG_MSG( 1, ( "bad message length" ) );
return( POLARSSL_ERR_SSL_INVALID_RECORD ); return( POLARSSL_ERR_SSL_INVALID_RECORD );
} }
#endif
} }
/* /*
@ -2014,6 +2109,7 @@ int ssl_write_certificate( ssl_context *ssl )
return( 0 ); return( 0 );
} }
#if defined(POLARSSL_SSL_PROTO_SSL3)
/* /*
* If using SSLv3 and got no cert, send an Alert message * If using SSLv3 and got no cert, send an Alert message
* (otherwise an empty Certificate message will be sent). * (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" ) ); SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) );
goto write_msg; goto write_msg;
} }
#endif /* POLARSSL_SSL_PROTO_SSL3 */
} }
else /* SSL_IS_SERVER */ else /* SSL_IS_SERVER */
{ {
@ -2079,7 +2176,9 @@ int ssl_write_certificate( ssl_context *ssl )
ssl->out_msgtype = SSL_MSG_HANDSHAKE; ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_CERTIFICATE; ssl->out_msg[0] = SSL_HS_CERTIFICATE;
#if defined(POLARSSL_SSL_PROTO_SSL3)
write_msg: write_msg:
#endif
ssl->state++; ssl->state++;
@ -2127,6 +2226,7 @@ int ssl_parse_certificate( ssl_context *ssl )
ssl->state++; ssl->state++;
#if defined(POLARSSL_SSL_PROTO_SSL3)
/* /*
* Check if the client sent an empty certificate * 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 ); 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 && if( ssl->endpoint == SSL_IS_SERVER &&
ssl->minor_ver != SSL_MINOR_VERSION_0 ) ssl->minor_ver != SSL_MINOR_VERSION_0 )
{ {
@ -2165,6 +2268,8 @@ int ssl_parse_certificate( ssl_context *ssl )
return( 0 ); return( 0 );
} }
} }
#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \
POLARSSL_SSL_PROTO_TLS1_2 */
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) 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, void ssl_optimize_checksum( ssl_context *ssl,
const ssl_ciphersuite_t *ciphersuite_info ) const ssl_ciphersuite_t *ciphersuite_info )
{ {
#if !defined(POLARSSL_SHA512_C)
((void) ciphersuite_info); ((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 ) if( ssl->minor_ver < SSL_MINOR_VERSION_3 )
ssl->handshake->update_checksum = ssl_update_checksum_md5sha1; 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 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; 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, static void ssl_update_checksum_start( ssl_context *ssl,
const unsigned char *buf, size_t len ) 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 ); md5_update( &ssl->handshake->fin_md5 , buf, len );
sha1_update( &ssl->handshake->fin_sha1, 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 ); sha256_update( &ssl->handshake->fin_sha256, buf, len );
#endif
#if defined(POLARSSL_SHA512_C) #if defined(POLARSSL_SHA512_C)
sha512_update( &ssl->handshake->fin_sha512, buf, len ); sha512_update( &ssl->handshake->fin_sha512, buf, len );
#endif #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, static void ssl_update_checksum_md5sha1( ssl_context *ssl,
const unsigned char *buf, size_t len ) const unsigned char *buf, size_t len )
{ {
md5_update( &ssl->handshake->fin_md5 , buf, len ); md5_update( &ssl->handshake->fin_md5 , buf, len );
sha1_update( &ssl->handshake->fin_sha1, 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, static void ssl_update_checksum_sha256( ssl_context *ssl,
const unsigned char *buf, size_t len ) const unsigned char *buf, size_t len )
{ {
sha256_update( &ssl->handshake->fin_sha256, buf, len ); sha256_update( &ssl->handshake->fin_sha256, buf, len );
} }
#endif
#if defined(POLARSSL_SHA512_C) #if defined(POLARSSL_SHA512_C)
static void ssl_update_checksum_sha384( ssl_context *ssl, 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 ); sha512_update( &ssl->handshake->fin_sha512, buf, len );
} }
#endif #endif
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
#if defined(POLARSSL_SSL_PROTO_SSL3)
static void ssl_calc_finished_ssl( static void ssl_calc_finished_ssl(
ssl_context *ssl, unsigned char *buf, int from ) ssl_context *ssl, unsigned char *buf, int from )
{ {
@ -2444,7 +2572,9 @@ static void ssl_calc_finished_ssl(
SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); 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( static void ssl_calc_finished_tls(
ssl_context *ssl, unsigned char *buf, int from ) ssl_context *ssl, unsigned char *buf, int from )
{ {
@ -2498,7 +2628,10 @@ static void ssl_calc_finished_tls(
SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); 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( static void ssl_calc_finished_tls_sha256(
ssl_context *ssl, unsigned char *buf, int from ) 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" ) ); SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
} }
#endif /* POLARSSL_SHA256_C */
#if defined(POLARSSL_SHA512_C) #if defined(POLARSSL_SHA512_C)
static void ssl_calc_finished_tls_sha384( static void ssl_calc_finished_tls_sha384(
@ -2589,7 +2723,8 @@ static void ssl_calc_finished_tls_sha384(
SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
} }
#endif #endif /* POLARSSL_SHA512_C */
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
void ssl_handshake_wrapup( ssl_context *ssl ) 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->transform_negotiate, 0, sizeof(ssl_transform) );
memset( ssl->session_negotiate, 0, sizeof(ssl_session) ); 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 ); md5_starts( &ssl->handshake->fin_md5 );
sha1_starts( &ssl->handshake->fin_sha1 ); 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 ); sha256_starts( &ssl->handshake->fin_sha256, 0 );
#endif
#if defined(POLARSSL_SHA512_C) #if defined(POLARSSL_SHA512_C)
sha512_starts( &ssl->handshake->fin_sha512, 1 ); sha512_starts( &ssl->handshake->fin_sha512, 1 );
#endif #endif
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
ssl->handshake->update_checksum = ssl_update_checksum_start; ssl->handshake->update_checksum = ssl_update_checksum_start;
ssl->handshake->sig_alg = SSL_HASH_SHA1; 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; ssl->rsa_key_len = ssl_rsa_key_len;
#endif #endif
ssl->min_major_ver = SSL_MAJOR_VERSION_3; ssl->min_major_ver = SSL_MIN_MAJOR_VERSION;
ssl->min_minor_ver = SSL_MINOR_VERSION_0; ssl->min_minor_ver = SSL_MIN_MINOR_VERSION;
ssl->max_major_ver = SSL_MAJOR_VERSION_3; ssl->max_major_ver = SSL_MAX_MAJOR_VERSION;
ssl->max_minor_ver = SSL_MINOR_VERSION_3; ssl->max_minor_ver = SSL_MAX_MINOR_VERSION;
ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() ); 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 ) void ssl_set_max_version( ssl_context *ssl, int major, int 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_major_ver = major;
ssl->max_minor_ver = minor; ssl->max_minor_ver = minor;
}
} }
void ssl_set_min_version( ssl_context *ssl, int major, int minor ) void ssl_set_min_version( ssl_context *ssl, int major, int 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_major_ver = major;
ssl->min_minor_ver = minor; ssl->min_minor_ver = minor;
}
} }
#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) #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" ) ); SSL_DEBUG_MSG( 3, ( "ignoring renegotiation, sending alert" ) );
#if defined(POLARSSL_SSL_PROTO_SSL3)
if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) 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 ); return( ret );
} }
else 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, if( ( ret = ssl_send_alert_message( ssl,
SSL_ALERT_LEVEL_WARNING, SSL_ALERT_LEVEL_WARNING,
@ -3533,6 +3688,10 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
return( ret ); return( ret );
} }
} }
else
#endif
/* Should never happen */
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
} }
else else
{ {