Browse Source

[tls] Send empty Certificate record if requested by server

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
281f9aa7a6
2 changed files with 61 additions and 3 deletions
  1. 4
    3
      src/include/ipxe/tls.h
  2. 57
    0
      src/net/tls.c

+ 4
- 3
src/include/ipxe/tls.h View File

@@ -87,9 +87,10 @@ enum tls_rx_state {
87 87
 /** TLS TX pending flags */
88 88
 enum tls_tx_pending {
89 89
 	TLS_TX_CLIENT_HELLO = 0x0001,
90
-	TLS_TX_CLIENT_KEY_EXCHANGE = 0x0002,
91
-	TLS_TX_CHANGE_CIPHER = 0x0004,
92
-	TLS_TX_FINISHED = 0x0008,
90
+	TLS_TX_CERTIFICATE = 0x0002,
91
+	TLS_TX_CLIENT_KEY_EXCHANGE = 0x0004,
92
+	TLS_TX_CHANGE_CIPHER = 0x0008,
93
+	TLS_TX_FINISHED = 0x0010,
93 94
 };
94 95
 
95 96
 /** A TLS cipher specification */

+ 57
- 0
src/net/tls.c View File

@@ -684,6 +684,27 @@ static int tls_send_client_hello ( struct tls_session *tls ) {
684 684
 	return tls_send_handshake ( tls, &hello, sizeof ( hello ) );
685 685
 }
686 686
 
687
+/**
688
+ * Transmit Certificate record
689
+ *
690
+ * @v tls		TLS session
691
+ * @ret rc		Return status code
692
+ */
693
+static int tls_send_certificate ( struct tls_session *tls ) {
694
+	struct {
695
+		uint32_t type_length;
696
+		uint8_t length[3];
697
+	} __attribute__ (( packed )) certificate;
698
+
699
+	memset ( &certificate, 0, sizeof ( certificate ) );
700
+	certificate.type_length = ( cpu_to_le32 ( TLS_CERTIFICATE ) |
701
+				    htonl ( sizeof ( certificate ) -
702
+					    sizeof ( certificate.type_length)));
703
+
704
+	return tls_send_handshake ( tls, &certificate, sizeof ( certificate ) );
705
+}
706
+
707
+
687 708
 /**
688 709
  * Transmit Client Key Exchange record
689 710
  *
@@ -955,6 +976,30 @@ static int tls_new_certificate ( struct tls_session *tls,
955 976
 	return -EINVAL;
956 977
 }
957 978
 
979
+/**
980
+ * Receive new Certificate Request handshake record
981
+ *
982
+ * @v tls		TLS session
983
+ * @v data		Plaintext handshake record
984
+ * @v len		Length of plaintext handshake record
985
+ * @ret rc		Return status code
986
+ */
987
+static int tls_new_certificate_request ( struct tls_session *tls,
988
+					 void *data __unused,
989
+					 size_t len __unused ) {
990
+
991
+	/* We can only send an empty certificate (as mandated by
992
+	 * TLSv1.2), so there is no point in parsing the Certificate
993
+	 * Request.
994
+	 */
995
+
996
+	/* Schedule Certificate transmission */
997
+	tls->tx_pending |= TLS_TX_CERTIFICATE;
998
+	tls_tx_resume ( tls );
999
+
1000
+	return 0;
1001
+}
1002
+
958 1003
 /**
959 1004
  * Receive new Server Hello Done handshake record
960 1005
  *
@@ -1070,6 +1115,10 @@ static int tls_new_handshake ( struct tls_session *tls,
1070 1115
 		case TLS_CERTIFICATE:
1071 1116
 			rc = tls_new_certificate ( tls, payload, payload_len );
1072 1117
 			break;
1118
+		case TLS_CERTIFICATE_REQUEST:
1119
+			rc = tls_new_certificate_request ( tls, payload,
1120
+							   payload_len );
1121
+			break;
1073 1122
 		case TLS_SERVER_HELLO_DONE:
1074 1123
 			rc = tls_new_server_hello_done ( tls, payload,
1075 1124
 							 payload_len );
@@ -1741,6 +1790,14 @@ static void tls_tx_step ( struct tls_session *tls ) {
1741 1790
 			goto err;
1742 1791
 		}
1743 1792
 		tls->tx_pending &= ~TLS_TX_CLIENT_HELLO;
1793
+	} else if ( tls->tx_pending & TLS_TX_CERTIFICATE ) {
1794
+		/* Send Certificate */
1795
+		if ( ( rc = tls_send_certificate ( tls ) ) != 0 ) {
1796
+			DBGC ( tls, "TLS %p cold not send Certificate: %s\n",
1797
+			       tls, strerror ( rc ) );
1798
+			goto err;
1799
+		}
1800
+		tls->tx_pending &= ~TLS_TX_CERTIFICATE;
1744 1801
 	} else if ( tls->tx_pending & TLS_TX_CLIENT_KEY_EXCHANGE ) {
1745 1802
 		/* Send Client Key Exchange */
1746 1803
 		if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) {

Loading…
Cancel
Save