Skip to content

Commit 3798fdd

Browse files
authored
Merge pull request #262 from jtesta/key_exchange_fix
Fix for invalid x25519 key share causing TLSv1.3 being skipped against Windows Server 2022 hosts
2 parents 0a6acce + 107b877 commit 3798fdd

File tree

1 file changed

+49
-19
lines changed

1 file changed

+49
-19
lines changed

sslscan.c

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4862,6 +4862,43 @@ int bs_read_socket(bs *b, int s, size_t num_bytes) {
48624862
}
48634863

48644864

4865+
/* Internal function. Use bs_append_x25519_pubkey() and bs_append_x448_pubkey() instead. */
4866+
void __bs_append_xstar_pubkey(bs *b, unsigned int gen_x25519) {
4867+
unsigned char public_key[64] = {0}; /* X25519 requires 32 bytes minimum, and X448 requires 56 bytes minimum. */
4868+
size_t public_key_len = sizeof(public_key);
4869+
EVP_PKEY *pkey = NULL;
4870+
EVP_PKEY_CTX *pctx = NULL;
4871+
4872+
4873+
/* Create an X25519 or X448 key depending on which is requested. */
4874+
if (gen_x25519)
4875+
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
4876+
else
4877+
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X448, NULL);
4878+
4879+
/* Create the private and public keys, and append the raw public key to the byte string. */
4880+
EVP_PKEY_keygen_init(pctx);
4881+
EVP_PKEY_keygen(pctx, &pkey);
4882+
EVP_PKEY_get_raw_public_key(pkey, public_key, &public_key_len);
4883+
bs_append_bytes(b, public_key, public_key_len);
4884+
4885+
EVP_PKEY_free(pkey); pkey = NULL;
4886+
EVP_PKEY_CTX_free(pctx); pctx = NULL;
4887+
}
4888+
4889+
4890+
/* Generates a random x25519 public key and appends it to the byte string. */
4891+
void bs_append_x25519_pubkey(bs *b) {
4892+
__bs_append_xstar_pubkey(b, 1);
4893+
}
4894+
4895+
4896+
/* Generates a random x448 public key and appends it to the byte string. */
4897+
void bs_append_x448_pubkey(bs *b) {
4898+
__bs_append_xstar_pubkey(b, 0);
4899+
}
4900+
4901+
48654902
/* Returns true if a specific TLS version is supported by the server. */
48664903
unsigned int checkIfTLSVersionIsSupported(struct sslCheckOptions *options, unsigned int tls_version) {
48674904
bs *tls_extensions = NULL, *ciphersuite_list = NULL, *client_hello = NULL, *server_hello = NULL;
@@ -5165,12 +5202,8 @@ void tlsExtensionAddDefaultKeyShare(bs *tls_extensions) {
51655202
0x00, 0x20, // Key Exchange Length (32)
51665203
}, 10);
51675204

5168-
/* Add 32 bytes of the (bogus) X25519 key share. */
5169-
srand(time(NULL) ^ 0xbeefdead);
5170-
for (int i = 0; i < 32; i++) {
5171-
unsigned char c = (unsigned char)rand();
5172-
bs_append_bytes(tls_extensions, &c, 1);
5173-
}
5205+
/* Append a random X25519 public key. */
5206+
bs_append_x25519_pubkey(tls_extensions);
51745207

51755208
/* Update the length of the extensions. */
51765209
tlsExtensionUpdateLength(tls_extensions);
@@ -5453,9 +5486,11 @@ int testSupportedGroups(struct sslCheckOptions *options) {
54535486

54545487
/* Auto-generated by ./tools/iana_tls_supported_groups_parser.py on December 24, 2019. */
54555488
#define COL_PLAIN ""
5456-
#define NID_TYPE_NA 0 /* Not Applicable (i.e.: X25519/X448) */
5489+
#define NID_TYPE_UNUSED 0
54575490
#define NID_TYPE_ECDHE 1 /* For ECDHE curves (sec*, P-256/384-521) */
54585491
#define NID_TYPE_DHE 2 /* For ffdhe* */
5492+
#define NID_TYPE_X25519 3
5493+
#define NID_TYPE_X448 4
54595494
/* Bit strength of DHE 2048 and 3072-bit moduli is taken directly from NIST SP 800-57 pt.1, rev4., pg. 53; DHE 4096, 6144, and 8192 are estimated using that document. */
54605495
struct group_key_exchange group_key_exchanges[] = {
54615496
{0x0001, "sect163k1", 81, COL_RED, NID_sect163k1, NID_TYPE_ECDHE, 0},
@@ -5486,8 +5521,8 @@ int testSupportedGroups(struct sslCheckOptions *options) {
54865521
{0x001a, "brainpoolP256r1", 128, COL_PLAIN, NID_brainpoolP256r1, NID_TYPE_ECDHE, 0},
54875522
{0x001b, "brainpoolP384r1", 192, COL_PLAIN, NID_brainpoolP384r1, NID_TYPE_ECDHE, 0},
54885523
{0x001c, "brainpoolP512r1", 256, COL_PLAIN, NID_brainpoolP512r1, NID_TYPE_ECDHE, 0},
5489-
{0x001d, "x25519", 128, COL_GREEN, -1, NID_TYPE_NA, 32},
5490-
{0x001e, "x448", 224, COL_GREEN, -1, NID_TYPE_NA, 56},
5524+
{0x001d, "x25519", 128, COL_GREEN, -1, NID_TYPE_X25519, 32},
5525+
{0x001e, "x448", 224, COL_GREEN, -1, NID_TYPE_X448, 56},
54915526
{0x0100, "ffdhe2048", 112, COL_PLAIN, NID_ffdhe2048, NID_TYPE_DHE, 256},
54925527
{0x0101, "ffdhe3072", 128, COL_PLAIN, NID_ffdhe3072, NID_TYPE_DHE, 384},
54935528
{0x0102, "ffdhe4096", 150, COL_PLAIN, NID_ffdhe4096, NID_TYPE_DHE, 512},
@@ -5541,16 +5576,11 @@ int testSupportedGroups(struct sslCheckOptions *options) {
55415576
bs_new_size(&key_exchange, key_exchange_len);
55425577

55435578
/* Generate the right type of key exchange data. */
5544-
if (nid_type == NID_TYPE_NA) {
5545-
5546-
/* Generate "random" data. X25519 and X448 public keys have no discernible structure. */
5547-
srand(time(NULL) ^ 0xdeadbeef);
5548-
for (int j = 0; j < key_exchange_len; j++) {
5549-
unsigned char c = (unsigned char)rand();
5550-
bs_append_bytes(key_exchange, &c, 1);
5551-
}
5552-
5553-
} else if (nid_type == NID_TYPE_ECDHE) {
5579+
if (nid_type == NID_TYPE_X25519)
5580+
bs_append_x25519_pubkey(key_exchange);
5581+
else if (nid_type == NID_TYPE_X448)
5582+
bs_append_x448_pubkey(key_exchange);
5583+
else if (nid_type == NID_TYPE_ECDHE) {
55545584

55555585
/* Generate the ECDHE key. */
55565586
EC_KEY *key = EC_KEY_new_by_curve_name(nid);

0 commit comments

Comments
 (0)