Ver código fonte

[tls] Support RFC5746 secure renegotiation

Support renegotiation with servers supporting RFC5746.  This allows
for the use of per-directory client certificates.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6 anos atrás
pai
commit
1e4a3f5bab
2 arquivos alterados com 203 adições e 19 exclusões
  1. 15
    0
      src/include/ipxe/tls.h
  2. 188
    19
      src/net/tls.c

+ 15
- 0
src/include/ipxe/tls.h Ver arquivo

108
 /* TLS signature algorithms extension */
108
 /* TLS signature algorithms extension */
109
 #define TLS_SIGNATURE_ALGORITHMS 13
109
 #define TLS_SIGNATURE_ALGORITHMS 13
110
 
110
 
111
+/* TLS renegotiation information extension */
112
+#define TLS_RENEGOTIATION_INFO 0xff01
113
+
114
+/** TLS verification data */
115
+struct tls_verify_data {
116
+	/** Client verification data */
117
+	uint8_t client[12];
118
+	/** Server verification data */
119
+	uint8_t server[12];
120
+} __attribute__ (( packed ));
121
+
111
 /** TLS RX state machine state */
122
 /** TLS RX state machine state */
112
 enum tls_rx_state {
123
 enum tls_rx_state {
113
 	TLS_RX_HEADER = 0,
124
 	TLS_RX_HEADER = 0,
271
 	uint8_t *handshake_ctx;
282
 	uint8_t *handshake_ctx;
272
 	/** Client certificate (if used) */
283
 	/** Client certificate (if used) */
273
 	struct x509_certificate *cert;
284
 	struct x509_certificate *cert;
285
+	/** Secure renegotiation flag */
286
+	int secure_renegotiation;
287
+	/** Verification data */
288
+	struct tls_verify_data verify;
274
 
289
 
275
 	/** Server certificate chain */
290
 	/** Server certificate chain */
276
 	struct x509_chain *chain;
291
 	struct x509_chain *chain;

+ 188
- 19
src/net/tls.c Ver arquivo

162
 #define EINFO_EPERM_CLIENT_CERT						\
162
 #define EINFO_EPERM_CLIENT_CERT						\
163
 	__einfo_uniqify ( EINFO_EPERM, 0x03,				\
163
 	__einfo_uniqify ( EINFO_EPERM, 0x03,				\
164
 			  "No suitable client certificate available" )
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
 #define EPROTO_VERSION __einfo_error ( EINFO_EPROTO_VERSION )
173
 #define EPROTO_VERSION __einfo_error ( EINFO_EPROTO_VERSION )
166
 #define EINFO_EPROTO_VERSION						\
174
 #define EINFO_EPROTO_VERSION						\
167
 	__einfo_uniqify ( EINFO_EPROTO, 0x01,				\
175
 	__einfo_uniqify ( EINFO_EPROTO, 0x01,				\
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
  * Resume TX state machine
923
  * Resume TX state machine
892
  *
924
  *
954
 				struct tls_signature_hash_id
986
 				struct tls_signature_hash_id
955
 					code[TLS_NUM_SIG_HASH_ALGORITHMS];
987
 					code[TLS_NUM_SIG_HASH_ALGORITHMS];
956
 			} __attribute__ (( packed )) signature_algorithms;
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
 		} __attribute__ (( packed )) extensions;
996
 		} __attribute__ (( packed )) extensions;
958
 	} __attribute__ (( packed )) hello;
997
 	} __attribute__ (( packed )) hello;
959
 	struct tls_cipher_suite *suite;
998
 	struct tls_cipher_suite *suite;
995
 		= htons ( sizeof ( hello.extensions.signature_algorithms.code));
1034
 		= htons ( sizeof ( hello.extensions.signature_algorithms.code));
996
 	i = 0 ; for_each_table_entry ( sighash, TLS_SIG_HASH_ALGORITHMS )
1035
 	i = 0 ; for_each_table_entry ( sighash, TLS_SIG_HASH_ALGORITHMS )
997
 		hello.extensions.signature_algorithms.code[i++] = sighash->code;
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
 	return tls_send_handshake ( tls, &hello, sizeof ( hello ) );
1046
 	return tls_send_handshake ( tls, &hello, sizeof ( hello ) );
1000
 }
1047
 }
1201
 	struct digest_algorithm *digest = tls->handshake_digest;
1248
 	struct digest_algorithm *digest = tls->handshake_digest;
1202
 	struct {
1249
 	struct {
1203
 		uint32_t type_length;
1250
 		uint32_t type_length;
1204
-		uint8_t verify_data[12];
1251
+		uint8_t verify_data[ sizeof ( tls->verify.client ) ];
1205
 	} __attribute__ (( packed )) finished;
1252
 	} __attribute__ (( packed )) finished;
1206
 	uint8_t digest_out[ digest->digestsize ];
1253
 	uint8_t digest_out[ digest->digestsize ];
1207
 	int rc;
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
 	/* Construct record */
1262
 	/* Construct record */
