mirror of
https://github.com/ipxe/ipxe
synced 2026-05-18 10:00:30 +03:00
[tls] Treat signature algorithm identifiers as opaque 16-bit values
RFC 5246 defines the signature_algorithm extension values for TLS
version 1.2 as being tuples of {HashAlgorithm, SignatureAlgorithm}
pairs. RFC 8446 redefines the signature_algorithm extension values
for TLS version 1.3 in a backwards-compatible way as opaque 16-bit
SignatureScheme values, and RFC 8447 updates RFC 5246 to allow these
values to be used with TLS version 1.2.
Redefine our concept of a signature algorithm identifier to remove the
internal structure that no longer exists.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
FILE_SECBOOT ( PERMITTED );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/ecdsa.h>
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/asn1.h>
|
||||
@@ -43,10 +44,7 @@ struct asn1_algorithm ecdsa_with_sha224_algorithm __asn1_algorithm = {
|
||||
/** ECDSA with SHA-224 signature hash algorithm */
|
||||
struct tls_signature_hash_algorithm
|
||||
tls_ecdsa_sha224 __tls_sig_hash_algorithm = {
|
||||
.code = {
|
||||
.signature = TLS_ECDSA_ALGORITHM,
|
||||
.hash = TLS_SHA224_ALGORITHM,
|
||||
},
|
||||
.code = htons ( TLS_ECDSA_SHA224_ALGORITHM ),
|
||||
.pubkey = &ecdsa_algorithm,
|
||||
.digest = &sha224_algorithm,
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
FILE_SECBOOT ( PERMITTED );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/ecdsa.h>
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/asn1.h>
|
||||
@@ -43,10 +44,7 @@ struct asn1_algorithm ecdsa_with_sha256_algorithm __asn1_algorithm = {
|
||||
/** ECDSA with SHA-256 signature hash algorithm */
|
||||
struct tls_signature_hash_algorithm
|
||||
tls_ecdsa_sha256 __tls_sig_hash_algorithm = {
|
||||
.code = {
|
||||
.signature = TLS_ECDSA_ALGORITHM,
|
||||
.hash = TLS_SHA256_ALGORITHM,
|
||||
},
|
||||
.code = htons ( TLS_ECDSA_SHA256_ALGORITHM ),
|
||||
.pubkey = &ecdsa_algorithm,
|
||||
.digest = &sha256_algorithm,
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
FILE_SECBOOT ( PERMITTED );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/ecdsa.h>
|
||||
#include <ipxe/sha512.h>
|
||||
#include <ipxe/asn1.h>
|
||||
@@ -43,10 +44,7 @@ struct asn1_algorithm ecdsa_with_sha384_algorithm __asn1_algorithm = {
|
||||
/** ECDSA with SHA-384 signature hash algorithm */
|
||||
struct tls_signature_hash_algorithm
|
||||
tls_ecdsa_sha384 __tls_sig_hash_algorithm = {
|
||||
.code = {
|
||||
.signature = TLS_ECDSA_ALGORITHM,
|
||||
.hash = TLS_SHA384_ALGORITHM,
|
||||
},
|
||||
.code = htons ( TLS_ECDSA_SHA384_ALGORITHM ),
|
||||
.pubkey = &ecdsa_algorithm,
|
||||
.digest = &sha384_algorithm,
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
FILE_SECBOOT ( PERMITTED );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/ecdsa.h>
|
||||
#include <ipxe/sha512.h>
|
||||
#include <ipxe/asn1.h>
|
||||
@@ -43,10 +44,7 @@ struct asn1_algorithm ecdsa_with_sha512_algorithm __asn1_algorithm = {
|
||||
/** ECDSA with SHA-512 signature hash algorithm */
|
||||
struct tls_signature_hash_algorithm
|
||||
tls_ecdsa_sha512 __tls_sig_hash_algorithm = {
|
||||
.code = {
|
||||
.signature = TLS_ECDSA_ALGORITHM,
|
||||
.hash = TLS_SHA512_ALGORITHM,
|
||||
},
|
||||
.code = htons ( TLS_ECDSA_SHA512_ALGORITHM ),
|
||||
.pubkey = &ecdsa_algorithm,
|
||||
.digest = &sha512_algorithm,
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
FILE_SECBOOT ( PERMITTED );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/sha1.h>
|
||||
#include <ipxe/asn1.h>
|
||||
@@ -54,10 +55,7 @@ struct rsa_digestinfo_prefix rsa_sha1_prefix __rsa_digestinfo_prefix = {
|
||||
|
||||
/** RSA with SHA-1 signature hash algorithm */
|
||||
struct tls_signature_hash_algorithm tls_rsa_sha1 __tls_sig_hash_algorithm = {
|
||||
.code = {
|
||||
.signature = TLS_RSA_ALGORITHM,
|
||||
.hash = TLS_SHA1_ALGORITHM,
|
||||
},
|
||||
.code = htons ( TLS_RSA_SHA1_ALGORITHM ),
|
||||
.pubkey = &rsa_algorithm,
|
||||
.digest = &sha1_algorithm,
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
FILE_SECBOOT ( PERMITTED );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/asn1.h>
|
||||
@@ -54,10 +55,7 @@ struct rsa_digestinfo_prefix rsa_sha224_prefix __rsa_digestinfo_prefix = {
|
||||
|
||||
/** RSA with SHA-224 signature hash algorithm */
|
||||
struct tls_signature_hash_algorithm tls_rsa_sha224 __tls_sig_hash_algorithm = {
|
||||
.code = {
|
||||
.signature = TLS_RSA_ALGORITHM,
|
||||
.hash = TLS_SHA224_ALGORITHM,
|
||||
},
|
||||
.code = htons ( TLS_RSA_SHA224_ALGORITHM ),
|
||||
.pubkey = &rsa_algorithm,
|
||||
.digest = &sha224_algorithm,
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
FILE_SECBOOT ( PERMITTED );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/asn1.h>
|
||||
@@ -54,10 +55,7 @@ struct rsa_digestinfo_prefix rsa_sha256_prefix __rsa_digestinfo_prefix = {
|
||||
|
||||
/** RSA with SHA-256 signature hash algorithm */
|
||||
struct tls_signature_hash_algorithm tls_rsa_sha256 __tls_sig_hash_algorithm = {
|
||||
.code = {
|
||||
.signature = TLS_RSA_ALGORITHM,
|
||||
.hash = TLS_SHA256_ALGORITHM,
|
||||
},
|
||||
.code = htons ( TLS_RSA_SHA256_ALGORITHM ),
|
||||
.pubkey = &rsa_algorithm,
|
||||
.digest = &sha256_algorithm,
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
FILE_SECBOOT ( PERMITTED );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/sha512.h>
|
||||
#include <ipxe/asn1.h>
|
||||
@@ -54,10 +55,7 @@ struct rsa_digestinfo_prefix rsa_sha384_prefix __rsa_digestinfo_prefix = {
|
||||
|
||||
/** RSA with SHA-384 signature hash algorithm */
|
||||
struct tls_signature_hash_algorithm tls_rsa_sha384 __tls_sig_hash_algorithm = {
|
||||
.code = {
|
||||
.signature = TLS_RSA_ALGORITHM,
|
||||
.hash = TLS_SHA384_ALGORITHM,
|
||||
},
|
||||
.code = htons ( TLS_RSA_SHA384_ALGORITHM ),
|
||||
.pubkey = &rsa_algorithm,
|
||||
.digest = &sha384_algorithm,
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
FILE_SECBOOT ( PERMITTED );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/sha512.h>
|
||||
#include <ipxe/asn1.h>
|
||||
@@ -54,10 +55,7 @@ struct rsa_digestinfo_prefix rsa_sha512_prefix __rsa_digestinfo_prefix = {
|
||||
|
||||
/** RSA with SHA-512 signature hash algorithm */
|
||||
struct tls_signature_hash_algorithm tls_rsa_sha512 __tls_sig_hash_algorithm = {
|
||||
.code = {
|
||||
.signature = TLS_RSA_ALGORITHM,
|
||||
.hash = TLS_SHA512_ALGORITHM,
|
||||
},
|
||||
.code = htons ( TLS_RSA_SHA512_ALGORITHM ),
|
||||
.pubkey = &rsa_algorithm,
|
||||
.digest = &sha512_algorithm,
|
||||
};
|
||||
|
||||
+12
-21
@@ -113,17 +113,16 @@ struct tls_header {
|
||||
#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xc02f
|
||||
#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xc030
|
||||
|
||||
/* TLS hash algorithm identifiers */
|
||||
#define TLS_MD5_ALGORITHM 1
|
||||
#define TLS_SHA1_ALGORITHM 2
|
||||
#define TLS_SHA224_ALGORITHM 3
|
||||
#define TLS_SHA256_ALGORITHM 4
|
||||
#define TLS_SHA384_ALGORITHM 5
|
||||
#define TLS_SHA512_ALGORITHM 6
|
||||
|
||||
/* TLS signature algorithm identifiers */
|
||||
#define TLS_RSA_ALGORITHM 1
|
||||
#define TLS_ECDSA_ALGORITHM 3
|
||||
/* TLS signature hash algorithm identifiers */
|
||||
#define TLS_RSA_SHA1_ALGORITHM 0x0201
|
||||
#define TLS_RSA_SHA224_ALGORITHM 0x0301
|
||||
#define TLS_ECDSA_SHA224_ALGORITHM 0x0303
|
||||
#define TLS_RSA_SHA256_ALGORITHM 0x0401
|
||||
#define TLS_ECDSA_SHA256_ALGORITHM 0x0403
|
||||
#define TLS_RSA_SHA384_ALGORITHM 0x0501
|
||||
#define TLS_ECDSA_SHA384_ALGORITHM 0x0503
|
||||
#define TLS_RSA_SHA512_ALGORITHM 0x0601
|
||||
#define TLS_ECDSA_SHA512_ALGORITHM 0x0603
|
||||
|
||||
/* TLS server name extension */
|
||||
#define TLS_SERVER_NAME 0
|
||||
@@ -279,22 +278,14 @@ struct tls_cipherspec_pair {
|
||||
struct tls_cipherspec pending;
|
||||
};
|
||||
|
||||
/** A TLS signature and hash algorithm identifier */
|
||||
struct tls_signature_hash_id {
|
||||
/** Hash algorithm */
|
||||
uint8_t hash;
|
||||
/** Signature algorithm */
|
||||
uint8_t signature;
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/** A TLS signature algorithm */
|
||||
struct tls_signature_hash_algorithm {
|
||||
/** Digest algorithm */
|
||||
struct digest_algorithm *digest;
|
||||
/** Public-key algorithm */
|
||||
struct pubkey_algorithm *pubkey;
|
||||
/** Numeric code */
|
||||
struct tls_signature_hash_id code;
|
||||
/** Numeric code (in network-endian order) */
|
||||
uint16_t code;
|
||||
};
|
||||
|
||||
/** TLS signature hash algorithm table
|
||||
|
||||
+18
-34
@@ -1033,38 +1033,19 @@ tls_signature_hash_algorithm ( struct pubkey_algorithm *pubkey,
|
||||
}
|
||||
|
||||
/**
|
||||
* Find TLS signature algorithm
|
||||
* Find TLS signature and hash algorithm
|
||||
*
|
||||
* @v code Signature and hash algorithm identifier
|
||||
* @ret pubkey Public key algorithm, or NULL
|
||||
* @ret sig_hash Signature and hash algorithm, or NULL
|
||||
*/
|
||||
static struct pubkey_algorithm *
|
||||
tls_signature_hash_pubkey ( struct tls_signature_hash_id code ) {
|
||||
static struct tls_signature_hash_algorithm *
|
||||
tls_find_signature_hash ( unsigned int code ) {
|
||||
struct tls_signature_hash_algorithm *sig_hash;
|
||||
|
||||
/* Identify signature and hash algorithm */
|
||||
for_each_table_entry ( sig_hash, TLS_SIG_HASH_ALGORITHMS ) {
|
||||
if ( sig_hash->code.signature == code.signature )
|
||||
return sig_hash->pubkey;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find TLS hash algorithm
|
||||
*
|
||||
* @v code Signature and hash algorithm identifier
|
||||
* @ret digest Digest algorithm, or NULL
|
||||
*/
|
||||
static struct digest_algorithm *
|
||||
tls_signature_hash_digest ( struct tls_signature_hash_id code ) {
|
||||
struct tls_signature_hash_algorithm *sig_hash;
|
||||
|
||||
/* Identify signature and hash algorithm */
|
||||
for_each_table_entry ( sig_hash, TLS_SIG_HASH_ALGORITHMS ) {
|
||||
if ( sig_hash->code.hash == code.hash )
|
||||
return sig_hash->digest;
|
||||
if ( sig_hash->code == code )
|
||||
return sig_hash;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1199,8 +1180,7 @@ static int tls_client_hello ( struct tls_connection *tls,
|
||||
uint16_t len;
|
||||
struct {
|
||||
uint16_t len;
|
||||
struct tls_signature_hash_id
|
||||
code[TLS_NUM_SIG_HASH_ALGORITHMS];
|
||||
uint16_t code[TLS_NUM_SIG_HASH_ALGORITHMS];
|
||||
} __attribute__ (( packed )) data;
|
||||
} __attribute__ (( packed )) *signature_algorithms_ext;
|
||||
struct {
|
||||
@@ -1502,11 +1482,12 @@ struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm = {
|
||||
static int tls_verify_dh_params ( struct tls_connection *tls,
|
||||
size_t param_len ) {
|
||||
struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
|
||||
struct tls_signature_hash_algorithm *sig_hash;
|
||||
struct pubkey_algorithm *pubkey;
|
||||
struct digest_algorithm *digest;
|
||||
int use_sig_hash = tls_version ( tls, TLS_VERSION_TLS_1_2 );
|
||||
const struct {
|
||||
struct tls_signature_hash_id sig_hash[use_sig_hash];
|
||||
uint16_t sig_hash[use_sig_hash];
|
||||
uint16_t signature_len;
|
||||
uint8_t signature[0];
|
||||
} __attribute__ (( packed )) *sig;
|
||||
@@ -1536,13 +1517,16 @@ static int tls_verify_dh_params ( struct tls_connection *tls,
|
||||
|
||||
/* Identify signature and hash algorithm */
|
||||
if ( use_sig_hash ) {
|
||||
pubkey = tls_signature_hash_pubkey ( sig->sig_hash[0] );
|
||||
digest = tls_signature_hash_digest ( sig->sig_hash[0] );
|
||||
if ( ( ! pubkey ) || ( ! digest ) ) {
|
||||
DBGC ( tls, "TLS %p ServerKeyExchange unsupported "
|
||||
"signature and hash algorithm\n", tls );
|
||||
sig_hash = tls_find_signature_hash ( sig->sig_hash[0] );
|
||||
if ( ! sig_hash ) {
|
||||
DBGC ( tls, "TLS %p unsupported signature hash "
|
||||
"%#04x\n", tls, sig->sig_hash[0] );
|
||||
return -ENOTSUP_SIG_HASH;
|
||||
}
|
||||
pubkey = sig_hash->pubkey;
|
||||
digest = sig_hash->digest;
|
||||
DBGC ( tls, "TLS %p using signature hash %s-%s\n",
|
||||
tls, pubkey->name, digest->name );
|
||||
if ( pubkey != cipherspec->suite->pubkey ) {
|
||||
DBGC ( tls, "TLS %p ServerKeyExchange incorrect "
|
||||
"signature algorithm %s (expected %s)\n", tls,
|
||||
@@ -1910,7 +1894,7 @@ static int tls_send_certificate_verify ( struct tls_connection *tls ) {
|
||||
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 sig_hash[use_sig_hash];
|
||||
uint16_t signature_len;
|
||||
} __attribute__ (( packed )) header;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user