mirror of https://github.com/ipxe/ipxe.git
[tls] Record ServerKeyExchange record, if provided
Accept and record the ServerKeyExchange record, which is required for key exchange mechanisms such as Ephemeral Diffie-Hellman (DHE). Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/785/head
parent
028aac99a3
commit
80c45c5c71
|
@ -310,6 +310,10 @@ struct tls_connection {
|
||||||
uint8_t server_random[32];
|
uint8_t server_random[32];
|
||||||
/** Client random bytes */
|
/** Client random bytes */
|
||||||
struct tls_client_random client_random;
|
struct tls_client_random client_random;
|
||||||
|
/** Server Key Exchange record (if any) */
|
||||||
|
void *server_key;
|
||||||
|
/** Server Key Exchange record length */
|
||||||
|
size_t server_key_len;
|
||||||
/** MD5+SHA1 context for handshake verification */
|
/** MD5+SHA1 context for handshake verification */
|
||||||
uint8_t handshake_md5_sha1_ctx[MD5_SHA1_CTX_SIZE];
|
uint8_t handshake_md5_sha1_ctx[MD5_SHA1_CTX_SIZE];
|
||||||
/** SHA256 context for handshake verification */
|
/** SHA256 context for handshake verification */
|
||||||
|
|
|
@ -377,6 +377,7 @@ static void free_tls ( struct refcnt *refcnt ) {
|
||||||
tls_clear_cipher ( tls, &tls->tx_cipherspec_pending );
|
tls_clear_cipher ( tls, &tls->tx_cipherspec_pending );
|
||||||
tls_clear_cipher ( tls, &tls->rx_cipherspec );
|
tls_clear_cipher ( tls, &tls->rx_cipherspec );
|
||||||
tls_clear_cipher ( tls, &tls->rx_cipherspec_pending );
|
tls_clear_cipher ( tls, &tls->rx_cipherspec_pending );
|
||||||
|
free ( tls->server_key );
|
||||||
list_for_each_entry_safe ( iobuf, tmp, &tls->rx_data, list ) {
|
list_for_each_entry_safe ( iobuf, tmp, &tls->rx_data, list ) {
|
||||||
list_del ( &iobuf->list );
|
list_del ( &iobuf->list );
|
||||||
free_iob ( iobuf );
|
free_iob ( iobuf );
|
||||||
|
@ -1867,6 +1868,37 @@ static int tls_new_certificate ( struct tls_connection *tls,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive new Server Key Exchange handshake record
|
||||||
|
*
|
||||||
|
* @v tls TLS connection
|
||||||
|
* @v data Plaintext handshake record
|
||||||
|
* @v len Length of plaintext handshake record
|
||||||
|
* @ret rc Return status code
|
||||||
|
*/
|
||||||
|
static int tls_new_server_key_exchange ( struct tls_connection *tls,
|
||||||
|
const void *data, size_t len ) {
|
||||||
|
|
||||||
|
/* Free any existing server key exchange record */
|
||||||
|
free ( tls->server_key );
|
||||||
|
tls->server_key_len = 0;
|
||||||
|
|
||||||
|
/* Allocate copy of server key exchange record */
|
||||||
|
tls->server_key = malloc ( len );
|
||||||
|
if ( ! tls->server_key )
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* Store copy of server key exchange record for later
|
||||||
|
* processing. We cannot verify the signature at this point
|
||||||
|
* since the certificate validation will not yet have
|
||||||
|
* completed.
|
||||||
|
*/
|
||||||
|
memcpy ( tls->server_key, data, len );
|
||||||
|
tls->server_key_len = len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receive new Certificate Request handshake record
|
* Receive new Certificate Request handshake record
|
||||||
*
|
*
|
||||||
|
@ -2100,6 +2132,10 @@ static int tls_new_handshake ( struct tls_connection *tls,
|
||||||
case TLS_CERTIFICATE:
|
case TLS_CERTIFICATE:
|
||||||
rc = tls_new_certificate ( tls, payload, payload_len );
|
rc = tls_new_certificate ( tls, payload, payload_len );
|
||||||
break;
|
break;
|
||||||
|
case TLS_SERVER_KEY_EXCHANGE:
|
||||||
|
rc = tls_new_server_key_exchange ( tls, payload,
|
||||||
|
payload_len );
|
||||||
|
break;
|
||||||
case TLS_CERTIFICATE_REQUEST:
|
case TLS_CERTIFICATE_REQUEST:
|
||||||
rc = tls_new_certificate_request ( tls, payload,
|
rc = tls_new_certificate_request ( tls, payload,
|
||||||
payload_len );
|
payload_len );
|
||||||
|
|
Loading…
Reference in New Issue