1210
 	memset ( &finished, 0, sizeof ( finished ) );
1263
 	memset ( &finished, 0, sizeof ( finished ) );
1211
 	finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
1264
 	finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
1212
 				 htonl ( sizeof ( finished ) -
1265
 				 htonl ( sizeof ( finished ) -
1213
 					 sizeof ( finished.type_length ) ) );
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
 	/* Transmit record */
1270
 	/* Transmit record */
1220
 	if ( ( rc = tls_send_handshake ( tls, &finished,
1271
 	if ( ( rc = tls_send_handshake ( tls, &finished,
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
  * Receive new Server Hello handshake record
1381
  * Receive new Server Hello handshake record
1300
  *
1382
  *
1317
 		uint8_t compression_method;
1399
 		uint8_t compression_method;
1318
 		char next[0];
1400
 		char next[0];
1319
 	} __attribute__ (( packed )) *hello_b;
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
 	uint16_t version;
1415
 	uint16_t version;
1416
+	size_t exts_len;
1417
+	size_t ext_len;
1418
+	size_t remaining;
1321
 	int rc;
1419
 	int rc;
1322
 
1420
 
1323
 	/* Parse header */
1421
 	/* Parse header */
1332
 	session_id = hello_a->session_id;
1430
 	session_id = hello_a->session_id;
1333
 	hello_b = ( ( void * ) ( session_id + hello_a->session_id_len ) );
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
 	/* Check and store protocol version */
1483
 	/* Check and store protocol version */
1336
 	version = ntohs ( hello_a->version );
1484
 	version = ntohs ( hello_a->version );
1337
 	if ( version < TLS_VERSION_TLS_1_0 ) {
1485
 	if ( version < TLS_VERSION_TLS_1_0 ) {
1370
 	if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
1518
 	if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
1371
 		return rc;
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
 	return 0;
1545
 	return 0;
1374
 }
1546
 }
1375
 
1547
 
1569
 			      const void *data, size_t len ) {
1741
 			      const void *data, size_t len ) {
1570
 	struct digest_algorithm *digest = tls->handshake_digest;
1742
 	struct digest_algorithm *digest = tls->handshake_digest;
1571
 	const struct {
1743
 	const struct {
1572
-		uint8_t verify_data[12];
1744
+		uint8_t verify_data[ sizeof ( tls->verify.server ) ];
1573
 		char next[0];
1745
 		char next[0];
1574
 	} __attribute__ (( packed )) *finished = data;
1746
 	} __attribute__ (( packed )) *finished = data;
1575
 	uint8_t digest_out[ digest->digestsize ];
1747
 	uint8_t digest_out[ digest->digestsize ];
1576
-	uint8_t verify_data[ sizeof ( finished->verify_data ) ];
1577
 
1748
 
1578
 	/* Sanity check */
1749
 	/* Sanity check */
1579
 	if ( sizeof ( *finished ) != len ) {
1750
 	if ( sizeof ( *finished ) != len ) {
1585
 	/* Verify data */
1756
 	/* Verify data */
1586
 	tls_verify_handshake ( tls, digest_out );
1757
 	tls_verify_handshake ( tls, digest_out );
1587
 	tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
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
 		DBGC ( tls, "TLS %p verification failed\n", tls );
1763
 		DBGC ( tls, "TLS %p verification failed\n", tls );
1593
 		return -EPERM_VERIFY;
1764
 		return -EPERM_VERIFY;
1594
 	}
1765
 	}
1644
 
1815
 
1645
 		/* Handle payload */
1816
 		/* Handle payload */
1646
 		switch ( handshake->type ) {
1817
 		switch ( handshake->type ) {
1818
+		case TLS_HELLO_REQUEST:
1819
+			rc = tls_new_hello_request ( tls, payload,
1820
+						     payload_len );
1821
+			break;
1647
 		case TLS_SERVER_HELLO:
1822
 		case TLS_SERVER_HELLO:
1648
 			rc = tls_new_server_hello ( tls, payload, payload_len );
1823
 			rc = tls_new_server_hello ( tls, payload, payload_len );
1649
 			break;
1824
 			break;
2622
 		      ( sizeof ( tls->pre_master_secret.random ) ) ) ) != 0 ) {
2797
 		      ( sizeof ( tls->pre_master_secret.random ) ) ) ) != 0 ) {
2623
 		goto err_random;
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
 	iob_populate ( &tls->rx_header_iobuf, &tls->rx_header, 0,
2800
 	iob_populate ( &tls->rx_header_iobuf, &tls->rx_header, 0,
2631
 		       sizeof ( tls->rx_header ) );
2801
 		       sizeof ( tls->rx_header ) );
2632
 	INIT_LIST_HEAD ( &tls->rx_data );
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
 	/* Attach to parent interface, mortalise self, and return */
2807
 	/* Attach to parent interface, mortalise self, and return */
2639
 	intf_plug_plug ( &tls->plainstream, xfer );
2808
 	intf_plug_plug ( &tls->plainstream, xfer );

Carregando…
Cancelar
Salvar