diff options
| author | Michael Brown | 2012-03-03 23:47:16 +0100 |
|---|---|---|
| committer | Michael Brown | 2012-03-03 23:47:16 +0100 |
| commit | 281f9aa7a6775e60c78469228fe3d1a3a1355db9 (patch) | |
| tree | cc907a658c3891efc52555ef574bfbc81a154810 /src | |
| parent | [tls] Verify the contents of the Finished record (diff) | |
| download | ipxe-281f9aa7a6775e60c78469228fe3d1a3a1355db9.tar.gz ipxe-281f9aa7a6775e60c78469228fe3d1a3a1355db9.tar.xz ipxe-281f9aa7a6775e60c78469228fe3d1a3a1355db9.zip | |
[tls] Send empty Certificate record if requested by server
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/include/ipxe/tls.h | 7 | ||||
| -rw-r--r-- | src/net/tls.c | 57 |
2 files changed, 61 insertions, 3 deletions
diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h index 2aa2b06da..49401e6bf 100644 --- a/src/include/ipxe/tls.h +++ b/src/include/ipxe/tls.h @@ -87,9 +87,10 @@ enum tls_rx_state { /** TLS TX pending flags */ enum tls_tx_pending { TLS_TX_CLIENT_HELLO = 0x0001, - TLS_TX_CLIENT_KEY_EXCHANGE = 0x0002, - TLS_TX_CHANGE_CIPHER = 0x0004, - TLS_TX_FINISHED = 0x0008, + TLS_TX_CERTIFICATE = 0x0002, + TLS_TX_CLIENT_KEY_EXCHANGE = 0x0004, + TLS_TX_CHANGE_CIPHER = 0x0008, + TLS_TX_FINISHED = 0x0010, }; /** A TLS cipher specification */ diff --git a/src/net/tls.c b/src/net/tls.c index 28a4ba4ec..0249ed7cb 100644 --- a/src/net/tls.c +++ b/src/net/tls.c @@ -685,6 +685,27 @@ static int tls_send_client_hello ( struct tls_session *tls ) { } /** + * Transmit Certificate record + * + * @v tls TLS session + * @ret rc Return status code + */ +static int tls_send_certificate ( struct tls_session *tls ) { + struct { + uint32_t type_length; + uint8_t length[3]; + } __attribute__ (( packed )) certificate; + + memset ( &certificate, 0, sizeof ( certificate ) ); + certificate.type_length = ( cpu_to_le32 ( TLS_CERTIFICATE ) | + htonl ( sizeof ( certificate ) - + sizeof ( certificate.type_length))); + + return tls_send_handshake ( tls, &certificate, sizeof ( certificate ) ); +} + + +/** * Transmit Client Key Exchange record * * @v tls TLS session @@ -956,6 +977,30 @@ static int tls_new_certificate ( struct tls_session *tls, } /** + * Receive new Certificate Request handshake record + * + * @v tls TLS session + * @v data Plaintext handshake record + * @v len Length of plaintext handshake record + * @ret rc Return status code + */ +static int tls_new_certificate_request ( struct tls_session *tls, + void *data __unused, + size_t len __unused ) { + + /* We can only send an empty certificate (as mandated by + * TLSv1.2), so there is no point in parsing the Certificate + * Request. + */ + + /* Schedule Certificate transmission */ + tls->tx_pending |= TLS_TX_CERTIFICATE; + tls_tx_resume ( tls ); + + return 0; +} + +/** * Receive new Server Hello Done handshake record * * @v tls TLS session @@ -1070,6 +1115,10 @@ static int tls_new_handshake ( struct tls_session *tls, case TLS_CERTIFICATE: rc = tls_new_certificate ( tls, payload, payload_len ); break; + case TLS_CERTIFICATE_REQUEST: + rc = tls_new_certificate_request ( tls, payload, + payload_len ); + break; case TLS_SERVER_HELLO_DONE: rc = tls_new_server_hello_done ( tls, payload, payload_len ); @@ -1741,6 +1790,14 @@ static void tls_tx_step ( struct tls_session *tls ) { goto err; } tls->tx_pending &= ~TLS_TX_CLIENT_HELLO; + } else if ( tls->tx_pending & TLS_TX_CERTIFICATE ) { + /* Send Certificate */ + if ( ( rc = tls_send_certificate ( tls ) ) != 0 ) { + DBGC ( tls, "TLS %p cold not send Certificate: %s\n", + tls, strerror ( rc ) ); + goto err; + } + tls->tx_pending &= ~TLS_TX_CERTIFICATE; } else if ( tls->tx_pending & TLS_TX_CLIENT_KEY_EXCHANGE ) { /* Send Client Key Exchange */ if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) { |
