summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/tls.c69
1 files changed, 35 insertions, 34 deletions
diff --git a/src/net/tls.c b/src/net/tls.c
index 1bcb5c027..c01ce9515 100644
--- a/src/net/tls.c
+++ b/src/net/tls.c
@@ -1863,6 +1863,7 @@ static int tls_send_certificate_verify ( struct tls_connection *tls ) {
struct asn1_cursor *key = privkey_cursor ( tls->client.key );
uint8_t digest_out[ digest->digestsize ];
struct tls_signature_hash_algorithm *sig_hash = NULL;
+ struct asn1_builder builder = { NULL, 0 };
int rc;
/* Generate digest to be signed */
@@ -1880,53 +1881,53 @@ static int tls_send_certificate_verify ( struct tls_connection *tls ) {
}
}
- /* Generate and transmit record */
+ /* Sign digest */
+ if ( ( rc = pubkey_sign ( pubkey, key, digest, digest_out,
+ &builder ) ) != 0 ) {
+ DBGC ( tls, "TLS %p could not sign %s digest using %s client "
+ "private key: %s\n", tls, digest->name, pubkey->name,
+ strerror ( rc ) );
+ goto err_pubkey_sign;
+ }
+
+ /* Construct Certificate Verify record */
{
- size_t max_len = pubkey_max_len ( pubkey, key );
int use_sig_hash = ( ( sig_hash == NULL ) ? 0 : 1 );
struct {
uint32_t type_length;
struct tls_signature_hash_id sig_hash[use_sig_hash];
uint16_t signature_len;
- uint8_t signature[max_len];
- } __attribute__ (( packed )) certificate_verify;
- size_t unused;
- int len;
-
- /* Sign digest */
- len = pubkey_sign ( pubkey, key, digest, digest_out,
- certificate_verify.signature );
- if ( len < 0 ) {
- rc = len;
- DBGC ( tls, "TLS %p could not sign %s digest using %s "
- "client private key: %s\n", tls, digest->name,
- pubkey->name, strerror ( rc ) );
- goto err_pubkey_sign;
- }
- unused = ( max_len - len );
-
- /* Construct Certificate Verify record */
- certificate_verify.type_length =
- ( cpu_to_le32 ( TLS_CERTIFICATE_VERIFY ) |
- htonl ( sizeof ( certificate_verify ) -
- sizeof ( certificate_verify.type_length ) -
- unused ) );
+ } __attribute__ (( packed )) header;
+
+ header.type_length = ( cpu_to_le32 ( TLS_CERTIFICATE_VERIFY ) |
+ htonl ( builder.len +
+ sizeof ( header ) -
+ sizeof ( header.type_length )));
if ( use_sig_hash ) {
- memcpy ( &certificate_verify.sig_hash[0],
- &sig_hash->code,
- sizeof ( certificate_verify.sig_hash[0] ) );
+ memcpy ( &header.sig_hash[0], &sig_hash->code,
+ sizeof ( header.sig_hash[0] ) );
}
- certificate_verify.signature_len =
- htons ( sizeof ( certificate_verify.signature ) -
- unused );
+ header.signature_len = htons ( builder.len );
- /* Transmit record */
- rc = tls_send_handshake ( tls, &certificate_verify,
- ( sizeof ( certificate_verify ) - unused ) );
+ if ( ( rc = asn1_prepend_raw ( &builder, &header,
+ sizeof ( header ) ) ) != 0 ) {
+ DBGC ( tls, "TLS %p could not construct Certificate "
+ "Verify: %s\n", tls, strerror ( rc ) );
+ goto err_prepend;
+ }
+ }
+
+ /* Transmit record */
+ if ( ( rc = tls_send_handshake ( tls, builder.data,
+ builder.len ) ) != 0 ) {
+ goto err_send;
}
+ err_send:
+ err_prepend:
err_pubkey_sign:
err_sig_hash:
+ free ( builder.data );
return rc;
}