diff options
author | Michael Brown <mcb30@ipxe.org> | 2022-10-11 13:49:57 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2022-10-11 14:37:12 +0100 |
commit | 80c45c5c71af76e4313c37528d29aa485b247073 (patch) | |
tree | 1aaabb621966e59777ad31db443709dd36330472 | |
parent | 028aac99a397f591de6cc6f6f2b4763f55aa8962 (diff) | |
download | ipxe-80c45c5c71af76e4313c37528d29aa485b247073.zip ipxe-80c45c5c71af76e4313c37528d29aa485b247073.tar.gz ipxe-80c45c5c71af76e4313c37528d29aa485b247073.tar.bz2 |
[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>
-rw-r--r-- | src/include/ipxe/tls.h | 4 | ||||
-rw-r--r-- | src/net/tls.c | 36 |
2 files changed, 40 insertions, 0 deletions
diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h index 6560897..672cfbd 100644 --- a/src/include/ipxe/tls.h +++ b/src/include/ipxe/tls.h @@ -310,6 +310,10 @@ struct tls_connection { uint8_t server_random[32]; /** Client random bytes */ 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 */ uint8_t handshake_md5_sha1_ctx[MD5_SHA1_CTX_SIZE]; /** SHA256 context for handshake verification */ diff --git a/src/net/tls.c b/src/net/tls.c index 4fb5b17..a1ffcac 100644 --- a/src/net/tls.c +++ b/src/net/tls.c @@ -377,6 +377,7 @@ static void free_tls ( struct refcnt *refcnt ) { tls_clear_cipher ( tls, &tls->tx_cipherspec_pending ); tls_clear_cipher ( tls, &tls->rx_cipherspec ); tls_clear_cipher ( tls, &tls->rx_cipherspec_pending ); + free ( tls->server_key ); list_for_each_entry_safe ( iobuf, tmp, &tls->rx_data, list ) { list_del ( &iobuf->list ); free_iob ( iobuf ); @@ -1868,6 +1869,37 @@ static int tls_new_certificate ( struct tls_connection *tls, } /** + * 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 * * @v tls TLS connection @@ -2100,6 +2132,10 @@ static int tls_new_handshake ( struct tls_connection *tls, case TLS_CERTIFICATE: rc = tls_new_certificate ( tls, payload, payload_len ); break; + case TLS_SERVER_KEY_EXCHANGE: + rc = tls_new_server_key_exchange ( tls, payload, + payload_len ); + break; case TLS_CERTIFICATE_REQUEST: rc = tls_new_certificate_request ( tls, payload, payload_len ); |