|
@@ -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 ) {
|