david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[tls] Send empty Certificate record if requested by server

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2012-03-03 22:47:16 +00:00
parent a42f6cab14
commit 281f9aa7a6
2 changed files with 61 additions and 3 deletions

View File

@ -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 */

View File

@ -684,6 +684,27 @@ static int tls_send_client_hello ( struct tls_session *tls ) {
return tls_send_handshake ( tls, &hello, sizeof ( hello ) );
}
/**
* 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
*
@ -955,6 +976,30 @@ static int tls_new_certificate ( struct tls_session *tls,
return -EINVAL;
}
/**
* 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
*
@ -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 ) {