mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-10-30 03:00:21 -04:00 
			
		
		
		
	Start adding srv support for hello verify request
Dummy fixed content for now. Also, seems to be a race condition in the way the socket is closed and reopened, leading to a few "random" failures in compat.sh. A fix is planned for later.
This commit is contained in:
		
							parent
							
								
									a0e1632b79
								
							
						
					
					
						commit
						2c9ee81f6e
					
				| @ -146,6 +146,7 @@ | |||||||
| #define POLARSSL_ERR_SSL_INTERNAL_ERROR                    -0x6C00  /**< Internal error (eg, unexpected failure in lower-level module) */ | #define POLARSSL_ERR_SSL_INTERNAL_ERROR                    -0x6C00  /**< Internal error (eg, unexpected failure in lower-level module) */ | ||||||
| #define POLARSSL_ERR_SSL_COUNTER_WRAPPING                  -0x6B80  /**< A counter would wrap (eg, too many messages exchanged). */ | #define POLARSSL_ERR_SSL_COUNTER_WRAPPING                  -0x6B80  /**< A counter would wrap (eg, too many messages exchanged). */ | ||||||
| #define POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO       -0x6B00  /**< Unexpected message at ServerHello in renegotiation. */ | #define POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO       -0x6B00  /**< Unexpected message at ServerHello in renegotiation. */ | ||||||
|  | #define POLARSSL_ERR_SSL_HELLO_VERIFY_REQUIRED             -0x6A80  /**< DTLS client must retry for hello verification */ | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Various constants |  * Various constants | ||||||
|  | |||||||
| @ -452,6 +452,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) | |||||||
|             snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" ); |             snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" ); | ||||||
|         if( use_ret == -(POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) ) |         if( use_ret == -(POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) ) | ||||||
|             snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" ); |             snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" ); | ||||||
|  |         if( use_ret == -(POLARSSL_ERR_SSL_HELLO_VERIFY_REQUIRED) ) | ||||||
|  |             snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" ); | ||||||
| #endif /* POLARSSL_SSL_TLS_C */ | #endif /* POLARSSL_SSL_TLS_C */ | ||||||
| 
 | 
 | ||||||
| #if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) | #if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) | ||||||
|  | |||||||
| @ -1116,6 +1116,34 @@ have_ciphersuite_v2: | |||||||
| } | } | ||||||
| #endif /* POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ | #endif /* POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ | ||||||
| 
 | 
 | ||||||
|  | #if defined(POLARSSL_SSL_PROTO_DTLS) | ||||||
|  | /*
 | ||||||
|  |  * Generate cookie for DTLS ClientHello verification | ||||||
|  |  */ | ||||||
|  | static int ssl_generate_verify_cookie( ssl_context *ssl ) | ||||||
|  | { | ||||||
|  |     unsigned char *cookie = ssl->handshake->verify_cookie; | ||||||
|  |     unsigned char cookie_len; | ||||||
|  | 
 | ||||||
|  |     polarssl_free( cookie ); | ||||||
|  | 
 | ||||||
|  |     cookie_len = 16; /* fixed for now */ | ||||||
|  |     if( ( cookie = polarssl_malloc( cookie_len ) ) == NULL ) | ||||||
|  |     { | ||||||
|  |         SSL_DEBUG_MSG( 1, ( "malloc (%d bytes) failed\n", cookie_len ) ); | ||||||
|  |         return( POLARSSL_ERR_SSL_MALLOC_FAILED ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Dummy, fixed string for now */ | ||||||
|  |     memset( cookie, 0x2a, cookie_len ); | ||||||
|  | 
 | ||||||
|  |     ssl->handshake->verify_cookie = cookie; | ||||||
|  |     ssl->handshake->verify_cookie_len = cookie_len; | ||||||
|  | 
 | ||||||
|  |     return( 0 ); | ||||||
|  | } | ||||||
|  | #endif /* POLARSSL_SSL_PROTO_DTLS */ | ||||||
|  | 
 | ||||||
| static int ssl_parse_client_hello( ssl_context *ssl ) | static int ssl_parse_client_hello( ssl_context *ssl ) | ||||||
| { | { | ||||||
|     int ret; |     int ret; | ||||||
| @ -1161,6 +1189,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) | |||||||
|      * Record layer: |      * Record layer: | ||||||
|      *     0  .   0   message type |      *     0  .   0   message type | ||||||
|      *     1  .   2   protocol version |      *     1  .   2   protocol version | ||||||
|  |      *     3  .   11  DTLS: epoch + record sequence number | ||||||
|      *     3  .   4   message length |      *     3  .   4   message length | ||||||
|      */ |      */ | ||||||
|     SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d", |     SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d", | ||||||
| @ -1190,6 +1219,23 @@ static int ssl_parse_client_hello( ssl_context *ssl ) | |||||||
|         return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); |         return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /* For DTLS if this is the initial handshake, remember the client sequence
 | ||||||
|  |      * number to use it in our next message (RFC 6347 4.2.1) */ | ||||||
|  | #if defined(POLARSSL_SSL_PROTO_DTLS) | ||||||
|  |     if( ssl->transport == SSL_TRANSPORT_DATAGRAM && | ||||||
|  |         ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) | ||||||
|  |     { | ||||||
|  |         /* Epoch should be 0 for initial handshakes */ | ||||||
|  |         if( ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0 ) | ||||||
|  |         { | ||||||
|  |             SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); | ||||||
|  |             return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         memcpy( ssl->out_ctr + 2, ssl->in_ctr + 2, 6 ); | ||||||
|  |     } | ||||||
|  | #endif /* POLARSSL_SSL_PROTO_DTLS */ | ||||||
|  | 
 | ||||||
|     msg_len = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; |     msg_len = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; | ||||||
| 
 | 
 | ||||||
|     if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) |     if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) | ||||||
| @ -1232,7 +1278,14 @@ static int ssl_parse_client_hello( ssl_context *ssl ) | |||||||
|             return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); |             return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // TODO: DTLS: check message_seq
 |         /*
 | ||||||
|  |          * Copy the client's handshake message_seq on initial handshakes | ||||||
|  |          */ | ||||||
|  |         if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) | ||||||
|  |             ssl->handshake->msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; | ||||||
|  | 
 | ||||||
