diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 5b4e36f2f..e9e33e357 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -124,6 +124,7 @@ #define SSL_MAX_FRAG_LEN_1024 2 /*!< MaxFragmentLength 2^10 */ #define SSL_MAX_FRAG_LEN_2048 3 /*!< MaxFragmentLength 2^11 */ #define SSL_MAX_FRAG_LEN_4096 4 /*!< MaxFragmentLength 2^12 */ +#define SSL_MAX_FRAG_LEN_INVALID 5 /*!< first invalid value */ #define SSL_IS_CLIENT 0 #define SSL_IS_SERVER 1 @@ -330,6 +331,8 @@ struct _ssl_session #if defined(POLARSSL_X509_PARSE_C) x509_cert *peer_cert; /*!< peer X.509 cert chain */ #endif /* POLARSSL_X509_PARSE_C */ + + unsigned char mfl_code; /*!< MaxFragmentLength negotiated by peer */ }; /* @@ -508,8 +511,7 @@ struct _ssl_context size_t out_msglen; /*!< record header: message length */ size_t out_left; /*!< amount of data not yet written */ - /* Maximum fragment length extension (RFC 6066 section 4) */ - unsigned char mfl_code; /*!< numerical code for MaxFragmentLength */ + unsigned char mfl_code; /*!< MaxFragmentLength chosen by us */ /* * PKI layer diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 2177253f3..abcc867dd 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -295,15 +295,14 @@ static int ssl_parse_max_fragment_length_ext( ssl_context *ssl, const unsigned char *buf, size_t len ) { - int ret; - - if( len != 1 || - ( ret = ssl_set_max_frag_len( ssl, buf[0] ) ) != 0 ) + if( len != 1 || buf[0] >= SSL_MAX_FRAG_LEN_INVALID ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } + ssl->session_negotiate->mfl_code = buf[0]; + return( 0 ); } @@ -993,7 +992,7 @@ static void ssl_write_max_fragment_length_ext( ssl_context *ssl, { unsigned char *p = buf; - if( ssl->mfl_code == SSL_MAX_FRAG_LEN_NONE ) { + if( ssl->session_negotiate->mfl_code == SSL_MAX_FRAG_LEN_NONE ) { *olen = 0; return; } @@ -1006,7 +1005,7 @@ static void ssl_write_max_fragment_length_ext( ssl_context *ssl, *p++ = 0x00; *p++ = 1; - *p++ = ssl->mfl_code; + *p++ = ssl->session_negotiate->mfl_code; *olen = 5; } diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 0374ee818..a230dc939 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -67,7 +67,7 @@ * } MaxFragmentLength; * and we add 0 -> extension unused */ -static unsigned int mfl_code_to_length[] = +static unsigned int mfl_code_to_length[SSL_MAX_FRAG_LEN_INVALID] = { SSL_MAX_CONTENT_LEN, /* SSL_MAX_FRAG_LEN_NONE */ 512, /* SSL_MAX_FRAG_LEN_512 */ @@ -2886,8 +2886,6 @@ int ssl_session_reset( ssl_context *ssl ) ssl->out_msglen = 0; ssl->out_left = 0; - ssl->mfl_code = SSL_MAX_FRAG_LEN_NONE; - ssl->transform_in = NULL; ssl->transform_out = NULL; @@ -3424,6 +3422,15 @@ int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len ) */ max_len = mfl_code_to_length[ssl->mfl_code]; + /* + * Check if a smaller max length was negociated + */ + 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]; + } + n = ( len < max_len) ? len : max_len; if( ssl->out_left != 0 )