diff --git a/include/polarssl/config.h b/include/polarssl/config.h index 22faf0438..bb88ea9b4 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -528,6 +528,15 @@ */ #define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO +/** + * \def POLARSSL_SSL_MAX_FRAGMENT_LENGTH + * + * Enable support for RFC 6066 max_fragment_length extension in SSL + * + * Comment this macro to disable support for the max_fragment_length extension + */ +#define POLARSSL_SSL_MAX_FRAGMENT_LENGTH + /** * \def POLARSSL_SSL_SESSION_TICKETS * diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index ed11e1e4a..d0e71e392 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -362,7 +362,10 @@ struct _ssl_session uint32_t ticket_lifetime; /*!< ticket lifetime hint */ #endif /* POLARSSL_SSL_SESSION_TICKETS */ +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) unsigned char mfl_code; /*!< MaxFragmentLength negotiated by peer */ +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + int trunc_hmac; /*!< flag for truncated hmac activation */ }; @@ -560,7 +563,9 @@ struct _ssl_context size_t out_msglen; /*!< record header: message length */ size_t out_left; /*!< amount of data not yet written */ +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) unsigned char mfl_code; /*!< MaxFragmentLength chosen by us */ +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ /* * PKI layer @@ -1025,6 +1030,7 @@ void ssl_set_max_version( ssl_context *ssl, int major, int minor ); */ void ssl_set_min_version( ssl_context *ssl, int major, int minor ); +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) /** * \brief Set the maximum fragment length to emit and/or negotiate * (Default: SSL_MAX_CONTENT_LEN, usually 2^14 bytes) @@ -1041,6 +1047,7 @@ void ssl_set_min_version( ssl_context *ssl, int major, int minor ); * \return O if successful or POLARSSL_ERR_SSL_BAD_INPUT_DATA */ int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code ); +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ /** * \brief Activate negotiation of truncated HMAC (Client only) diff --git a/library/ssl_cli.c b/library/ssl_cli.c index ac728324f..772b2c983 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -276,6 +276,7 @@ static void ssl_write_supported_point_formats_ext( ssl_context *ssl, } #endif +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) static void ssl_write_max_fragment_length_ext( ssl_context *ssl, unsigned char *buf, size_t *olen ) @@ -299,6 +300,7 @@ static void ssl_write_max_fragment_length_ext( ssl_context *ssl, *olen = 5; } +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ static void ssl_write_truncated_hmac_ext( ssl_context *ssl, unsigned char *buf, size_t *olen ) @@ -546,8 +548,10 @@ static int ssl_write_client_hello( ssl_context *ssl ) ext_len += olen; #endif +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; +#endif ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; @@ -621,6 +625,7 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl, return( 0 ); } +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) static int ssl_parse_max_fragment_length_ext( ssl_context *ssl, const unsigned char *buf, size_t len ) @@ -638,6 +643,7 @@ static int ssl_parse_max_fragment_length_ext( ssl_context *ssl, return( 0 ); } +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ static int ssl_parse_truncated_hmac_ext( ssl_context *ssl, const unsigned char *buf, @@ -891,6 +897,7 @@ static int ssl_parse_server_hello( ssl_context *ssl ) break; +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) case TLS_EXT_MAX_FRAGMENT_LENGTH: SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) ); @@ -901,6 +908,7 @@ static int ssl_parse_server_hello( ssl_context *ssl ) } break; +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ case TLS_EXT_TRUNCATED_HMAC: SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) ); diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 7de15779a..ff0e9d1f5 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -564,6 +564,7 @@ static int ssl_parse_supported_point_formats( ssl_context *ssl, } #endif /* POLARSSL_ECP_C */ +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) static int ssl_parse_max_fragment_length_ext( ssl_context *ssl, const unsigned char *buf, size_t len ) @@ -578,6 +579,7 @@ static int ssl_parse_max_fragment_length_ext( ssl_context *ssl, return( 0 ); } +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ static int ssl_parse_truncated_hmac_ext( ssl_context *ssl, const unsigned char *buf, @@ -1174,6 +1176,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) break; #endif /* POLARSSL_ECP_C */ +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) case TLS_EXT_MAX_FRAGMENT_LENGTH: SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) ); @@ -1181,6 +1184,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) if( ret != 0 ) return( ret ); break; +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ case TLS_EXT_TRUNCATED_HMAC: SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) ); @@ -1386,6 +1390,7 @@ static void ssl_write_renegotiation_ext( ssl_context *ssl, *olen = 5 + ssl->verify_data_len * 2; } +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) static void ssl_write_max_fragment_length_ext( ssl_context *ssl, unsigned char *buf, size_t *olen ) @@ -1410,6 +1415,7 @@ static void ssl_write_max_fragment_length_ext( ssl_context *ssl, *olen = 5; } +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ static int ssl_write_server_hello( ssl_context *ssl ) { @@ -1551,8 +1557,10 @@ static int ssl_write_server_hello( ssl_context *ssl ) ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; +#endif ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; diff --git a/library/ssl_tls.c b/library/ssl_tls.c index bb605b91a..1281bc827 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -59,6 +59,7 @@ #define strcasecmp _stricmp #endif +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) /* * Convert max_fragment_length codes to length. * RFC 6066 says: @@ -75,6 +76,7 @@ static unsigned int mfl_code_to_length[SSL_MAX_FRAG_LEN_INVALID] = 2048, /* SSL_MAX_FRAG_LEN_2048 */ 4096, /* SSL_MAX_FRAG_LEN_4096 */ }; +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ static int ssl_session_copy( ssl_session *dst, const ssl_session *src ) { @@ -3238,6 +3240,7 @@ void ssl_set_min_version( ssl_context *ssl, int major, int minor ) ssl->min_minor_ver = minor; } +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code ) { if( mfl_code >= sizeof( mfl_code_to_length ) || @@ -3250,6 +3253,7 @@ int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code ) return( 0 ); } +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ int ssl_set_truncated_hmac( ssl_context *ssl, int truncate ) { @@ -3555,7 +3559,7 @@ int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len ) { int ret; size_t n; - unsigned int max_len; + unsigned int max_len = SSL_MAX_CONTENT_LEN; SSL_DEBUG_MSG( 2, ( "=> write" ) ); @@ -3568,19 +3572,21 @@ int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len ) } } +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) /* * Assume mfl_code is correct since it was checked when set */ max_len = mfl_code_to_length[ssl->mfl_code]; /* - * Check if a smaller max length was negociated + * Check if a smaller max length was negotiated */ if( ssl->session_out != NULL && mfl_code_to_length[ssl->session_out->mfl_code] < max_len ) { max_len = mfl_code_to_length[ssl->session_out->mfl_code]; } +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ n = ( len < max_len) ? len : max_len; diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 291795f0d..a422bf43a 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -185,6 +185,14 @@ static int my_verify( void *data, x509_cert *crt, int depth, int *flags ) #define USAGE_TICKETS "" #endif /* POLARSSL_SSL_SESSION_TICKETS */ +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) +#define USAGE_MAX_FRAG_LEN \ + " max_frag_len=%%d default: 16384 (tls default)\n" \ + " options: 512, 1024, 2048, 4096\n" +#else +#define USAGE_MAX_FRAG_LEN "" +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + #define USAGE \ "\n usage: ssl_client2 param=<>...\n" \ "\n acceptable parameters:\n" \ @@ -204,8 +212,7 @@ static int my_verify( void *data, x509_cert *crt, int depth, int *flags ) " options: ssl3, tls1, tls1_1, tls1_2\n" \ " auth_mode=%%s default: \"optional\"\n" \ " options: none, optional, required\n" \ - " max_frag_len=%%d default: 16384 (tls default)\n" \ - " options: 512, 1024, 2048, 4096\n" \ + USAGE_MAX_FRAG_LEN \ " trunc_hmac=%%d default: 0 (disabled)\n" \ USAGE_PSK \ "\n" \ @@ -671,7 +678,9 @@ int main( int argc, char *argv[] ) ssl_set_endpoint( &ssl, SSL_IS_CLIENT ); ssl_set_authmode( &ssl, opt.auth_mode ); +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) ssl_set_max_frag_len( &ssl, opt.mfl_code ); +#endif if( opt.trunc_hmac != 0 ) ssl_set_truncated_hmac( &ssl, SSL_TRUNC_HMAC_ENABLED ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index aca0db526..681850bee 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -153,6 +153,14 @@ static void my_debug( void *ctx, int level, const char *str ) #define USAGE_TICKETS "" #endif /* POLARSSL_SSL_SESSION_TICKETS */ +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) +#define USAGE_MAX_FRAG_LEN \ + " max_frag_len=%%d default: 16384 (tls default)\n" \ + " options: 512, 1024, 2048, 4096\n" +#else +#define USAGE_MAX_FRAG_LEN "" +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + #define USAGE \ "\n usage: ssl_server2 param=<>...\n" \ "\n acceptable parameters:\n" \ @@ -169,8 +177,7 @@ static void my_debug( void *ctx, int level, const char *str ) " options: ssl3, tls1, tls1_1, tls1_2\n" \ " auth_mode=%%s default: \"optional\"\n" \ " options: none, optional, required\n" \ - " max_frag_len=%%d default: 16384 (tls default)\n" \ - " options: 512, 1024, 2048, 4096\n" \ + USAGE_MAX_FRAG_LEN \ USAGE_PSK \ "\n" \ " force_ciphersuite= default: all enabled\n"\ @@ -618,7 +625,9 @@ int main( int argc, char *argv[] ) ssl_set_endpoint( &ssl, SSL_IS_SERVER ); ssl_set_authmode( &ssl, opt.auth_mode ); +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) ssl_set_max_frag_len( &ssl, opt.mfl_code ); +#endif ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg ); ssl_set_dbg( &ssl, my_debug, stdout );