summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
authorMichael Brown2025-12-02 14:12:25 +0100
committerMichael Brown2025-12-02 14:12:25 +0100
commit1ccc320ee99651622ced9b33764d5e7890ca3f57 (patch)
tree8915b83470bd0b1e320223a8310540ef9c247feb /src/net
parent[crypto] Construct signatures using ASN.1 builders (diff)
downloadipxe-1ccc320ee99651622ced9b33764d5e7890ca3f57.tar.gz
ipxe-1ccc320ee99651622ced9b33764d5e7890ca3f57.tar.xz
ipxe-1ccc320ee99651622ced9b33764d5e7890ca3f57.zip
[crypto] Construct asymmetric ciphered data using ASN.1 builders
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net')
-rw-r--r--src/net/tls.c68
1 files changed, 39 insertions, 29 deletions
diff --git a/src/net/tls.c b/src/net/tls.c
index c01ce9515..6140ca58a 100644
--- a/src/net/tls.c
+++ b/src/net/tls.c
@@ -1416,59 +1416,69 @@ static int tls_send_certificate ( struct tls_connection *tls ) {
static int tls_send_client_key_exchange_pubkey ( struct tls_connection *tls ) {
struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
- size_t max_len = pubkey_max_len ( pubkey, &tls->server.key );
struct {
uint16_t version;
uint8_t random[46];
} __attribute__ (( packed )) pre_master_secret;
- struct {
- uint32_t type_length;
- uint16_t encrypted_pre_master_secret_len;
- uint8_t encrypted_pre_master_secret[max_len];
- } __attribute__ (( packed )) key_xchg;
- size_t unused;
- int len;
+ struct asn1_cursor cursor = {
+ .data = &pre_master_secret,
+ .len = sizeof ( pre_master_secret ),
+ };
+ struct asn1_builder builder = { NULL, 0 };
int rc;
/* Generate pre-master secret */
pre_master_secret.version = htons ( TLS_VERSION_MAX );
if ( ( rc = tls_generate_random ( tls, &pre_master_secret.random,
( sizeof ( pre_master_secret.random ) ) ) ) != 0 ) {
- return rc;
+ goto err_random;
}
/* Encrypt pre-master secret using server's public key */
- memset ( &key_xchg, 0, sizeof ( key_xchg ) );
- len = pubkey_encrypt ( pubkey, &tls->server.key, &pre_master_secret,
- sizeof ( pre_master_secret ),
- key_xchg.encrypted_pre_master_secret );
- if ( len < 0 ) {
- rc = len;
+ if ( ( rc = pubkey_encrypt ( pubkey, &tls->server.key, &cursor,
+ &builder ) ) != 0 ) {
DBGC ( tls, "TLS %p could not encrypt pre-master secret: %s\n",
tls, strerror ( rc ) );
- return rc;
+ goto err_encrypt;
+ }
+
+ /* Construct Client Key Exchange record */
+ {
+ struct {
+ uint32_t type_length;
+ uint16_t encrypted_pre_master_secret_len;
+ } __attribute__ (( packed )) header;
+
+ header.type_length =
+ ( cpu_to_le32 ( TLS_CLIENT_KEY_EXCHANGE ) |
+ htonl ( builder.len + sizeof ( header ) -
+ sizeof ( header.type_length ) ) );
+ header.encrypted_pre_master_secret_len = htons ( builder.len );
+
+ if ( ( rc = asn1_prepend_raw ( &builder, &header,
+ sizeof ( header ) ) ) != 0 ) {
+ DBGC ( tls, "TLS %p could not construct Client Key "
+ "Exchange: %s\n", tls, strerror ( rc ) );
+ goto err_prepend;
+ }
}
- unused = ( max_len - len );
- key_xchg.type_length =
- ( cpu_to_le32 ( TLS_CLIENT_KEY_EXCHANGE ) |
- htonl ( sizeof ( key_xchg ) -
- sizeof ( key_xchg.type_length ) - unused ) );
- key_xchg.encrypted_pre_master_secret_len =
- htons ( sizeof ( key_xchg.encrypted_pre_master_secret ) -
- unused );
/* Transmit Client Key Exchange record */
- if ( ( rc = tls_send_handshake ( tls, &key_xchg,
- ( sizeof ( key_xchg ) -
- unused ) ) ) != 0 ) {
- return rc;
+ if ( ( rc = tls_send_handshake ( tls, builder.data,
+ builder.len ) ) != 0 ) {
+ goto err_send;
}
/* Generate master secret */
tls_generate_master_secret ( tls, &pre_master_secret,
sizeof ( pre_master_secret ) );
- return 0;
+ err_random:
+ err_encrypt:
+ err_prepend:
+ err_send:
+ free ( builder.data );
+ return rc;
}
/** Public key exchange algorithm */