aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-10-11 13:49:57 +0100
committerMichael Brown <mcb30@ipxe.org>2022-10-11 14:37:12 +0100
commit80c45c5c71af76e4313c37528d29aa485b247073 (patch)
tree1aaabb621966e59777ad31db443709dd36330472
parent028aac99a397f591de6cc6f6f2b4763f55aa8962 (diff)
downloadipxe-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.h4
-rw-r--r--src/net/tls.c36
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 );