|  | @@ -162,6 +162,14 @@ FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			| 162 | 162 |  #define EINFO_EPERM_CLIENT_CERT						\
 | 
		
	
		
			
			| 163 | 163 |  	__einfo_uniqify ( EINFO_EPERM, 0x03,				\
 | 
		
	
		
			
			| 164 | 164 |  			  "No suitable client certificate available" )
 | 
		
	
		
			
			|  | 165 | +#define EPERM_RENEG_INSECURE __einfo_error ( EINFO_EPERM_RENEG_INSECURE )
 | 
		
	
		
			
			|  | 166 | +#define EINFO_EPERM_RENEG_INSECURE					\
 | 
		
	
		
			
			|  | 167 | +	__einfo_uniqify ( EINFO_EPERM, 0x04,				\
 | 
		
	
		
			
			|  | 168 | +			  "Secure renegotiation not supported" )
 | 
		
	
		
			
			|  | 169 | +#define EPERM_RENEG_VERIFY __einfo_error ( EINFO_EPERM_RENEG_VERIFY )
 | 
		
	
		
			
			|  | 170 | +#define EINFO_EPERM_RENEG_VERIFY					\
 | 
		
	
		
			
			|  | 171 | +	__einfo_uniqify ( EINFO_EPERM, 0x05,				\
 | 
		
	
		
			
			|  | 172 | +			  "Secure renegotiation verification failed" )
 | 
		
	
		
			
			| 165 | 173 |  #define EPROTO_VERSION __einfo_error ( EINFO_EPROTO_VERSION )
 | 
		
	
		
			
			| 166 | 174 |  #define EINFO_EPROTO_VERSION						\
 | 
		
	
		
			
			| 167 | 175 |  	__einfo_uniqify ( EINFO_EPROTO, 0x01,				\
 | 
		
	
	
		
			
			|  | @@ -887,6 +895,30 @@ static void tls_verify_handshake ( struct tls_session *tls, void *out ) {
 | 
		
	
		
			
			| 887 | 895 |   ******************************************************************************
 | 
		
	
		
			
			| 888 | 896 |   */
 | 
		
	
		
			
			| 889 | 897 |  
 | 
		
	
		
			
			|  | 898 | +/**
 | 
		
	
		
			
			|  | 899 | + * Restart negotiation
 | 
		
	
		
			
			|  | 900 | + *
 | 
		
	
		
			
			|  | 901 | + * @v tls		TLS session
 | 
		
	
		
			
			|  | 902 | + */
 | 
		
	
		
			
			|  | 903 | +static void tls_restart ( struct tls_session *tls ) {
 | 
		
	
		
			
			|  | 904 | +
 | 
		
	
		
			
			|  | 905 | +	/* Sanity check */
 | 
		
	
		
			
			|  | 906 | +	assert ( ! tls->tx_pending );
 | 
		
	
		
			
			|  | 907 | +	assert ( ! is_pending ( &tls->client_negotiation ) );
 | 
		
	
		
			
			|  | 908 | +	assert ( ! is_pending ( &tls->server_negotiation ) );
 | 
		
	
		
			
			|  | 909 | +
 | 
		
	
		
			
			|  | 910 | +	/* (Re)initialise handshake context */
 | 
		
	
		
			
			|  | 911 | +	digest_init ( &md5_sha1_algorithm, tls->handshake_md5_sha1_ctx );
 | 
		
	
		
			
			|  | 912 | +	digest_init ( &sha256_algorithm, tls->handshake_sha256_ctx );
 | 
		
	
		
			
			|  | 913 | +	tls->handshake_digest = &sha256_algorithm;
 | 
		
	
		
			
			|  | 914 | +	tls->handshake_ctx = tls->handshake_sha256_ctx;
 | 
		
	
		
			
			|  | 915 | +
 | 
		
	
		
			
			|  | 916 | +	/* (Re)start negotiation */
 | 
		
	
		
			
			|  | 917 | +	tls->tx_pending = TLS_TX_CLIENT_HELLO;
 | 
		
	
		
			
			|  | 918 | +	pending_get ( &tls->client_negotiation );
 | 
		
	
		
			
			|  | 919 | +	pending_get ( &tls->server_negotiation );
 | 
		
	
		
			
			|  | 920 | +}
 | 
		
	
		
			
			|  | 921 | +
 | 
		
	
		
			
			| 890 | 922 |  /**
 | 
		
	
		
			
			| 891 | 923 |   * Resume TX state machine
 | 
		
	
		
			
			| 892 | 924 |   *
 | 
		
	
	
		
			
			|  | @@ -954,6 +986,13 @@ static int tls_send_client_hello ( struct tls_session *tls ) {
 | 
		
	
		
			
			| 954 | 986 |  				struct tls_signature_hash_id
 | 
		
	
		
			
			| 955 | 987 |  					code[TLS_NUM_SIG_HASH_ALGORITHMS];
 | 
		
	
		
			
			| 956 | 988 |  			} __attribute__ (( packed )) signature_algorithms;
 | 
		
	
		
			
			|  | 989 | +			uint16_t renegotiation_info_type;
 | 
		
	
		
			
			|  | 990 | +			uint16_t renegotiation_info_len;
 | 
		
	
		
			
			|  | 991 | +			struct {
 | 
		
	
		
			
			|  | 992 | +				uint8_t len;
 | 
		
	
		
			
			|  | 993 | +				uint8_t data[ tls->secure_renegotiation ?
 | 
		
	
		
			
			|  | 994 | +					      sizeof ( tls->verify.client ) :0];
 | 
		
	
		
			
			|  | 995 | +			} __attribute__ (( packed )) renegotiation_info;
 | 
		
	
		
			
			| 957 | 996 |  		} __attribute__ (( packed )) extensions;
 | 
		
	
		
			
			| 958 | 997 |  	} __attribute__ (( packed )) hello;
 | 
		
	
		
			
			| 959 | 998 |  	struct tls_cipher_suite *suite;
 | 
		
	
	
		
			
			|  | @@ -995,6 +1034,14 @@ static int tls_send_client_hello ( struct tls_session *tls ) {
 | 
		
	
		
			
			| 995 | 1034 |  		= htons ( sizeof ( hello.extensions.signature_algorithms.code));
 | 
		
	
		
			
			| 996 | 1035 |  	i = 0 ; for_each_table_entry ( sighash, TLS_SIG_HASH_ALGORITHMS )
 | 
		
	
		
			
			| 997 | 1036 |  		hello.extensions.signature_algorithms.code[i++] = sighash->code;
 | 
		
	
		
			
			|  | 1037 | +	hello.extensions.renegotiation_info_type
 | 
		
	
		
			
			|  | 1038 | +		= htons ( TLS_RENEGOTIATION_INFO );
 | 
		
	
		
			
			|  | 1039 | +	hello.extensions.renegotiation_info_len
 | 
		
	
		
			
			|  | 1040 | +		= htons ( sizeof ( hello.extensions.renegotiation_info ) );
 | 
		
	
		
			
			|  | 1041 | +	hello.extensions.renegotiation_info.len
 | 
		
	
		
			
			|  | 1042 | +		= sizeof ( hello.extensions.renegotiation_info.data );
 | 
		
	
		
			
			|  | 1043 | +	memcpy ( hello.extensions.renegotiation_info.data, tls->verify.client,
 | 
		
	
		
			
			|  | 1044 | +		 sizeof ( hello.extensions.renegotiation_info.data ) );
 | 
		
	
		
			
			| 998 | 1045 |  
 | 
		
	
		
			
			| 999 | 1046 |  	return tls_send_handshake ( tls, &hello, sizeof ( hello ) );
 | 
		
	
		
			
			| 1000 | 1047 |  }
 | 
		
	
	
		
			
			|  | @@ -1201,20 +1248,24 @@ static int tls_send_finished ( struct tls_session *tls ) {
 | 
		
	
		
			
			| 1201 | 1248 |  	struct digest_algorithm *digest = tls->handshake_digest;
 | 
		
	
		
			
			| 1202 | 1249 |  	struct {
 | 
		
	
		
			
			| 1203 | 1250 |  		uint32_t type_length;
 | 
		
	
		
			
			| 1204 |  | -		uint8_t verify_data[12];
 | 
		
	
		
			
			|  | 1251 | +		uint8_t verify_data[ sizeof ( tls->verify.client ) ];
 | 
		
	
		
			
			| 1205 | 1252 |  	} __attribute__ (( packed )) finished;
 | 
		
	
		
			
			| 1206 | 1253 |  	uint8_t digest_out[ digest->digestsize ];
 | 
		
	
		
			
			| 1207 | 1254 |  	int rc;
 | 
		
	
		
			
			| 1208 | 1255 |  
 | 
		
	
		
			
			|  | 1256 | +	/* Construct client verification data */
 | 
		
	
		
			
			|  | 1257 | +	tls_verify_handshake ( tls, digest_out );
 | 
		
	
		
			
			|  | 1258 | +	tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
 | 
		
	
		
			
			|  | 1259 | +			tls->verify.client, sizeof ( tls->verify.client ),
 | 
		
	
		
			
			|  | 1260 | +			"client finished", digest_out, sizeof ( digest_out ) );
 | 
		
	
		
			
			|  | 1261 | +
 | 
		
	
		
			
			| 1209 | 1262 |  	/* Construct record */
 | 
		
	
		
			
			| 1210 | 1263 |  	memset ( &finished, 0, sizeof ( finished ) );
 | 
		
	
		
			
			| 1211 | 1264 |  	finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
 | 
		
	
		
			
			| 1212 | 1265 |  				 htonl ( sizeof ( finished ) -
 | 
		
	
		
			
			| 1213 | 1266 |  					 sizeof ( finished.type_length ) ) );
 | 
		
	
		
			
			| 1214 |  | -	tls_verify_handshake ( tls, digest_out );
 | 
		
	
		
			
			| 1215 |  | -	tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
 | 
		
	
		
			
			| 1216 |  | -			finished.verify_data, sizeof ( finished.verify_data ),
 | 
		
	
		
			
			| 1217 |  | -			"client finished", digest_out, sizeof ( digest_out ) );
 | 
		
	
		
			
			|  | 1267 | +	memcpy ( finished.verify_data, tls->verify.client,
 | 
		
	
		
			
			|  | 1268 | +		 sizeof ( finished.verify_data ) );
 | 
		
	
		
			
			| 1218 | 1269 |  
 | 
		
	
		
			
			| 1219 | 1270 |  	/* Transmit record */
 | 
		
	
		
			
			| 1220 | 1271 |  	if ( ( rc = tls_send_handshake ( tls, &finished,
 | 
		
	
	
		
			
			|  | @@ -1295,6 +1346,37 @@ static int tls_new_alert ( struct tls_session *tls, const void *data,
 | 
		
	
		
			
			| 1295 | 1346 |  	}
 | 
		
	
		
			
			| 1296 | 1347 |  }
 | 
		
	
		
			
			| 1297 | 1348 |  
 | 
		
	
		
			
			|  | 1349 | +/**
 | 
		
	
		
			
			|  | 1350 | + * Receive new Hello Request handshake record
 | 
		
	
		
			
			|  | 1351 | + *
 | 
		
	
		
			
			|  | 1352 | + * @v tls		TLS session
 | 
		
	
		
			
			|  | 1353 | + * @v data		Plaintext handshake record
 | 
		
	
		
			
			|  | 1354 | + * @v len		Length of plaintext handshake record
 | 
		
	
		
			
			|  | 1355 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 1356 | + */
 | 
		
	
		
			
			|  | 1357 | +static int tls_new_hello_request ( struct tls_session *tls,
 | 
		
	
		
			
			|  | 1358 | +				   const void *data __unused,
 | 
		
	
		
			
			|  | 1359 | +				   size_t len __unused ) {
 | 
		
	
		
			
			|  | 1360 | +
 | 
		
	
		
			
			|  | 1361 | +	/* Ignore if a handshake is in progress */
 | 
		
	
		
			
			|  | 1362 | +	if ( ! tls_ready ( tls ) ) {
 | 
		
	
		
			
			|  | 1363 | +		DBGC ( tls, "TLS %p ignoring Hello Request\n", tls );
 | 
		
	
		
			
			|  | 1364 | +		return 0;
 | 
		
	
		
			
			|  | 1365 | +	}
 | 
		
	
		
			
			|  | 1366 | +
 | 
		
	
		
			
			|  | 1367 | +	/* Fail unless server supports secure renegotiation */
 | 
		
	
		
			
			|  | 1368 | +	if ( ! tls->secure_renegotiation ) {
 | 
		
	
		
			
			|  | 1369 | +		DBGC ( tls, "TLS %p refusing to renegotiate insecurely\n",
 | 
		
	
		
			
			|  | 1370 | +		       tls );
 | 
		
	
		
			
			|  | 1371 | +		return -EPERM_RENEG_INSECURE;
 | 
		
	
		
			
			|  | 1372 | +	}
 | 
		
	
		
			
			|  | 1373 | +
 | 
		
	
		
			
			|  | 1374 | +	/* Restart negotiation */
 | 
		
	
		
			
			|  | 1375 | +	tls_restart ( tls );
 | 
		
	
		
			
			|  | 1376 | +
 | 
		
	
		
			
			|  | 1377 | +	return 0;
 | 
		
	
		
			
			|  | 1378 | +}
 | 
		
	
		
			
			|  | 1379 | +
 | 
		
	
		
			
			| 1298 | 1380 |  /**
 | 
		
	
		
			
			| 1299 | 1381 |   * Receive new Server Hello handshake record
 | 
		
	
		
			
			| 1300 | 1382 |   *
 | 
		
	
	
		
			
			|  | @@ -1317,7 +1399,23 @@ static int tls_new_server_hello ( struct tls_session *tls,
 | 
		
	
		
			
			| 1317 | 1399 |  		uint8_t compression_method;
 | 
		
	
		
			
			| 1318 | 1400 |  		char next[0];
 | 
		
	
		
			
			| 1319 | 1401 |  	} __attribute__ (( packed )) *hello_b;
 | 
		
	
		
			
			|  | 1402 | +	const struct {
 | 
		
	
		
			
			|  | 1403 | +		uint16_t len;
 | 
		
	
		
			
			|  | 1404 | +		uint8_t data[0];
 | 
		
	
		
			
			|  | 1405 | +	} __attribute__ (( packed )) *exts;
 | 
		
	
		
			
			|  | 1406 | +	const struct {
 | 
		
	
		
			
			|  | 1407 | +		uint16_t type;
 | 
		
	
		
			
			|  | 1408 | +		uint16_t len;
 | 
		
	
		
			
			|  | 1409 | +		uint8_t data[0];
 | 
		
	
		
			
			|  | 1410 | +	} __attribute__ (( packed )) *ext;
 | 
		
	
		
			
			|  | 1411 | +	const struct {
 | 
		
	
		
			
			|  | 1412 | +		uint8_t len;
 | 
		
	
		
			
			|  | 1413 | +		uint8_t data[0];
 | 
		
	
		
			
			|  | 1414 | +	} __attribute__ (( packed )) *reneg = NULL;
 | 
		
	
		
			
			| 1320 | 1415 |  	uint16_t version;
 | 
		
	
		
			
			|  | 1416 | +	size_t exts_len;
 | 
		
	
		
			
			|  | 1417 | +	size_t ext_len;
 | 
		
	
		
			
			|  | 1418 | +	size_t remaining;
 | 
		
	
		
			
			| 1321 | 1419 |  	int rc;
 | 
		
	
		
			
			| 1322 | 1420 |  
 | 
		
	
		
			
			| 1323 | 1421 |  	/* Parse header */
 | 
		
	
	
		
			
			|  | @@ -1332,6 +1430,56 @@ static int tls_new_server_hello ( struct tls_session *tls,
 | 
		
	
		
			
			| 1332 | 1430 |  	session_id = hello_a->session_id;
 | 
		
	
		
			
			| 1333 | 1431 |  	hello_b = ( ( void * ) ( session_id + hello_a->session_id_len ) );
 | 
		
	
		
			
			| 1334 | 1432 |  
 | 
		
	
		
			
			|  | 1433 | +	/* Parse extensions, if present */
 | 
		
	
		
			
			|  | 1434 | +	remaining = ( len - sizeof ( *hello_a ) - hello_a->session_id_len -
 | 
		
	
		
			
			|  | 1435 | +		      sizeof ( *hello_b ) );
 | 
		
	
		
			
			|  | 1436 | +	if ( remaining ) {
 | 
		
	
		
			
			|  | 1437 | +
 | 
		
	
		
			
			|  | 1438 | +		/* Parse extensions length */
 | 
		
	
		
			
			|  | 1439 | +		exts = ( ( void * ) hello_b->next );
 | 
		
	
		
			
			|  | 1440 | +		if ( ( sizeof ( *exts ) > remaining ) ||
 | 
		
	
		
			
			|  | 1441 | +		     ( ( exts_len = ntohs ( exts->len ) ) >
 | 
		
	
		
			
			|  | 1442 | +		       ( remaining - sizeof ( *exts ) ) ) ) {
 | 
		
	
		
			
			|  | 1443 | +			DBGC ( tls, "TLS %p received underlength extensions\n",
 | 
		
	
		
			
			|  | 1444 | +			       tls );
 | 
		
	
		
			
			|  | 1445 | +			DBGC_HD ( tls, data, len );
 | 
		
	
		
			
			|  | 1446 | +			return -EINVAL_HELLO;
 | 
		
	
		
			
			|  | 1447 | +		}
 | 
		
	
		
			
			|  | 1448 | +
 | 
		
	
		
			
			|  | 1449 | +		/* Parse extensions */
 | 
		
	
		
			
			|  | 1450 | +		for ( ext = ( ( void * ) exts->data ), remaining = exts_len ;
 | 
		
	
		
			
			|  | 1451 | +		      remaining ;
 | 
		
	
		
			
			|  | 1452 | +		      ext = ( ( ( void * ) ext ) + sizeof ( *ext ) + ext_len ),
 | 
		
	
		
			
			|  | 1453 | +			      remaining -= ( sizeof ( *ext ) + ext_len ) ) {
 | 
		
	
		
			
			|  | 1454 | +
 | 
		
	
		
			
			|  | 1455 | +			/* Parse extension length */
 | 
		
	
		
			
			|  | 1456 | +			if ( ( sizeof ( *ext ) > remaining ) ||
 | 
		
	
		
			
			|  | 1457 | +			     ( ( ext_len = ntohs ( ext->len ) ) >
 | 
		
	
		
			
			|  | 1458 | +			       ( remaining - sizeof ( *ext ) ) ) ) {
 | 
		
	
		
			
			|  | 1459 | +				DBGC ( tls, "TLS %p received underlength "
 | 
		
	
		
			
			|  | 1460 | +				       "extension\n", tls );
 | 
		
	
		
			
			|  | 1461 | +				DBGC_HD ( tls, data, len );
 | 
		
	
		
			
			|  | 1462 | +				return -EINVAL_HELLO;
 | 
		
	
		
			
			|  | 1463 | +			}
 | 
		
	
		
			
			|  | 1464 | +
 | 
		
	
		
			
			|  | 1465 | +			/* Record known extensions */
 | 
		
	
		
			
			|  | 1466 | +			switch ( ext->type ) {
 | 
		
	
		
			
			|  | 1467 | +			case htons ( TLS_RENEGOTIATION_INFO ) :
 | 
		
	
		
			
			|  | 1468 | +				reneg = ( ( void * ) ext->data );
 | 
		
	
		
			
			|  | 1469 | +				if ( ( sizeof ( *reneg ) > ext_len ) ||
 | 
		
	
		
			
			|  | 1470 | +				     ( reneg->len >
 | 
		
	
		
			
			|  | 1471 | +				       ( ext_len - sizeof ( *reneg ) ) ) ) {
 | 
		
	
		
			
			|  | 1472 | +					DBGC ( tls, "TLS %p received "
 | 
		
	
		
			
			|  | 1473 | +					       "underlength renegotiation "
 | 
		
	
		
			
			|  | 1474 | +					       "info\n", tls );
 | 
		
	
		
			
			|  | 1475 | +					DBGC_HD ( tls, data, len );
 | 
		
	
		
			
			|  | 1476 | +					return -EINVAL_HELLO;
 | 
		
	
		
			
			|  | 1477 | +				}
 | 
		
	
		
			
			|  | 1478 | +				break;
 | 
		
	
		
			
			|  | 1479 | +			}
 | 
		
	
		
			
			|  | 1480 | +		}
 | 
		
	
		
			
			|  | 1481 | +	}
 | 
		
	
		
			
			|  | 1482 | +
 | 
		
	
		
			
			| 1335 | 1483 |  	/* Check and store protocol version */
 | 
		
	
		
			
			| 1336 | 1484 |  	version = ntohs ( hello_a->version );
 | 
		
	
		
			
			| 1337 | 1485 |  	if ( version < TLS_VERSION_TLS_1_0 ) {
 | 
		
	
	
		
			
			|  | @@ -1370,6 +1518,30 @@ static int tls_new_server_hello ( struct tls_session *tls,
 | 
		
	
		
			
			| 1370 | 1518 |  	if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
 | 
		
	
		
			
			| 1371 | 1519 |  		return rc;
 | 
		
	
		
			
			| 1372 | 1520 |  
 | 
		
	
		
			
			|  | 1521 | +	/* Handle secure renegotiation */
 | 
		
	
		
			
			|  | 1522 | +	if ( tls->secure_renegotiation ) {
 | 
		
	
		
			
			|  | 1523 | +
 | 
		
	
		
			
			|  | 1524 | +		/* Secure renegotiation is expected; verify data */
 | 
		
	
		
			
			|  | 1525 | +		if ( ( reneg == NULL ) ||
 | 
		
	
		
			
			|  | 1526 | +		     ( reneg->len != sizeof ( tls->verify ) ) ||
 | 
		
	
		
			
			|  | 1527 | +		     ( memcmp ( reneg->data, &tls->verify,
 | 
		
	
		
			
			|  | 1528 | +				sizeof ( tls->verify ) ) != 0 ) ) {
 | 
		
	
		
			
			|  | 1529 | +			DBGC ( tls, "TLS %p server failed secure "
 | 
		
	
		
			
			|  | 1530 | +			       "renegotiation\n", tls );
 | 
		
	
		
			
			|  | 1531 | +			return -EPERM_RENEG_VERIFY;
 | 
		
	
		
			
			|  | 1532 | +		}
 | 
		
	
		
			
			|  | 1533 | +
 | 
		
	
		
			
			|  | 1534 | +	} else if ( reneg != NULL ) {
 | 
		
	
		
			
			|  | 1535 | +
 | 
		
	
		
			
			|  | 1536 | +		/* Secure renegotiation is being enabled */
 | 
		
	
		
			
			|  | 1537 | +		if ( reneg->len != 0 ) {
 | 
		
	
		
			
			|  | 1538 | +			DBGC ( tls, "TLS %p server provided non-empty initial "
 | 
		
	
		
			
			|  | 1539 | +			       "renegotiation\n", tls );
 | 
		
	
		
			
			|  | 1540 | +			return -EPERM_RENEG_VERIFY;
 | 
		
	
		
			
			|  | 1541 | +		}
 | 
		
	
		
			
			|  | 1542 | +		tls->secure_renegotiation = 1;
 | 
		
	
		
			
			|  | 1543 | +	}
 | 
		
	
		
			
			|  | 1544 | +
 | 
		
	
		
			
			| 1373 | 1545 |  	return 0;
 | 
		
	
		
			
			| 1374 | 1546 |  }
 | 
		
	
		
			
			| 1375 | 1547 |  
 | 
		
	
	
		
			
			|  | @@ -1569,11 +1741,10 @@ static int tls_new_finished ( struct tls_session *tls,
 | 
		
	
		
			
			| 1569 | 1741 |  			      const void *data, size_t len ) {
 | 
		
	
		
			
			| 1570 | 1742 |  	struct digest_algorithm *digest = tls->handshake_digest;
 | 
		
	
		
			
			| 1571 | 1743 |  	const struct {
 | 
		
	
		
			
			| 1572 |  | -		uint8_t verify_data[12];
 | 
		
	
		
			
			|  | 1744 | +		uint8_t verify_data[ sizeof ( tls->verify.server ) ];
 | 
		
	
		
			
			| 1573 | 1745 |  		char next[0];
 | 
		
	
		
			
			| 1574 | 1746 |  	} __attribute__ (( packed )) *finished = data;
 | 
		
	
		
			
			| 1575 | 1747 |  	uint8_t digest_out[ digest->digestsize ];
 | 
		
	
		
			
			| 1576 |  | -	uint8_t verify_data[ sizeof ( finished->verify_data ) ];
 | 
		
	
		
			
			| 1577 | 1748 |  
 | 
		
	
		
			
			| 1578 | 1749 |  	/* Sanity check */
 | 
		
	
		
			
			| 1579 | 1750 |  	if ( sizeof ( *finished ) != len ) {
 | 
		
	
	
		
			
			|  | @@ -1585,10 +1756,10 @@ static int tls_new_finished ( struct tls_session *tls,
 | 
		
	
		
			
			| 1585 | 1756 |  	/* Verify data */
 | 
		
	
		
			
			| 1586 | 1757 |  	tls_verify_handshake ( tls, digest_out );
 | 
		
	
		
			
			| 1587 | 1758 |  	tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
 | 
		
	
		
			
			| 1588 |  | -			verify_data, sizeof ( verify_data ), "server finished",
 | 
		
	
		
			
			| 1589 |  | -			digest_out, sizeof ( digest_out ) );
 | 
		
	
		
			
			| 1590 |  | -	if ( memcmp ( verify_data, finished->verify_data,
 | 
		
	
		
			
			| 1591 |  | -		      sizeof ( verify_data ) ) != 0 ) {
 | 
		
	
		
			
			|  | 1759 | +			tls->verify.server, sizeof ( tls->verify.server ),
 | 
		
	
		
			
			|  | 1760 | +			"server finished", digest_out, sizeof ( digest_out ) );
 | 
		
	
		
			
			|  | 1761 | +	if ( memcmp ( tls->verify.server, finished->verify_data,
 | 
		
	
		
			
			|  | 1762 | +		      sizeof ( tls->verify.server ) ) != 0 ) {
 | 
		
	
		
			
			| 1592 | 1763 |  		DBGC ( tls, "TLS %p verification failed\n", tls );
 | 
		
	
		
			
			| 1593 | 1764 |  		return -EPERM_VERIFY;
 | 
		
	
		
			
			| 1594 | 1765 |  	}
 | 
		
	
	
		
			
			|  | @@ -1644,6 +1815,10 @@ static int tls_new_handshake ( struct tls_session *tls,
 | 
		
	
		
			
			| 1644 | 1815 |  
 | 
		
	
		
			
			| 1645 | 1816 |  		/* Handle payload */
 | 
		
	
		
			
			| 1646 | 1817 |  		switch ( handshake->type ) {
 | 
		
	
		
			
			|  | 1818 | +		case TLS_HELLO_REQUEST:
 | 
		
	
		
			
			|  | 1819 | +			rc = tls_new_hello_request ( tls, payload,
 | 
		
	
		
			
			|  | 1820 | +						     payload_len );
 | 
		
	
		
			
			|  | 1821 | +			break;
 | 
		
	
		
			
			| 1647 | 1822 |  		case TLS_SERVER_HELLO:
 | 
		
	
		
			
			| 1648 | 1823 |  			rc = tls_new_server_hello ( tls, payload, payload_len );
 | 
		
	
		
			
			| 1649 | 1824 |  			break;
 | 
		
	
	
		
			
			|  | @@ -2622,18 +2797,12 @@ int add_tls ( struct interface *xfer, const char *name,
 | 
		
	
		
			
			| 2622 | 2797 |  		      ( sizeof ( tls->pre_master_secret.random ) ) ) ) != 0 ) {
 | 
		
	
		
			
			| 2623 | 2798 |  		goto err_random;
 | 
		
	
		
			
			| 2624 | 2799 |  	}
 | 
		
	
		
			
			| 2625 |  | -	digest_init ( &md5_sha1_algorithm, tls->handshake_md5_sha1_ctx );
 | 
		
	
		
			
			| 2626 |  | -	digest_init ( &sha256_algorithm, tls->handshake_sha256_ctx );
 | 
		
	
		
			
			| 2627 |  | -	tls->handshake_digest = &sha256_algorithm;
 | 
		
	
		
			
			| 2628 |  | -	tls->handshake_ctx = tls->handshake_sha256_ctx;
 | 
		
	
		
			
			| 2629 |  | -	tls->tx_pending = TLS_TX_CLIENT_HELLO;
 | 
		
	
		
			
			| 2630 | 2800 |  	iob_populate ( &tls->rx_header_iobuf, &tls->rx_header, 0,
 | 
		
	
		
			
			| 2631 | 2801 |  		       sizeof ( tls->rx_header ) );
 | 
		
	
		
			
			| 2632 | 2802 |  	INIT_LIST_HEAD ( &tls->rx_data );
 | 
		
	
		
			
			| 2633 | 2803 |  
 | 
		
	
		
			
			| 2634 |  | -	/* Add pending operations for server and client Finished messages */
 | 
		
	
		
			
			| 2635 |  | -	pending_get ( &tls->client_negotiation );
 | 
		
	
		
			
			| 2636 |  | -	pending_get ( &tls->server_negotiation );
 | 
		
	
		
			
			|  | 2804 | +	/* Start negotiation */
 | 
		
	
		
			
			|  | 2805 | +	tls_restart ( tls );
 | 
		
	
		
			
			| 2637 | 2806 |  
 | 
		
	
		
			
			| 2638 | 2807 |  	/* Attach to parent interface, mortalise self, and return */
 | 
		
	
		
			
			| 2639 | 2808 |  	intf_plug_plug ( &tls->plainstream, xfer );
 |