|  |         // TODO: DTLS: check message_seq on non-initial handshakes?
 | ||||||
|  |         // (or already done in ssl_read_record?)
 | ||||||
| 
 | 
 | ||||||
|         /*
 |         /*
 | ||||||
|          * For now we don't support fragmentation, so make sure |          * For now we don't support fragmentation, so make sure | ||||||
| @ -1376,8 +1429,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) | |||||||
|         cookie_offset = 39 + sess_len; |         cookie_offset = 39 + sess_len; | ||||||
|         cookie_len = buf[cookie_offset]; |         cookie_len = buf[cookie_offset]; | ||||||
| 
 | 
 | ||||||
|         if( // cookie_len > <MAX> || // TODO-DTLS
 |         if( cookie_offset + 1 + cookie_len + 2 > msg_len ) | ||||||
|             cookie_offset + 1 + cookie_len + 2 > msg_len ) |  | ||||||
|         { |         { | ||||||
|             SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |             SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); | ||||||
|             return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); |             return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); | ||||||
| @ -1386,9 +1438,34 @@ static int ssl_parse_client_hello( ssl_context *ssl ) | |||||||
|         SSL_DEBUG_BUF( 3, "client hello, cookie", |         SSL_DEBUG_BUF( 3, "client hello, cookie", | ||||||
|                        buf + cookie_offset + 1, cookie_len ); |                        buf + cookie_offset + 1, cookie_len ); | ||||||
| 
 | 
 | ||||||
|         // TODO-DTLS: check cookie, reject if invalid!
 |         /*
 | ||||||
|  |          * Generate reference cookie content: | ||||||
|  |          * - used for verification below, | ||||||
|  |          * - stored to be sent if verification fails | ||||||
|  |          */ | ||||||
|  |         if( ( ret = ssl_generate_verify_cookie( ssl ) ) != 0 ) | ||||||
|  |         { | ||||||
|  |             SSL_DEBUG_RET( 1, "ssl_generate_verify_cookie", ret ); | ||||||
|  |             return( ret ); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /* If the received cookie is OK, no need to send one */ | ||||||
|  |         if( cookie_len == ssl->handshake->verify_cookie_len && | ||||||
|  |             safer_memcmp( buf + cookie_offset + 1, | ||||||
|  |                           ssl->handshake->verify_cookie, | ||||||
|  |                           ssl->handshake->verify_cookie_len ) == 0 ) | ||||||
|  |         { | ||||||
|  |             polarssl_free( ssl->handshake->verify_cookie ); | ||||||
|  |             ssl->handshake->verify_cookie = NULL; | ||||||
|  |             ssl->handshake->verify_cookie_len = 0; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         SSL_DEBUG_MSG( 2, ( "client hello, cookie verification %s", | ||||||
|  |                             ssl->handshake->verify_cookie == NULL ? | ||||||
|  |                             "passed" : "failed" ) ); | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| #endif | #endif /* POLARSSL_SSL_PROTO_DTLS */ | ||||||
| 
 | 
 | ||||||
|     /*
 |     /*
 | ||||||
|      * Check the ciphersuitelist length (will be parsed later) |      * Check the ciphersuitelist length (will be parsed later) | ||||||
| @ -1883,6 +1960,52 @@ static void ssl_write_alpn_ext( ssl_context *ssl, | |||||||
| } | } | ||||||
| #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ | #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ | ||||||
| 
 | 
 | ||||||
|  | #if defined(POLARSSL_SSL_PROTO_DTLS) | ||||||
|  | static int ssl_write_hello_verify_request( ssl_context *ssl ) | ||||||
|  | { | ||||||
|  |     int ret; | ||||||
|  |     unsigned char *p = ssl->out_msg + 4; | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_MSG( 2, ( "=> write hello verify request" ) ); | ||||||
|  | 
 | ||||||
|  |     /*
 | ||||||
|  |      * struct { | ||||||
|  |      *   ProtocolVersion server_version; | ||||||
|  |      *   opaque cookie<0..2^8-1>; | ||||||
|  |      * } HelloVerifyRequest; | ||||||
|  |      */ | ||||||
|  | 
 | ||||||
|  |     /* For now, use fixed version = DTLS 1.0 */ | ||||||
|  |     ssl_write_version( SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, | ||||||
|  |                        ssl->transport, p ); | ||||||
|  |     SSL_DEBUG_BUF( 3, "server version", (unsigned char *) p, 2 ); | ||||||
|  |     p += 2; | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_BUF( 3, "cookie", ssl->handshake->verify_cookie, | ||||||
|  |                                 ssl->handshake->verify_cookie_len ); | ||||||
|  |     *p++ = ssl->handshake->verify_cookie_len; | ||||||
|  |     memcpy( p, ssl->handshake->verify_cookie, | ||||||
|  |                ssl->handshake->verify_cookie_len ); | ||||||
|  |     p += ssl->handshake->verify_cookie_len; | ||||||
|  | 
 | ||||||
|  |     ssl->out_msglen  = p - ssl->out_msg; | ||||||
|  |     ssl->out_msgtype = SSL_MSG_HANDSHAKE; | ||||||
|  |     ssl->out_msg[0]  = SSL_HS_HELLO_VERIFY_REQUEST; | ||||||
|  | 
 | ||||||
|  |     ssl->state = SSL_CLIENT_HELLO; | ||||||
|  | 
 | ||||||
|  |     if( ( ret = ssl_write_record( ssl ) ) != 0 ) | ||||||
|  |     { | ||||||
|  |         SSL_DEBUG_RET( 1, "ssl_write_record", ret ); | ||||||
|  |         return( ret ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_MSG( 2, ( "<= write hello verify request" ) ); | ||||||
|  | 
 | ||||||
|  |     return( 0 ); | ||||||
|  | } | ||||||
|  | #endif /* POLARSSL_SSL_PROTO_DTLS */ | ||||||
|  | 
 | ||||||
| static int ssl_write_server_hello( ssl_context *ssl ) | static int ssl_write_server_hello( ssl_context *ssl ) | ||||||
| { | { | ||||||
| #if defined(POLARSSL_HAVE_TIME) | #if defined(POLARSSL_HAVE_TIME) | ||||||
| @ -1894,6 +2017,23 @@ static int ssl_write_server_hello( ssl_context *ssl ) | |||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_MSG( 2, ( "=> write server hello" ) ); |     SSL_DEBUG_MSG( 2, ( "=> write server hello" ) ); | ||||||
| 
 | 
 | ||||||
|  | #if defined(POLARSSL_SSL_PROTO_DTLS) | ||||||
|  |     if( ssl->transport == SSL_TRANSPORT_DATAGRAM && | ||||||
|  |         ssl->handshake->verify_cookie != NULL ) | ||||||
|  |     { | ||||||
|  |         SSL_DEBUG_MSG( 2, ( "client hello was not authenticated" ) ); | ||||||
|  |         SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); | ||||||
|  | 
 | ||||||
|  |         if( ( ret = ssl_write_hello_verify_request( ssl ) ) != 0 ) | ||||||
|  |         { | ||||||
|  |             SSL_DEBUG_RET( 1, "ssl_write_hello_verify_request", ret ); | ||||||
|  |             return( ret ); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return( POLARSSL_ERR_SSL_HELLO_VERIFY_REQUIRED ); | ||||||
|  |     } | ||||||
|  | #endif /* POLARSSL_SSL_PROTO_DTLS */ | ||||||
|  | 
 | ||||||
|     if( ssl->f_rng == NULL ) |     if( ssl->f_rng == NULL ) | ||||||
|     { |     { | ||||||
|         SSL_DEBUG_MSG( 1, ( "no RNG provided") ); |         SSL_DEBUG_MSG( 1, ( "no RNG provided") ); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Manuel Pégourié-Gonnard
						Manuel Pégourié-Gonnard