From: Georgios Kontaxis Date: Tue, 15 May 2018 06:31:10 +0000 (-0700) Subject: Added support for ServerKeyExchange TLS handshake messages. X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=80d60a809212f2cea7725dc85455f09bdb10730a;p=starttls.git Added support for ServerKeyExchange TLS handshake messages. --- diff --git a/scan/_Makefile b/scan/_Makefile index 47b2aad..2f6f491 100644 --- a/scan/_Makefile +++ b/scan/_Makefile @@ -61,5 +61,5 @@ bin/replay: src/replay.c src/tls* src/ciphersuites.h src/aux.h src/replay.c src/tls.c -o bin/replay clean: - rm -rf bin ssl.* ssl.replay.dbg x509-*.der + rm -rf bin ssl.* ssl.replay.dbg x509-*.der server_kx_dh-* rm -i Makefile diff --git a/scan/src/ciphersuites.h b/scan/src/ciphersuites.h index 8fcdca3..240c115 100644 --- a/scan/src/ciphersuites.h +++ b/scan/src/ciphersuites.h @@ -326,7 +326,7 @@ CipherSuite CipherSuites[CIPHERSUITES] = { #endif /* == (Emphemeral)Diffie-Hellman Exchange == */ - + #if __SSL_3_0__ || __TLS_1_0__ || __TLS_GOD__ /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */ 0x000B, #endif @@ -66127,10 +66127,179 @@ const char * CipherSuiteNames[CIPHERSUITESMAX + 1] = { "ERR_NOT_IMPLEMENTED ", /* 0xFFFF */ }; +/* + * Extract the key exchange algorithm from a given ciphersuite and test + * against known algorithms. + */ +#define KEYEXCHANGE_UNKNOWN ((0 << 0) & 0xFFFFFFFF) +#define KEYEXCHANGE_DHE_DSS ((1 << 0) & 0xFFFFFFFF) +#define KEYEXCHANGE_DHE_RSA ((1 << 1) & 0xFFFFFFFF) +#define KEYEXCHANGE_DH_ANON ((1 << 2) & 0xFFFFFFFF) +#define KEYEXCHANGE_RSA ((1 << 3) & 0xFFFFFFFF) +#define KEYEXCHANGE_DH_DSS ((1 << 4) & 0xFFFFFFFF) +#define KEYEXCHANGE_DH_RSA ((1 << 5) & 0xFFFFFFFF) + +#define HAS_KEYEXCHANGE_DHPARAMS(n) (n & (\ + KEYEXCHANGE_DH_ANON | \ + KEYEXCHANGE_DHE_DSS | \ + KEYEXCHANGE_DHE_RSA)) + +#define HAS_KEYEXCHANGE_DHPARAMS_SIGNED(n) (n & (\ + KEYEXCHANGE_DHE_DSS | \ + KEYEXCHANGE_DHE_RSA)) + +#define IS_CIPHERSUITE_KEYEXCHANGE_DH_ANON(n) (\ + CipherSuite_KeyExchangeAlgorithm(n) & CIPHERSUITE_KEYEXCHANGE_DH_ANON) + +#define IS_CIPHERSUITE_KEYEXCHANGE_DHE_DSS(n) (\ + CipherSuite_KeyExchangeAlgorithm(n) & CIPHERSUITE_KEYEXCHANGE_DHE_DSS) + +#define IS_CIPHERSUITE_KEYEXCHANGE_DHE_RSA(n) (\ + CipherSuite_KeyExchangeAlgorithm(n) & CIPHERSUITE_KEYEXCHANGE_DHE_RSA) + +#define IS_CIPHERSUITE_KEYEXCHANGE_RSA(n) (\ + CipherSuite_KeyExchangeAlgorithm(n) & CIPHERSUITE_KEYEXCHANGE_RSA) + +#define IS_CIPHERSUITE_KEYEXCHANGE_DH_DSS(n) (\ + CipherSuite_KeyExchangeAlgorithm(n) & CIPHERSUITE_KEYEXCHANGE_DH_DSS) + +#define IS_CIPHERSUITE_KEYEXCHANGE_DH_RSA(n) (\ + CipherSuite_KeyExchangeAlgorithm(n) & CIPHERSUITE_KEYEXCHANGE_DH_RSA) + +uint32_t CipherSuite_KeyExchangeAlgorithm (uint16_t ciphersuite) +{ + switch (ciphersuite) + { + /* TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 */ case 0x0017: + /* TLS_DH_anon_WITH_RC4_128_MD5 */ case 0x0018: + /* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA */ case 0x0019: + /* TLS_DH_anon_WITH_DES_CBC_SHA */ case 0x001A: + /* TLS_DH_anon_WITH_3DES_EDE_CBC_SHA */ case 0x001B: + /* TLS_DH_anon_WITH_AES_128_CBC_SHA */ case 0x0034: + /* TLS_DH_anon_WITH_AES_256_CBC_SHA */ case 0x003A: + /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */ case 0x006C: + /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */ case 0x006D: + /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA */ case 0x0046: + /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA */ case 0x0089: + /* TLS_DH_anon_WITH_SEED_CBC_SHA */ case 0x009B: + /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */ case 0x00A6: + /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */ case 0x00A7: + /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 */ case 0x00BF: + /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */ case 0x00C5: + return KEYEXCHANGE_DH_ANON; + break; + /* TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA */ case 0x0011: + /* TLS_DHE_DSS_WITH_DES_CBC_SHA */ case 0x0012: + /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA */ case 0x0013: + /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA */ case 0x0032: + /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA */ case 0x0038: + /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 */ case 0x0040: + /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 */ case 0x006A: + /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA */ case 0x0044: + /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA */ case 0x0087: + /* TLS_DHE_DSS_WITH_SEED_CBC_SHA */ case 0x0099: + /* TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 */ case 0x00A2: + /* TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 */ case 0x00A3: + /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 */ case 0x00BD: + /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 */ case 0x00C3: + /* TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA */ case 0x0063: + /* TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA */ case 0x0065: + /* TLS_DHE_DSS_WITH_RC4_128_SHA */ case 0x0066: + return KEYEXCHANGE_DHE_DSS; + break; + /* TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA */ case 0x0014: + /* TLS_DHE_RSA_WITH_DES_CBC_SHA */ case 0x0015: + /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */ case 0x0016: + /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */ case 0x0033: + /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */ case 0x0039: + /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */ case 0x0067: + /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */ case 0x006B: + /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA */ case 0x0045: + /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA */ case 0x0088: + /* TLS_DHE_RSA_WITH_SEED_CBC_SHA */ case 0x009A: + /* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 */ case 0x009E: + /* TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 */ case 0x009F: + /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */ case 0x00BE: + /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */ case 0x00C4: + return KEYEXCHANGE_DHE_RSA; + break; + /* TLS_RSA_WITH_NULL_MD5 */ case 0x0001: + /* TLS_RSA_WITH_NULL_SHA */ case 0x0002: + /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 */ case 0x0003: + /* TLS_RSA_WITH_RC4_128_MD5 */ case 0x0004: + /* TLS_RSA_WITH_RC4_128_SHA */ case 0x0005: + /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */ case 0x0006: + /* TLS_RSA_WITH_IDEA_CBC_SHA */ case 0x0007: + /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA */ case 0x0008: + /* TLS_RSA_WITH_DES_CBC_SHA */ case 0x0009: + /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */ case 0x000A: + /* TLS_RSA_WITH_AES_128_CBC_SHA */ case 0x002F: + /* TLS_RSA_WITH_AES_256_CBC_SHA */ case 0x0035: + /* TLS_RSA_WITH_NULL_SHA256 */ case 0x003B: + /* TLS_RSA_WITH_AES_128_CBC_SHA256 */ case 0x003C: + /* TLS_RSA_WITH_AES_256_CBC_SHA256 */ case 0x003D: + /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */ case 0x0041: + /* TLS_RSA_EXPORT1024_WITH_RC4_56_MD5 */ case 0x0060: + /* TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 */ case 0x0061: + /* TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA */ case 0x0062: + /* TLS_RSA_EXPORT1024_WITH_RC4_56_SHA */ case 0x0064: + /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */ case 0x0084: + /* TLS_RSA_PSK_WITH_RC4_128_SHA */ case 0x0092: + /* TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA */ case 0x0093: + /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA */ case 0x0094: + /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA */ case 0x0095: + /* TLS_RSA_WITH_SEED_CBC_SHA */ case 0x0096: + /* TLS_RSA_WITH_AES_128_GCM_SHA256 */ case 0x009C: + /* TLS_RSA_WITH_AES_256_GCM_SHA384 */ case 0x009D: + /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */ case 0x00BA: + /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */ case 0x00C0: + return KEYEXCHANGE_RSA; + break; + /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */ case 0x000B: + /* TLS_DH_DSS_WITH_DES_CBC_SHA */ case 0x000C: + /* TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA */ case 0x000D: + /* TLS_DH_DSS_WITH_AES_128_CBC_SHA */ case 0x0030: + /* TLS_DH_DSS_WITH_AES_256_CBC_SHA */ case 0x0036: + /* TLS_DH_DSS_WITH_AES_128_CBC_SHA256 */ case 0x003E: + /* TLS_DH_DSS_WITH_AES_256_CBC_SHA256 */ case 0x0068: + /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA */ case 0x0042: + /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA */ case 0x0085: + /* TLS_DH_DSS_WITH_SEED_CBC_SHA */ case 0x0097: + /* TLS_DH_DSS_WITH_AES_128_GCM_SHA256 */ case 0x00A4: + /* TLS_DH_DSS_WITH_AES_256_GCM_SHA384 */ case 0x00A5: + /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 */ case 0x00BB: + /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 */ case 0x00C1: + return KEYEXCHANGE_DH_DSS; + break; + /* TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */ case 0x000E: + /* TLS_DH_RSA_WITH_DES_CBC_SHA */ case 0x000F: + /* TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA */ case 0x0010: + /* TLS_DH_RSA_WITH_AES_128_CBC_SHA */ case 0x0031: + /* TLS_DH_RSA_WITH_AES_256_CBC_SHA */ case 0x0037: + /* TLS_DH_RSA_WITH_AES_128_CBC_SHA256 */ case 0x003F: + /* TLS_DH_RSA_WITH_AES_256_CBC_SHA256 */ case 0x0069: + /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA */ case 0x0043: + /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA */ case 0x0086: + /* TLS_DH_RSA_WITH_SEED_CBC_SHA */ case 0x0098: + /* TLS_DH_RSA_WITH_AES_128_GCM_SHA256 */ case 0x00A0: + /* TLS_DH_RSA_WITH_AES_256_GCM_SHA384 */ case 0x00A1: + /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */ case 0x00BC: + /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 */ case 0x00C2: + return KEYEXCHANGE_DH_RSA; + break; + default: + return KEYEXCHANGE_UNKNOWN; + break; + } + + return KEYEXCHANGE_UNKNOWN; +} + /* Largest compression number */ #define COMPRESSIONMAX 0 -#define COMPRESSION_TXT(n) (((n) >= 0 && (n) <= PROTOCOLMAX) ? Compression[(n)] : "UNKNOWN") +#define COMPRESSION_TXT(n) (\ + ((n) >= 0 && (n) <= COMPRESSIONMAX) ? Compression[(n)] : "UNKNOWN") char * Compression[COMPRESSIONMAX + 1] = { "null" diff --git a/scan/src/replay.c b/scan/src/replay.c index a748f58..b83a677 100644 --- a/scan/src/replay.c +++ b/scan/src/replay.c @@ -1,17 +1,19 @@ /* kontaxis 2014-10-06 */ -#include -#include +#include #include +#include #include -#include +#include +#include #include "tls_api.h" #define CRT_FNAME_TMPL "x509-NN.der" #define CRT_FNAME_MXSZ sizeof(CRT_FNAME_TMPL) -int certificate_handler (uint8_t *certificate, uint32_t certificate_length) +int tls_handshake_certificate_handler ( + uint8_t *certificate, uint32_t certificate_length) { static uint32_t crt_count = 0; char crt_fname[CRT_FNAME_MXSZ]; @@ -19,12 +21,19 @@ int certificate_handler (uint8_t *certificate, uint32_t certificate_length) uint32_t i; - fprintf(stderr, ">> Certificate %u bytes\n>> ", certificate_length); - for (i = 0; i < 30; i++) { + fprintf(stderr, ">> Certificate %u bytes\n", certificate_length); + if (certificate_length > 0) { + fprintf(stderr, ">> "); + } + for (i = 0; i < 30 && i < certificate_length; i++) { fprintf(stderr, "0x%02x ", certificate[i]); - if ((i + 1) % 10 == 0) fprintf(stderr, "\n>> "); + if ((i + 1) % 10 == 0) { + fprintf(stderr, "\n>> "); + } + } + if (certificate_length > 0) { + fprintf(stderr, "[...]\n"); } - fprintf(stderr, "[...]\n"); /* Output the certificate in its original format (DER). * Since certificate_handler() with certificates in the order they appear @@ -35,13 +44,17 @@ int certificate_handler (uint8_t *certificate, uint32_t certificate_length) * Hint: openssl x509 -inform DER -text -noout -in x509-0.der */ if (crt_count > 99) { - crt_count = 0; - } - snprintf(crt_fname, CRT_FNAME_MXSZ, "x509-%d.der", crt_count); - if ((fd = open(crt_fname, O_RDWR | O_TRUNC | O_CREAT, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { - perror("open"); + fprintf(stderr, + ">> [!] Certificate output to files has been truncated.\n"); + fd = -1; } else { + snprintf(crt_fname, CRT_FNAME_MXSZ, "x509-%02d.der", crt_count); + if ((fd = open(crt_fname, O_RDWR | O_TRUNC | O_CREAT, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { + perror("open"); + } + } + if (fd != -1) { if (write(fd, certificate, certificate_length) != certificate_length) { perror("write"); } @@ -55,10 +68,162 @@ int certificate_handler (uint8_t *certificate, uint32_t certificate_length) return 0; } +#define n16toh16(n) \ +((uint16_t) (((uint16_t) n) << 8) | (uint16_t) (((uint16_t) n) >> 8)) + +#define SERVER_KX_DH_FNAME_TMPL "server_kx_dh-NN" +#define SERVER_KX_DH_FNAME_MXSZ sizeof(SERVER_KX_DH_FNAME_TMPL) + +int tls_handshake_server_key_exchange_dh_handler ( + struct ServerDHParams *params) +{ + static uint32_t kx_dh_count = 0; + char kx_dh_fname[SERVER_KX_DH_FNAME_MXSZ]; + FILE *fp; + + uint32_t i; + + /* Prime modulus for the Diffie-Hellman operation. */ + + fprintf(stderr, ">> Diffie-Hellman Prime Modulus Length: %u\n", + n16toh16(params->dh_p_length)); + + if (n16toh16(params->dh_p_length) > 0) { + fprintf(stderr, ">> "); + } + for (i = 0; i < 30 && i < n16toh16(params->dh_p_length); i++) { + fprintf(stderr, "0x%02x ", params->dh_p[i]); + if ((i + 1) % 10 == 0) { + fprintf(stderr, "\n>> "); + } + } + if (n16toh16(params->dh_p_length) > 0) { + fprintf(stderr, "[...]\n"); + } + + /* Generator used for the Diffie-Hellman operation. */ + + fprintf(stderr, ">> Diffie-Hellman Generator Length: %u\n", + n16toh16(params->dh_g_length)); + + if (n16toh16(params->dh_g_length) > 0) { + fprintf(stderr, ">> "); + } + for (i = 0; i < 30 && i < n16toh16(params->dh_g_length); i++) { + fprintf(stderr, "0x%02x ", params->dh_g[i]); + if ((i + 1) % 10 == 0) { + fprintf(stderr, "\n>> "); + } + } + if (n16toh16(params->dh_g_length) > 0) { + fprintf(stderr, "[...]\n"); + } + + /* The server's Diffie-Hellman public value (g^X mod p). */ + + fprintf(stderr, ">> Diffie-Hellman Public Value Length: %u\n", + n16toh16(params->dh_Ys_length)); + + if (n16toh16(params->dh_Ys_length) > 0) { + fprintf(stderr, ">> "); + } + for (i = 0; i < 30 && i < n16toh16(params->dh_Ys_length); i++) { + fprintf(stderr, "0x%02x ", params->dh_Ys[i]); + if ((i + 1) % 10 == 0) { + fprintf(stderr, "\n>> "); + } + } + if (n16toh16(params->dh_Ys_length) > 0) { + fprintf(stderr, "[...]\n"); + } + + /* Write to disk. */ + + if (kx_dh_count > 99) { + fprintf(stderr, + ">> [!] ServerKeyExchange output to files has been truncated.\n"); + fp = NULL; + } else { + snprintf(kx_dh_fname, SERVER_KX_DH_FNAME_MXSZ, "server_kx_dh-%02d", + kx_dh_count); + if ((fp = fopen(kx_dh_fname, "w")) == NULL) { + perror("fopen"); + } + } + if (fp) { + fprintf(fp, "Diffie-Hellman Server Params\n"); + + fprintf(fp, "p Length: %u\n", n16toh16(params->dh_p_length)); + + if (n16toh16(params->dh_p_length) > 0) { + fprintf(fp, "p: "); + } + for (i = 0; i < n16toh16(params->dh_p_length); i++) { + fprintf(fp, "%02x", params->dh_p[i]); + } + if (n16toh16(params->dh_p_length) > 0) { + fprintf(fp, "\n"); + } + + fprintf(fp, "g Length: %u\n", n16toh16(params->dh_g_length)); + + if (n16toh16(params->dh_g_length) > 0) { + fprintf(fp, "g: "); + } + for (i = 0; i < n16toh16(params->dh_g_length); i++) { + fprintf(fp, "%02x", params->dh_g[i]); + } + if (n16toh16(params->dh_g_length) > 0) { + fprintf(fp, "\n"); + } + + fprintf(fp, "Pubkey Length: %u\n", n16toh16(params->dh_Ys_length)); + + if (n16toh16(params->dh_Ys_length) > 0) { + fprintf(fp, "Pubkey: "); + } + for (i = 0; i < n16toh16(params->dh_Ys_length); i++) { + fprintf(fp, "%02x", params->dh_Ys[i]); + } + if (n16toh16(params->dh_Ys_length) > 0) { + fprintf(fp, "\n"); + } + + if (fclose(fp) != 0) { + perror("fclose"); + } + } + kx_dh_count += 1; + + return 0; +} + +int tls_handshake_server_key_exchange_handler (uint8_t *ServerKeyExchange, + uint32_t ServerKeyExchangeType) +{ + /* + * { + * ServerDHParams params; + * [...] + * } ServerKeyExchange; + */ + if (ServerKeyExchangeType & SERVER_KEYEXCHANGE_DHPARAMS) { + struct ServerKeyExchange_DHparams *kx = + (struct ServerKeyExchange_DHparams *)ServerKeyExchange; + tls_handshake_server_key_exchange_dh_handler(kx->params); + return 0; + } + + return 0; +} + int main (int argc, char *argv[]) { int r; int tls_trace_fd; + int tls_dbg_o_fd; + + char *tls_trace_path; if (argc < 2) { tls_print_version(); @@ -72,13 +237,34 @@ int main (int argc, char *argv[]) return -1; } + if ((tls_dbg_o_fd = open("ssl.replay.dbg", O_CREAT | O_RDWR | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { + perror("open"); + return -1; + } + + /* Set the current working directory to where the trace file is. + * This results in new files being created (e.g., x509-*.der) in + * the same directory as the trace itself. + * Failure to change directory is not a deal breaker. */ + tls_trace_path = dirname(argv[1]); + if (chdir(tls_trace_path) == -1) { + perror("chdir"); + } + tls_init(); tls_set_in(tls_trace_fd); + tls_set_out(tls_dbg_o_fd); + /* register callback to receive individual ASN1 certificates * from Certificate handshake message */ - tls_set_cb_cert(&certificate_handler); + tls_set_callback_handshake_certificate(&tls_handshake_certificate_handler); + + /* register callback to receive ServerKeyExchange messages */ + tls_set_callback_handshake_server_key_exchange( + &tls_handshake_server_key_exchange_handler); r = tls_replay(); diff --git a/scan/src/test/dump/verify.sh b/scan/src/test/dump/verify.sh index 4c7b1b5..42bb8a7 100755 --- a/scan/src/test/dump/verify.sh +++ b/scan/src/test/dump/verify.sh @@ -56,7 +56,9 @@ for c in {0x00,0x04}; do # try with an unsupported and a supported cipher echo "Running prober..." ${e} -t ${target} -p 25 -x ${c} > smtp.txt 2> log.txt r=$? - if [ "${r}" != "0" ] && [ "${r}" != "30" ]; then + # 4: ERROR_NONE (Success) + # 30: ERROR_TLS (TLS handshake failed, e.g., unsupported ciphersuite) + if [ "${r}" != "4" ] && [ "${r}" != "30" ]; then >&2 echo "Fatal. Trouble(${r}). Check log.txt"; exit 1; fi diff --git a/scan/src/tls.c b/scan/src/tls.c index 5a33ed6..af593f6 100644 --- a/scan/src/tls.c +++ b/scan/src/tls.c @@ -63,7 +63,7 @@ unsigned int tls_initialized = 0; /* * process a TLS Handshake ClientHello message */ -int process_TLS_Handshake_ClientHello() +int tls_process_Handshake_ClientHello() { #if __DEBUG__ unsigned int i; @@ -78,63 +78,63 @@ int process_TLS_Handshake_ClientHello() char time_buf[80]; #endif - assert(n24toh32(TLSHandshake_header.Handshake__length) >= - sizeof(client_hello_min)); + assert(n24toh32(tls_Handshake_header.Handshake__length) >= + sizeof(tls_ClientHello_min)); - must_read_bytes = n24toh32(TLSHandshake_header.Handshake__length); + must_read_bytes = n24toh32(tls_Handshake_header.Handshake__length); /* Read up to the session ID length byte. Since the session ID * is of variable length we need to figure out how much to read as such. */ - if (read_bytes(tls_in, &client_hello_intro, - sizeof(client_hello_intro)) <= 0) { + if (read_bytes(tls_in, &tls_ClientHello_intro, + sizeof(tls_ClientHello_intro)) <= 0) { return -1; } - must_read_bytes -= sizeof(client_hello_intro); + must_read_bytes -= sizeof(tls_ClientHello_intro); #if __DEBUG__ fprintf(stderr, "TLS ClientHello Version: %s (0x%02x%02x)\n", - PROTOCOL_TXT(client_hello_intro.client_version_minor), - client_hello_intro.client_version_major, - client_hello_intro.client_version_minor); + PROTOCOL_TXT(tls_ClientHello_intro.client_version_minor), + tls_ClientHello_intro.client_version_major, + tls_ClientHello_intro.client_version_minor); - t = ntohl(client_hello_intro.random_gmt_unix_time); + t = ntohl(tls_ClientHello_intro.random_gmt_unix_time); ts = localtime(&t); if (strftime(time_buf, sizeof(time_buf), "%b %d, %Y %H:%M:%S %Z", ts)) { fprintf(stderr, "TLS ClientHello Random gmt_unix_time: %s (%u)\n", - time_buf, ntohl(client_hello_intro.random_gmt_unix_time)); + time_buf, ntohl(tls_ClientHello_intro.random_gmt_unix_time)); } fprintf(stderr, "TLS ClientHello Random random_bytes: "); for (i = 0; i < 28; i++) - fprintf(stderr, "%02x", client_hello_intro.random_random_bytes[i]); + fprintf(stderr, "%02x", tls_ClientHello_intro.random_random_bytes[i]); fprintf(stderr, "\n"); #endif /* log */ if (tls_out != -1) { - r = write(tls_out, &client_hello_intro, sizeof(client_hello_intro)); + r = write(tls_out, &tls_ClientHello_intro, sizeof(tls_ClientHello_intro)); if (r == 0 || r == -1) { perror("write"); return -1; } } - if (read_bytes(tls_in, &client_hello_session.session_id_length, - sizeof(client_hello_session.session_id_length)) <= 0) { + if (read_bytes(tls_in, &tls_ClientHello_session.session_id_length, + sizeof(tls_ClientHello_session.session_id_length)) <= 0) { return -1; } - must_read_bytes -= sizeof(client_hello_session.session_id_length); + must_read_bytes -= sizeof(tls_ClientHello_session.session_id_length); #if __DEBUG__ fprintf(stderr, "TLS ClientHello Session ID Length: %u\n", - client_hello_session.session_id_length); + tls_ClientHello_session.session_id_length); #endif /* log */ if (tls_out != -1) { - r = write(tls_out, &client_hello_session.session_id_length, - sizeof(client_hello_session.session_id_length)); + r = write(tls_out, &tls_ClientHello_session.session_id_length, + sizeof(tls_ClientHello_session.session_id_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -143,24 +143,24 @@ int process_TLS_Handshake_ClientHello() /* Now we know we must read session_id_length bytes */ - assert(client_hello_session.session_id_length <= - sizeof(client_hello_session.session_id)); + assert(tls_ClientHello_session.session_id_length <= + sizeof(tls_ClientHello_session.session_id)); - if (client_hello_session.session_id_length) { - if (read_bytes(tls_in, client_hello_session.session_id, - client_hello_session.session_id_length) <= 0) { + if (tls_ClientHello_session.session_id_length) { + if (read_bytes(tls_in, tls_ClientHello_session.session_id, + tls_ClientHello_session.session_id_length) <= 0) { return -1; } - must_read_bytes -= client_hello_session.session_id_length; + must_read_bytes -= tls_ClientHello_session.session_id_length; } #if __DEBUG__ - for (i = 0; i < client_hello_session.session_id_length; i++) { + for (i = 0; i < tls_ClientHello_session.session_id_length; i++) { if (i == 0) { fprintf(stderr, "TLS ClientHello Session ID: "); } - fprintf(stderr, "%02x", client_hello_session.session_id[i]); - if (i + 1 == client_hello_session.session_id_length) { + fprintf(stderr, "%02x", tls_ClientHello_session.session_id[i]); + if (i + 1 == tls_ClientHello_session.session_id_length) { fprintf(stderr, "\n"); } } @@ -168,9 +168,9 @@ int process_TLS_Handshake_ClientHello() /* log */ if (tls_out != -1) { - if (client_hello_session.session_id_length) { - r = write(tls_out, client_hello_session.session_id, - client_hello_session.session_id_length); + if (tls_ClientHello_session.session_id_length) { + r = write(tls_out, tls_ClientHello_session.session_id, + tls_ClientHello_session.session_id_length); if (r == 0 || r == -1) { perror("write"); return -1; @@ -180,51 +180,51 @@ int process_TLS_Handshake_ClientHello() /* ciphersuites */ - if (read_bytes(tls_in, &client_hello_ciphersuites.cipher_suites_length, - sizeof(client_hello_ciphersuites.cipher_suites_length)) <= 0) { + if (read_bytes(tls_in, &tls_ClientHello_ciphersuites.cipher_suites_length, + sizeof(tls_ClientHello_ciphersuites.cipher_suites_length)) <= 0) { return -1; } - must_read_bytes -= sizeof(client_hello_ciphersuites.cipher_suites_length); + must_read_bytes -= sizeof(tls_ClientHello_ciphersuites.cipher_suites_length); #if __DEBUG__ fprintf(stderr, "TLS ClientHello Cipher Suites Length: %u\n", - n16toh16(client_hello_ciphersuites.cipher_suites_length)); + n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length)); #endif /* log */ if (tls_out != -1) { - r = write(tls_out, &client_hello_ciphersuites.cipher_suites_length, - sizeof(client_hello_ciphersuites.cipher_suites_length)); + r = write(tls_out, &tls_ClientHello_ciphersuites.cipher_suites_length, + sizeof(tls_ClientHello_ciphersuites.cipher_suites_length)); if (r == 0 || r == -1) { perror("write"); return -1; } } - assert(n16toh16(client_hello_ciphersuites.cipher_suites_length) <= - sizeof(client_hello_ciphersuites.cipher_suites)); + assert(n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length) <= + sizeof(tls_ClientHello_ciphersuites.cipher_suites)); - if (read_bytes(tls_in, client_hello_ciphersuites.cipher_suites, - n16toh16(client_hello_ciphersuites.cipher_suites_length)) <= 0) { + if (read_bytes(tls_in, tls_ClientHello_ciphersuites.cipher_suites, + n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length)) <= 0) { return -1; } - must_read_bytes -= n16toh16(client_hello_ciphersuites.cipher_suites_length); + must_read_bytes -= n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length); #if __DEBUG__ /* length is in bytes */ for (i = 0; - i < n16toh16(client_hello_ciphersuites.cipher_suites_length) / + i < n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length) / sizeof(CipherSuite); i++) { fprintf(stderr, "TLS ClientHello Cipher Suite: %s (0x%04x)\n", - CIPHER_TXT(n16toh16(client_hello_ciphersuites.cipher_suites[i])), - n16toh16(client_hello_ciphersuites.cipher_suites[i])); + CIPHER_TXT(n16toh16(tls_ClientHello_ciphersuites.cipher_suites[i])), + n16toh16(tls_ClientHello_ciphersuites.cipher_suites[i])); } #endif /* log */ if (tls_out != -1) { - r = write(tls_out, client_hello_ciphersuites.cipher_suites, - n16toh16(client_hello_ciphersuites.cipher_suites_length)); + r = write(tls_out, tls_ClientHello_ciphersuites.cipher_suites, + n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -233,49 +233,49 @@ int process_TLS_Handshake_ClientHello() /* compression */ - if (read_bytes(tls_in, &client_hello_compression.compression_methods_length, - sizeof(client_hello_compression.compression_methods_length)) <= 0) { + if (read_bytes(tls_in, &tls_ClientHello_compression.compression_methods_length, + sizeof(tls_ClientHello_compression.compression_methods_length)) <= 0) { return -1; } must_read_bytes -= - sizeof(client_hello_compression.compression_methods_length); + sizeof(tls_ClientHello_compression.compression_methods_length); #if __DEBUG__ fprintf(stderr, "TLS ClientHello Compression Methods Length: %u\n", - client_hello_compression.compression_methods_length); + tls_ClientHello_compression.compression_methods_length); #endif /* log */ if (tls_out != -1) { - r = write(tls_out, &client_hello_compression.compression_methods_length, - sizeof(client_hello_compression.compression_methods_length)); + r = write(tls_out, &tls_ClientHello_compression.compression_methods_length, + sizeof(tls_ClientHello_compression.compression_methods_length)); if (r == 0 || r == -1) { perror("write"); return -1; } } - assert(client_hello_compression.compression_methods_length <= - sizeof(client_hello_compression.compression_methods)); + assert(tls_ClientHello_compression.compression_methods_length <= + sizeof(tls_ClientHello_compression.compression_methods)); - if (read_bytes(tls_in, client_hello_compression.compression_methods, - client_hello_compression.compression_methods_length) <= 0) { + if (read_bytes(tls_in, tls_ClientHello_compression.compression_methods, + tls_ClientHello_compression.compression_methods_length) <= 0) { return -1; } - must_read_bytes -= client_hello_compression.compression_methods_length; + must_read_bytes -= tls_ClientHello_compression.compression_methods_length; #if __DEBUG__ - for (i = 0; i < client_hello_compression.compression_methods_length; i++) { + for (i = 0; i < tls_ClientHello_compression.compression_methods_length; i++) { fprintf(stderr, "TLS ClientHello Compression Method: %s (%u)\n", - COMPRESSION_TXT(client_hello_compression.compression_methods[i]), - client_hello_compression.compression_methods[i]); + COMPRESSION_TXT(tls_ClientHello_compression.compression_methods[i]), + tls_ClientHello_compression.compression_methods[i]); } #endif /* log */ if (tls_out != -1) { - r = write(tls_out, client_hello_compression.compression_methods, - client_hello_compression.compression_methods_length); + r = write(tls_out, tls_ClientHello_compression.compression_methods, + tls_ClientHello_compression.compression_methods_length); if (r == 0 || r == -1) { perror("write"); return -1; @@ -285,21 +285,21 @@ int process_TLS_Handshake_ClientHello() /* extensions */ if (must_read_bytes > 0) { - if (read_bytes(tls_in, &extensions.extensions_length, - sizeof(extensions.extensions_length)) <= 0) { + if (read_bytes(tls_in, &tls_extensions.extensions_length, + sizeof(tls_extensions.extensions_length)) <= 0) { return -1; } - must_read_bytes -= sizeof(extensions.extensions_length); + must_read_bytes -= sizeof(tls_extensions.extensions_length); #if __DEBUG__ fprintf(stderr, "TLS ClientHello Extensions Length: %u\n", - n16toh16(extensions.extensions_length)); + n16toh16(tls_extensions.extensions_length)); #endif /* log */ if (tls_out != -1) { - r = write(tls_out, &extensions.extensions_length, - sizeof(extensions.extensions_length)); + r = write(tls_out, &tls_extensions.extensions_length, + sizeof(tls_extensions.extensions_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -308,22 +308,22 @@ int process_TLS_Handshake_ClientHello() /* Now we know we must read extensions_length bytes */ - assert(n16toh16(extensions.extensions_length) <= - sizeof(extensions.extensions)); + assert(n16toh16(tls_extensions.extensions_length) <= + sizeof(tls_extensions.extensions)); - if (n16toh16(extensions.extensions_length)) { - if (read_bytes(tls_in, extensions.extensions, - n16toh16(extensions.extensions_length)) <= 0) { + if (n16toh16(tls_extensions.extensions_length)) { + if (read_bytes(tls_in, tls_extensions.extensions, + n16toh16(tls_extensions.extensions_length)) <= 0) { return -1; } - must_read_bytes -= n16toh16(extensions.extensions_length); + must_read_bytes -= n16toh16(tls_extensions.extensions_length); } /* log */ if (tls_out != -1) { - if (n16toh16(extensions.extensions_length)) { - r = write(tls_out, extensions.extensions, - n16toh16(extensions.extensions_length)); + if (n16toh16(tls_extensions.extensions_length)) { + r = write(tls_out, tls_extensions.extensions, + n16toh16(tls_extensions.extensions_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -340,28 +340,28 @@ int process_TLS_Handshake_ClientHello() } -int prepare_TLS_Handshake_ClientHello (void) +int tls_prepare_Handshake_ClientHello (void) { uint16_t i; - client_hello_intro.client_version_major = PROTOCOLMAJOR; - client_hello_intro.client_version_minor = PROTOCOLMINOR; - client_hello_intro.random_gmt_unix_time = 0; - memset(client_hello_intro.random_random_bytes, 0, - sizeof(client_hello_intro.random_random_bytes)); + tls_ClientHello_intro.client_version_major = PROTOCOLMAJOR; + tls_ClientHello_intro.client_version_minor = PROTOCOLMINOR; + tls_ClientHello_intro.random_gmt_unix_time = 0; + memset(tls_ClientHello_intro.random_random_bytes, 0, + sizeof(tls_ClientHello_intro.random_random_bytes)); - client_hello_session.session_id_length = 0; + tls_ClientHello_session.session_id_length = 0; for (i = 0; i < opt_ciphersuite_count && - i < (sizeof(client_hello_ciphersuites.cipher_suites)/ - sizeof(client_hello_ciphersuites.cipher_suites[0])); i++) { - client_hello_ciphersuites.cipher_suites[i] = h16ton16(opt_ciphersuites[i]); + i < (sizeof(tls_ClientHello_ciphersuites.cipher_suites)/ + sizeof(tls_ClientHello_ciphersuites.cipher_suites[0])); i++) { + tls_ClientHello_ciphersuites.cipher_suites[i] = h16ton16(opt_ciphersuites[i]); } - client_hello_ciphersuites.cipher_suites_length = + tls_ClientHello_ciphersuites.cipher_suites_length = h16ton16(i * sizeof(opt_ciphersuites[0])); - client_hello_compression.compression_methods_length = 0x1; - client_hello_compression.compression_methods[0] = 0x0; + tls_ClientHello_compression.compression_methods_length = 0x1; + tls_ClientHello_compression.compression_methods[0] = 0x0; return 0; } @@ -370,7 +370,7 @@ int prepare_TLS_Handshake_ClientHello (void) /* * process a TLS Handshake ServerHello message */ -int process_TLS_Handshake_ServerHello() +int tls_process_Handshake_ServerHello() { #if __DEBUG__ unsigned int i; @@ -385,68 +385,68 @@ int process_TLS_Handshake_ServerHello() char time_buf[80]; #endif - assert(n24toh32(TLSHandshake_header.Handshake__length) >= - sizeof(server_hello_min)); + assert(n24toh32(tls_Handshake_header.Handshake__length) >= + sizeof(tls_ServerHello_min)); - must_read_bytes = n24toh32(TLSHandshake_header.Handshake__length); + must_read_bytes = n24toh32(tls_Handshake_header.Handshake__length); /* Read up to the session ID length byte. Since the session ID * is of variable length we need to figure out how much to read as such. */ - if (read_bytes(tls_in, &server_hello_intro, - sizeof(server_hello_intro)) <= 0) { + if (read_bytes(tls_in, &tls_ServerHello_intro, + sizeof(tls_ServerHello_intro)) <= 0) { return -1; } - must_read_bytes -= sizeof(server_hello_intro); + must_read_bytes -= sizeof(tls_ServerHello_intro); - server_version_major = server_hello_intro.server_version_major; - server_version_minor = server_hello_intro.server_version_minor; + server_version_major = tls_ServerHello_intro.server_version_major; + server_version_minor = tls_ServerHello_intro.server_version_minor; stat_flags |= STAT_SERVER_VERSION; #if __DEBUG__ fprintf(stderr, "TLS ServerHello Version: %s (0x%02x%02x)\n", - PROTOCOL_TXT(server_hello_intro.server_version_minor), - server_hello_intro.server_version_major, - server_hello_intro.server_version_minor); + PROTOCOL_TXT(tls_ServerHello_intro.server_version_minor), + tls_ServerHello_intro.server_version_major, + tls_ServerHello_intro.server_version_minor); - t = ntohl(server_hello_intro.random_gmt_unix_time); + t = ntohl(tls_ServerHello_intro.random_gmt_unix_time); ts = localtime(&t); if (strftime(time_buf, sizeof(time_buf), "%b %d, %Y %H:%M:%S %Z", ts)) { fprintf(stderr, "TLS ServerHello Random gmt_unix_time: %s (%u)\n", - time_buf, ntohl(server_hello_intro.random_gmt_unix_time)); + time_buf, ntohl(tls_ServerHello_intro.random_gmt_unix_time)); } fprintf(stderr, "TLS ServerHello Random random_bytes: "); for (i = 0; i < 28; i++) - fprintf(stderr, "%02x", server_hello_intro.random_random_bytes[i]); + fprintf(stderr, "%02x", tls_ServerHello_intro.random_random_bytes[i]); fprintf(stderr, "\n"); #endif /* log */ if (tls_out != -1) { - r = write(tls_out, &server_hello_intro, sizeof(server_hello_intro)); + r = write(tls_out, &tls_ServerHello_intro, sizeof(tls_ServerHello_intro)); if (r == 0 || r == -1) { perror("write"); return -1; } } - if (read_bytes(tls_in, &server_hello_session.session_id_length, - sizeof(server_hello_session.session_id_length)) <= 0) { + if (read_bytes(tls_in, &tls_ServerHello_session.session_id_length, + sizeof(tls_ServerHello_session.session_id_length)) <= 0) { return -1; } - must_read_bytes -= sizeof(server_hello_session.session_id_length); + must_read_bytes -= sizeof(tls_ServerHello_session.session_id_length); #if __DEBUG__ fprintf(stderr, "TLS ServerHello Session ID Length: %u\n", - server_hello_session.session_id_length); + tls_ServerHello_session.session_id_length); #endif /* log */ if (tls_out != -1) { - r = write(tls_out, &server_hello_session.session_id_length, - sizeof(server_hello_session.session_id_length)); + r = write(tls_out, &tls_ServerHello_session.session_id_length, + sizeof(tls_ServerHello_session.session_id_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -455,24 +455,24 @@ int process_TLS_Handshake_ServerHello() /* Now we know we must read session_id_length bytes */ - assert(server_hello_session.session_id_length <= - sizeof(server_hello_session.session_id)); + assert(tls_ServerHello_session.session_id_length <= + sizeof(tls_ServerHello_session.session_id)); - if (server_hello_session.session_id_length) { - if (read_bytes(tls_in, server_hello_session.session_id, - server_hello_session.session_id_length) <= 0) { + if (tls_ServerHello_session.session_id_length) { + if (read_bytes(tls_in, tls_ServerHello_session.session_id, + tls_ServerHello_session.session_id_length) <= 0) { return -1; } - must_read_bytes -= server_hello_session.session_id_length; + must_read_bytes -= tls_ServerHello_session.session_id_length; } #if __DEBUG__ - for (i = 0; i < server_hello_session.session_id_length; i++) { + for (i = 0; i < tls_ServerHello_session.session_id_length; i++) { if (i == 0) { fprintf(stderr, "TLS ServerHello Session ID: "); } - fprintf(stderr, "%02x", server_hello_session.session_id[i]); - if (i + 1 == server_hello_session.session_id_length) { + fprintf(stderr, "%02x", tls_ServerHello_session.session_id[i]); + if (i + 1 == tls_ServerHello_session.session_id_length) { fprintf(stderr, "\n"); } } @@ -480,9 +480,9 @@ int process_TLS_Handshake_ServerHello() /* log */ if (tls_out != -1) { - if (server_hello_session.session_id_length) { - r = write(tls_out, server_hello_session.session_id, - server_hello_session.session_id_length); + if (tls_ServerHello_session.session_id_length) { + r = write(tls_out, tls_ServerHello_session.session_id, + tls_ServerHello_session.session_id_length); if (r == 0 || r == -1) { perror("write"); return -1; @@ -492,26 +492,26 @@ int process_TLS_Handshake_ServerHello() /* ciphersuite */ - if (read_bytes(tls_in, &server_hello_ciphersuite.cipher_suite, - sizeof(server_hello_ciphersuite.cipher_suite)) <= 0) { + if (read_bytes(tls_in, &tls_ServerHello_ciphersuite.cipher_suite, + sizeof(tls_ServerHello_ciphersuite.cipher_suite)) <= 0) { return -1; } - must_read_bytes -= sizeof(server_hello_ciphersuite.cipher_suite); + must_read_bytes -= sizeof(tls_ServerHello_ciphersuite.cipher_suite); - server_suite = n16toh16(server_hello_ciphersuite.cipher_suite); + server_suite = n16toh16(tls_ServerHello_ciphersuite.cipher_suite); stat_flags |= STAT_SERVER_SUITE; #if __DEBUG__ fprintf(stderr, "TLS ServerHello Cipher Suite: %s (0x%04x)\n", - CIPHER_TXT(n16toh16(server_hello_ciphersuite.cipher_suite)), - n16toh16(server_hello_ciphersuite.cipher_suite)); + CIPHER_TXT(n16toh16(tls_ServerHello_ciphersuite.cipher_suite)), + n16toh16(tls_ServerHello_ciphersuite.cipher_suite)); #endif /* log */ if (tls_out != -1) { - r = write(tls_out, &server_hello_ciphersuite.cipher_suite, - sizeof(server_hello_ciphersuite.cipher_suite)); + r = write(tls_out, &tls_ServerHello_ciphersuite.cipher_suite, + sizeof(tls_ServerHello_ciphersuite.cipher_suite)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -520,22 +520,22 @@ int process_TLS_Handshake_ServerHello() /* compression */ - if (read_bytes(tls_in, &server_hello_compression.compression_method, - sizeof(server_hello_compression.compression_method)) <= 0) { + if (read_bytes(tls_in, &tls_ServerHello_compression.compression_method, + sizeof(tls_ServerHello_compression.compression_method)) <= 0) { return -1; } - must_read_bytes -= sizeof(server_hello_compression.compression_method); + must_read_bytes -= sizeof(tls_ServerHello_compression.compression_method); #if __DEBUG__ fprintf(stderr, "TLS ServerHello Compression Method: %s (%u)\n", - COMPRESSION_TXT(server_hello_compression.compression_method), - server_hello_compression.compression_method); + COMPRESSION_TXT(tls_ServerHello_compression.compression_method), + tls_ServerHello_compression.compression_method); #endif /* log */ if (tls_out != -1) { - r = write(tls_out, &server_hello_compression.compression_method, - sizeof(server_hello_compression.compression_method)); + r = write(tls_out, &tls_ServerHello_compression.compression_method, + sizeof(tls_ServerHello_compression.compression_method)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -545,21 +545,21 @@ int process_TLS_Handshake_ServerHello() /* extensions */ if (must_read_bytes > 0) { - if (read_bytes(tls_in, &extensions.extensions_length, - sizeof(extensions.extensions_length)) <= 0) { + if (read_bytes(tls_in, &tls_extensions.extensions_length, + sizeof(tls_extensions.extensions_length)) <= 0) { return -1; } - must_read_bytes -= sizeof(extensions.extensions_length); + must_read_bytes -= sizeof(tls_extensions.extensions_length); #if __DEBUG__ fprintf(stderr, "TLS ServerHello Extensions Length: %u\n", - n16toh16(extensions.extensions_length)); + n16toh16(tls_extensions.extensions_length)); #endif /* log */ if (tls_out != -1) { - r = write(tls_out, &extensions.extensions_length, - sizeof(extensions.extensions_length)); + r = write(tls_out, &tls_extensions.extensions_length, + sizeof(tls_extensions.extensions_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -568,22 +568,22 @@ int process_TLS_Handshake_ServerHello() /* Now we know we must read extensions_length bytes */ - assert(n16toh16(extensions.extensions_length) <= - sizeof(extensions.extensions)); + assert(n16toh16(tls_extensions.extensions_length) <= + sizeof(tls_extensions.extensions)); - if (n16toh16(extensions.extensions_length)) { - if (read_bytes(tls_in, extensions.extensions, - n16toh16(extensions.extensions_length)) <= 0) { + if (n16toh16(tls_extensions.extensions_length)) { + if (read_bytes(tls_in, tls_extensions.extensions, + n16toh16(tls_extensions.extensions_length)) <= 0) { return -1; } - must_read_bytes -= n16toh16(extensions.extensions_length); + must_read_bytes -= n16toh16(tls_extensions.extensions_length); } /* log */ if (tls_out != -1) { - if (n16toh16(extensions.extensions_length)) { - r = write(tls_out, extensions.extensions, - n16toh16(extensions.extensions_length)); + if (n16toh16(tls_extensions.extensions_length)) { + r = write(tls_out, tls_extensions.extensions, + n16toh16(tls_extensions.extensions_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -602,12 +602,13 @@ int process_TLS_Handshake_ServerHello() /* * process a TLS Handshake Certificate message + * (extract individual certificates etc.) * * Message consists of a { uint8_t certificate_list_length[3] } header * followed by one or more instances of { uint8_t certificate_length[3]; * }. */ -int process_TLS_Handshake_Certificate() +int tls_process_Handshake_Certificate() { unsigned int r; @@ -615,15 +616,15 @@ int process_TLS_Handshake_Certificate() /* certificate list */ - if (read_bytes(tls_in, &certificate.certificate_list_length, - sizeof(certificate.certificate_list_length)) <= 0) { + if (read_bytes(tls_in, &tls_Certificate.certificate_list_length, + sizeof(tls_Certificate.certificate_list_length)) <= 0) { return -1; } /* log */ if (tls_out != -1) { - r = write(tls_out, &certificate.certificate_list_length, - sizeof(certificate.certificate_list_length)); + r = write(tls_out, &tls_Certificate.certificate_list_length, + sizeof(tls_Certificate.certificate_list_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -632,25 +633,25 @@ int process_TLS_Handshake_Certificate() #if __DEBUG__ fprintf(stderr, "TLS Certificates Length: %u\n", - n24toh32(certificate.certificate_list_length)); + n24toh32(tls_Certificate.certificate_list_length)); #endif - must_read_bytes = n24toh32(certificate.certificate_list_length); + must_read_bytes = n24toh32(tls_Certificate.certificate_list_length); while(must_read_bytes > 0) { - assert(must_read_bytes >= sizeof(asn1certificate_min)); + assert(must_read_bytes >= sizeof(tls_ASN1Cert_min)); /* certificate */ - if (read_bytes(tls_in, &asn1certificate.certificate_length, - sizeof(asn1certificate.certificate_length)) <= 0) { + if (read_bytes(tls_in, &tls_ASN1Cert.certificate_length, + sizeof(tls_ASN1Cert.certificate_length)) <= 0) { return -1; } - must_read_bytes -= sizeof(asn1certificate.certificate_length); + must_read_bytes -= sizeof(tls_ASN1Cert.certificate_length); /* log */ if (tls_out != -1) { - r = write(tls_out, &asn1certificate.certificate_length, - sizeof(asn1certificate.certificate_length)); + r = write(tls_out, &tls_ASN1Cert.certificate_length, + sizeof(tls_ASN1Cert.certificate_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -659,22 +660,22 @@ int process_TLS_Handshake_Certificate() #if __DEBUG__ fprintf(stderr, "TLS Certificate Length: %u\n", - n24toh32(asn1certificate.certificate_length)); + n24toh32(tls_ASN1Cert.certificate_length)); #endif - assert(n24toh32(asn1certificate.certificate_length) <= - sizeof(asn1certificate.certificate)); + assert(n24toh32(tls_ASN1Cert.certificate_length) <= + sizeof(tls_ASN1Cert.certificate)); - if (read_bytes(tls_in, asn1certificate.certificate, - n24toh32(asn1certificate.certificate_length)) <= 0) { + if (read_bytes(tls_in, tls_ASN1Cert.certificate, + n24toh32(tls_ASN1Cert.certificate_length)) <= 0) { return -1; } - must_read_bytes -= n24toh32(asn1certificate.certificate_length); + must_read_bytes -= n24toh32(tls_ASN1Cert.certificate_length); /* log */ if (tls_out != -1) { - r = write(tls_out, asn1certificate.certificate, - n24toh32(asn1certificate.certificate_length)); + r = write(tls_out, tls_ASN1Cert.certificate, + n24toh32(tls_ASN1Cert.certificate_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -684,8 +685,8 @@ int process_TLS_Handshake_Certificate() /* invoke certificate handler if present */ if (tls_callbacks[SSL3_RT_HANDSHAKE][SSL3_MT_CERTIFICATE]) { (*tls_callbacks[SSL3_RT_HANDSHAKE][SSL3_MT_CERTIFICATE])( - asn1certificate.certificate, - n24toh32(asn1certificate.certificate_length)); + tls_ASN1Cert.certificate, + n24toh32(tls_ASN1Cert.certificate_length)); } } @@ -693,6 +694,197 @@ int process_TLS_Handshake_Certificate() } +int tls_process_Handshake_ServerKeyExchange( + uint8_t *r_buf, uint32_t r_buf_length) +{ + uint32_t offset; + + offset = 0; + + memset(&tls_ServerKeyExchange, 0, sizeof(tls_ServerKeyExchange)); + + unsigned int KeyExchangeAlgorithm = + CipherSuite_KeyExchangeAlgorithm(server_suite); + + if (HAS_KEYEXCHANGE_DHPARAMS(KeyExchangeAlgorithm)) { + tls_ServerKeyExchange.params = &tls_ServerDHParams; + + /* Prime modulus for the Diffie-Hellman operation. */ + + /* Data available */ + assert(r_buf_length - offset >= sizeof(tls_ServerDHParams.dh_p_length)); + + tls_ServerDHParams.dh_p_length = *((uint16_t *)(r_buf+offset)); + + offset += sizeof(tls_ServerDHParams.dh_p_length); + +#if __DEBUG__ + fprintf(stderr, "TLS tls_ServerKeyExchange tls_ServerDHParams p Length: %u\n", + n16toh16(tls_ServerDHParams.dh_p_length)); +#endif + + /* Data available */ + assert(r_buf_length - offset >= n16toh16(tls_ServerDHParams.dh_p_length)); + /* Memory available */ + assert(sizeof(tls_ServerDHParams.dh_p) >= + n16toh16(tls_ServerDHParams.dh_p_length)); + + memcpy(tls_ServerDHParams.dh_p, r_buf+offset, + n16toh16(tls_ServerDHParams.dh_p_length)); + + offset += n16toh16(tls_ServerDHParams.dh_p_length); + + /* Generator used for the Diffie-Hellman operation. */ + + /* Data available */ + assert(r_buf_length - offset >= sizeof(tls_ServerDHParams.dh_g_length)); + + tls_ServerDHParams.dh_g_length = *((uint16_t *)(r_buf+offset)); + + offset += sizeof(tls_ServerDHParams.dh_g_length); + +#if __DEBUG__ + fprintf(stderr, "TLS tls_ServerKeyExchange tls_ServerDHParams g Length: %u\n", + n16toh16(tls_ServerDHParams.dh_g_length)); +#endif + + /* Data available */ + assert(r_buf_length - offset >= n16toh16(tls_ServerDHParams.dh_g_length)); + /* Memory available */ + assert(sizeof(tls_ServerDHParams.dh_g) >= + n16toh16(tls_ServerDHParams.dh_g_length)); + + memcpy(tls_ServerDHParams.dh_g, r_buf+offset, + n16toh16(tls_ServerDHParams.dh_g_length)); + + offset += n16toh16(tls_ServerDHParams.dh_g_length); + + /* The server's Diffie-Hellman public value (g^X mod p). */ + + /* Data available */ + assert(r_buf_length - offset >= sizeof(tls_ServerDHParams.dh_Ys_length)); + + tls_ServerDHParams.dh_Ys_length = *((uint16_t *)(r_buf+offset)); + + offset += sizeof(tls_ServerDHParams.dh_Ys_length); + +#if __DEBUG__ + fprintf(stderr, + "TLS tls_ServerKeyExchange tls_ServerDHParams Ys Length: %u\n", + n16toh16(tls_ServerDHParams.dh_Ys_length)); +#endif + + /* Data available */ + assert(r_buf_length - offset >= n16toh16(tls_ServerDHParams.dh_Ys_length)); + /* Memory available */ + assert(sizeof(tls_ServerDHParams.dh_Ys) >= + n16toh16(tls_ServerDHParams.dh_Ys_length)); + + memcpy(tls_ServerDHParams.dh_Ys, r_buf+offset, + n16toh16(tls_ServerDHParams.dh_Ys_length)); + + offset += n16toh16(tls_ServerDHParams.dh_Ys_length); + } + + if (HAS_KEYEXCHANGE_DHPARAMS_SIGNED(KeyExchangeAlgorithm)) { + tls_ServerKeyExchange.signed_params = &tls_DigitallySigned; + + /* Signed elements (tls.h:tls_DigitallySigned) now include a field + * (SignatureAndHashAlgorithm) that explicitly specifies + * the hash (and signature) algorithm used. + * + * Note: We are using the TLS record version fields to determine version + * to handle broken TLS handshakes where the ServerHello message (setting + * server_version_major, server_version_minor) arrives after the + * tls_ServerKeyExchange message (or never). + * + * https://tools.ietf.org/html/rfc5246#section-1.2 + */ + if (TLSPlaintext__versionMajor == 3 && TLSPlaintext__versionMinor == 3) { + + /* Signature Hash Algorithm Hash. */ + + /* Data available */ + assert(r_buf_length - offset >= sizeof(tls_DigitallySigned.algorithm_hash)); + + tls_DigitallySigned.algorithm_hash = *((uint8_t *)(r_buf+offset)); + + offset += sizeof(tls_DigitallySigned.algorithm_hash); + +#if __DEBUG__ + fprintf(stderr, + "TLS tls_ServerKeyExchange digitally-signed Hash Algorithm: %s (%u)\n", + TLS_HASH_ALGORITHM_TXT(tls_DigitallySigned.algorithm_hash), + tls_DigitallySigned.algorithm_hash); +#endif + + /* Signature Hash Algorithm Signature. */ + + /* Data available */ + assert(r_buf_length - offset >= + sizeof(tls_DigitallySigned.algorithm_signature)); + + tls_DigitallySigned.algorithm_signature = *((uint8_t *)(r_buf+offset)); + + offset += sizeof(tls_DigitallySigned.algorithm_signature); + +#if __DEBUG__ + fprintf(stderr, + "TLS tls_ServerKeyExchange digitally-signed Signature Algorithm: %s (%u)\n", + TLS_SIGNATURE_ALGORITHM_TXT(tls_DigitallySigned.algorithm_signature), + tls_DigitallySigned.algorithm_signature); +#endif + + } + + /* Signature */ + + /* Data available */ + assert(r_buf_length - offset >= sizeof(tls_DigitallySigned.signature_length)); + + tls_DigitallySigned.signature_length = *((uint16_t *)(r_buf+offset)); + + offset += sizeof(tls_DigitallySigned.signature_length); + +#if __DEBUG__ + fprintf(stderr, + "TLS tls_ServerKeyExchange digitally-signed Signature Length: %u\n", + n16toh16(tls_DigitallySigned.signature_length)); +#endif + + /* Data available */ + assert(r_buf_length - offset >= + n16toh16(tls_DigitallySigned.signature_length)); + /* Memory available */ + assert(sizeof(tls_DigitallySigned.signature) >= + n16toh16(tls_DigitallySigned.signature_length)); + + memcpy(tls_DigitallySigned.signature, r_buf+offset, + n16toh16(tls_DigitallySigned.signature_length)); + + offset += n16toh16(tls_DigitallySigned.signature_length); + } + + /* invoke server key exchange handler if present */ + if (tls_callbacks[SSL3_RT_HANDSHAKE][ + SSL3_MT_SERVER_KEY_EXCHANGE]) { + (*tls_callbacks[SSL3_RT_HANDSHAKE][SSL3_MT_SERVER_KEY_EXCHANGE])( + (uint8_t *)&tls_ServerKeyExchange, ( + (HAS_KEYEXCHANGE_DHPARAMS_SIGNED(KeyExchangeAlgorithm)) | + (HAS_KEYEXCHANGE_DHPARAMS(KeyExchangeAlgorithm)))); + } + + /* Make sure we've read *exactly* Handshake__length bytes */ + + if (offset != r_buf_length) { + fprintf(stderr, "%s:%s:%u Processed %u bytes (ideally %u).\n", + __FILE__, __FUNCTION__, __LINE__, offset, r_buf_length); + } + + return 0; +} + + /* * Processes an SSL/TLS Handshake. */ @@ -705,21 +897,21 @@ int _tls() unsigned int bail_tls = 0; /* read socket buffer */ - char r_buf[BUF_SIZE+1]; + uint8_t r_buf[BUF_SIZE+1]; /* reset */ error_tls = TLS_ERROR_NOOP; while(!bail_tls) { /* read SSL/TLS record header */ - if (read_bytes(tls_in, &TLSPlaintext_header, - sizeof(TLSPlaintext_header)) <= 0) { + if (read_bytes(tls_in, &tls_TLSPlaintext_header, + sizeof(tls_TLSPlaintext_header)) <= 0) { return -1; } /* log */ if (tls_out != -1) { - r = write(tls_out, &TLSPlaintext_header, sizeof(TLSPlaintext_header)); + r = write(tls_out, &tls_TLSPlaintext_header, sizeof(tls_TLSPlaintext_header)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -729,34 +921,34 @@ int _tls() #if __DEBUG__ fprintf(stderr,"\033[1;34m[.] TLS Record " "type:%u(%s) version:%u.%u length:%u\033[0m\n", - TLSPlaintext_header.TLSPlaintext__type, - TLSContentType(TLSPlaintext_header.TLSPlaintext__type), - TLSPlaintext_header.TLSPlaintext__versionMajor, - TLSPlaintext_header.TLSPlaintext__versionMinor, - ntohs(TLSPlaintext_header.TLSPlaintext__length)); + tls_TLSPlaintext_header.TLSPlaintext__type, + tls_ContentType(tls_TLSPlaintext_header.TLSPlaintext__type), + tls_TLSPlaintext_header.TLSPlaintext__versionMajor, + tls_TLSPlaintext_header.TLSPlaintext__versionMinor, + ntohs(tls_TLSPlaintext_header.TLSPlaintext__length)); #endif - TLSPlaintext__versionMajor = TLSPlaintext_header.TLSPlaintext__versionMajor; - TLSPlaintext__versionMinor = TLSPlaintext_header.TLSPlaintext__versionMinor; + TLSPlaintext__versionMajor = tls_TLSPlaintext_header.TLSPlaintext__versionMajor; + TLSPlaintext__versionMinor = tls_TLSPlaintext_header.TLSPlaintext__versionMinor; stat_flags |= STAT_TLS_VERSION; /* process SSL/TLS record */ - switch(TLSPlaintext_header.TLSPlaintext__type) { + switch(tls_TLSPlaintext_header.TLSPlaintext__type) { /* alert (21) */ case SSL3_RT_ALERT: /* there must be an alert header */ - assert(ntohs(TLSPlaintext_header.TLSPlaintext__length) >= - sizeof(TLSAlert_header)); + assert(ntohs(tls_TLSPlaintext_header.TLSPlaintext__length) >= + sizeof(tls_Alert)); - if (read_bytes(tls_in, &TLSAlert_header, - sizeof(TLSAlert_header)) <= 0) { + if (read_bytes(tls_in, &tls_Alert, + sizeof(tls_Alert)) <= 0) { return -1; } /* log */ if (tls_out != -1) { - r = write(tls_out, &TLSAlert_header, sizeof(TLSAlert_header)); + r = write(tls_out, &tls_Alert, sizeof(tls_Alert)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -767,10 +959,10 @@ int _tls() fprintf(stderr, "\033[1;36m[.] TLS Alert " "level:%u(%s) description:%u(%s)\033[0m\n", - TLSAlert_header.Alert__level, - AlertLevel(TLSAlert_header.Alert__level), - TLSAlert_header.Alert__description, - AlertDescription(TLSAlert_header.Alert__description)); + tls_Alert.Alert__level, + tls_AlertLevel(tls_Alert.Alert__level), + tls_Alert.Alert__description, + tls_AlertDescription(tls_Alert.Alert__description)); #endif error_tls = TLS_ERROR_ALERT; @@ -779,24 +971,24 @@ int _tls() /* handshake (22) */ case SSL3_RT_HANDSHAKE: /* there must be a handshake header */ - assert(ntohs(TLSPlaintext_header.TLSPlaintext__length) >= - sizeof(TLSHandshake_header)); + assert(ntohs(tls_TLSPlaintext_header.TLSPlaintext__length) >= + sizeof(tls_Handshake_header)); must_read_bytes = - ntohs(TLSPlaintext_header.TLSPlaintext__length); + ntohs(tls_TLSPlaintext_header.TLSPlaintext__length); while(must_read_bytes > 0) { /* read handshake header */ - if (read_bytes(tls_in, &TLSHandshake_header, - sizeof(TLSHandshake_header)) <= 0) { + if (read_bytes(tls_in, &tls_Handshake_header, + sizeof(tls_Handshake_header)) <= 0) { return -1; } - must_read_bytes -= sizeof(TLSHandshake_header); + must_read_bytes -= sizeof(tls_Handshake_header); /* log */ if (tls_out != -1) { - r = write(tls_out, &TLSHandshake_header, - sizeof(TLSHandshake_header)); + r = write(tls_out, &tls_Handshake_header, + sizeof(tls_Handshake_header)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -807,15 +999,15 @@ int _tls() fprintf(stderr, "\033[1;36m[.] TLS Handshake " "type:%u(%s) length:%u\033[0m\n", - TLSHandshake_header.Handshake__type, - TLSHandshakeType(TLSHandshake_header.Handshake__type), - n24toh32(TLSHandshake_header.Handshake__length)); + tls_Handshake_header.Handshake__type, + tls_HandshakeType(tls_Handshake_header.Handshake__type), + n24toh32(tls_Handshake_header.Handshake__length)); #endif /* The record layer fragments information blocks (e.g., handshake * messages or application data) into TLSPlaintext records carrying * data in chunks of 2^14 bytes or less.*/ - assert(ntohs(TLSPlaintext_header.TLSPlaintext__length) <= 0x4000); + assert(ntohs(tls_TLSPlaintext_header.TLSPlaintext__length) <= 0x4000); #if 1 /* We can't handle fragmentation right now. @@ -824,66 +1016,69 @@ int _tls() * larger messages should keep fragmentation away for now. * Implementing fragmentation should include updating all * handshake type handlers to account for their respective - * messages (e.g., server_hello) being fragmented and even + * messages (e.g., tls_ServerHello) being fragmented and even * for the fragments to appear interleaved.*/ - /* TODO: TLSHandshake_header.Handshake__length is NOT a reliable + /* TODO: tls_Handshake_header.Handshake__length is NOT a reliable * way to determine how much data is available right now. */ - assert(ntohs(TLSPlaintext_header.TLSPlaintext__length) >= - sizeof(TLSHandshake_header) + - n24toh32(TLSHandshake_header.Handshake__length)); + assert(ntohs(tls_TLSPlaintext_header.TLSPlaintext__length) >= + sizeof(tls_Handshake_header) + + n24toh32(tls_Handshake_header.Handshake__length)); #endif /* process Handshake type */ - switch(TLSHandshake_header.Handshake__type) { + switch(tls_Handshake_header.Handshake__type) { /* ClientHello (2) */ case SSL3_MT_CLIENT_HELLO: - if ((r = process_TLS_Handshake_ClientHello()) != 0) {return r;} + if ((r = tls_process_Handshake_ClientHello()) != 0) {return r;} break; /* ServerHello (2) */ case SSL3_MT_SERVER_HELLO: - if ((r = process_TLS_Handshake_ServerHello()) != 0) {return r;} + if ((r = tls_process_Handshake_ServerHello()) != 0) {return r;} break; /* Certificate (11) */ case SSL3_MT_CERTIFICATE: - /* save actual Certificate record */ - if ((r = process_TLS_Handshake_Certificate()) != 0) {return r;} + if ((r = tls_process_Handshake_Certificate()) != 0) {return r;} break; /* Server Key Exchange (12) */ case SSL3_MT_SERVER_KEY_EXCHANGE: - /* consume (and ignore) rest of this record */ + /* consume this record */ assert(BUF_SIZE >= - n24toh32(TLSHandshake_header.Handshake__length)); + n24toh32(tls_Handshake_header.Handshake__length)); if (read_bytes(tls_in, r_buf, - n24toh32(TLSHandshake_header.Handshake__length)) <= 0) { + n24toh32(tls_Handshake_header.Handshake__length)) <= 0) { return -1; } /* log */ if (tls_out != -1) { r = write(tls_out, r_buf, - n24toh32(TLSHandshake_header.Handshake__length)); + n24toh32(tls_Handshake_header.Handshake__length)); if (r == 0 || r == -1) { perror("write"); return -1; } } + + /* process this record */ + tls_process_Handshake_ServerKeyExchange(r_buf, + n24toh32(tls_Handshake_header.Handshake__length)); break; /* Certificate Request (13) */ case SSL3_MT_CERTIFICATE_REQUEST: /* consume (and ignore) rest of this record */ assert(BUF_SIZE >= - n24toh32(TLSHandshake_header.Handshake__length)); + n24toh32(tls_Handshake_header.Handshake__length)); if (read_bytes(tls_in, r_buf, - n24toh32(TLSHandshake_header.Handshake__length)) <= 0) { + n24toh32(tls_Handshake_header.Handshake__length)) <= 0) { return -1; } /* log */ if (tls_out != -1) { r = write(tls_out, r_buf, - n24toh32(TLSHandshake_header.Handshake__length)); + n24toh32(tls_Handshake_header.Handshake__length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -894,18 +1089,18 @@ int _tls() case SSL3_MT_SERVER_DONE: /* consume (and ignore) rest of this record */ assert(BUF_SIZE >= - n24toh32(TLSHandshake_header.Handshake__length)); + n24toh32(tls_Handshake_header.Handshake__length)); - if (n24toh32(TLSHandshake_header.Handshake__length)) { + if (n24toh32(tls_Handshake_header.Handshake__length)) { if (read_bytes(tls_in, r_buf, - n24toh32(TLSHandshake_header.Handshake__length)) <= 0) { + n24toh32(tls_Handshake_header.Handshake__length)) <= 0) { return -1; } if (tls_out != -1) { r = write(tls_out, r_buf, - n24toh32(TLSHandshake_header.Handshake__length)); - if (n24toh32(TLSHandshake_header.Handshake__length) && + n24toh32(tls_Handshake_header.Handshake__length)); + if (n24toh32(tls_Handshake_header.Handshake__length) && (r == 0 || r == -1)) { perror("write"); return -1; @@ -920,11 +1115,11 @@ int _tls() #if __DEBUG__ fprintf(stderr, "\033[1;31m[!] Unknown TLS handshake type:%u\033[0m\n", - (unsigned int) TLSHandshake_header.Handshake__type); + (unsigned int) tls_Handshake_header.Handshake__type); - for (r = 0; r < sizeof(TLSHandshake_header); r++) { + for (r = 0; r < sizeof(tls_Handshake_header); r++) { fprintf(stderr, "0x%02x ", - *(((char *)&TLSHandshake_header) + r)); + *(((char *)&tls_Handshake_header) + r)); } fprintf(stderr, "\n"); #endif @@ -935,18 +1130,18 @@ int _tls() } must_read_bytes -= - n24toh32(TLSHandshake_header.Handshake__length); + n24toh32(tls_Handshake_header.Handshake__length); } break; default: #if __DEBUG__ fprintf(stderr, "\033[1;31m[!] Unknown TLS record type:%u\033[0m\n", - (unsigned int) TLSPlaintext_header.TLSPlaintext__type); + (unsigned int) tls_TLSPlaintext_header.TLSPlaintext__type); - for (r = 0; r < sizeof(TLSPlaintext_header); r++) { + for (r = 0; r < sizeof(tls_TLSPlaintext_header); r++) { fprintf(stderr, "0x%02x ", - *(((char *)&TLSPlaintext_header) + r)); + *(((char *)&tls_TLSPlaintext_header) + r)); } fprintf(stderr, "\n"); #endif @@ -969,12 +1164,12 @@ int tls_live(void) unsigned int r; char buffer[ - sizeof(TLSPlaintext_header) + - sizeof(TLSHandshake_header) + - sizeof(client_hello_intro) + - sizeof(client_hello_session) + - sizeof(client_hello_ciphersuites) + - sizeof(client_hello_compression)]; + sizeof(tls_TLSPlaintext_header) + + sizeof(tls_Handshake_header) + + sizeof(tls_ClientHello_intro) + + sizeof(tls_ClientHello_session) + + sizeof(tls_ClientHello_ciphersuites) + + sizeof(tls_ClientHello_compression)]; uint32_t i; if (!tls_initialized) { @@ -1012,38 +1207,38 @@ int tls_live(void) */ /* prepare TLS Handshake ClientHello */ - prepare_TLS_Handshake_ClientHello(); + tls_prepare_Handshake_ClientHello(); /* prepare TLS Handshake header */ - TLSHandshake_header.Handshake__type = SSL3_MT_CLIENT_HELLO; + tls_Handshake_header.Handshake__type = SSL3_MT_CLIENT_HELLO; h24ton24( // ClientHello Version, Random fields; 34 bytes fixed - sizeof(client_hello_intro) + + sizeof(tls_ClientHello_intro) + // ClientHello Session ID; 1 bytes minimum - sizeof(client_hello_session.session_id_length) + - client_hello_session.session_id_length + + sizeof(tls_ClientHello_session.session_id_length) + + tls_ClientHello_session.session_id_length + // ClientHello Ciphersuites; 4 bytes minimum - sizeof(client_hello_ciphersuites.cipher_suites_length) + - n16toh16(client_hello_ciphersuites.cipher_suites_length) + + sizeof(tls_ClientHello_ciphersuites.cipher_suites_length) + + n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length) + // ClientHello Compression methods; 2 bytes minimum - sizeof(client_hello_compression.compression_methods_length) + - client_hello_compression.compression_methods_length, - TLSHandshake_header.Handshake__length); + sizeof(tls_ClientHello_compression.compression_methods_length) + + tls_ClientHello_compression.compression_methods_length, + tls_Handshake_header.Handshake__length); /* prepare TLS record header */ - TLSPlaintext_header.TLSPlaintext__type = SSL3_RT_HANDSHAKE; - TLSPlaintext_header.TLSPlaintext__versionMajor = PROTOCOLMAJOR; - TLSPlaintext_header.TLSPlaintext__versionMinor = PROTOCOLMINOR; - TLSPlaintext_header.TLSPlaintext__length = h16ton16( + tls_TLSPlaintext_header.TLSPlaintext__type = SSL3_RT_HANDSHAKE; + tls_TLSPlaintext_header.TLSPlaintext__versionMajor = PROTOCOLMAJOR; + tls_TLSPlaintext_header.TLSPlaintext__versionMinor = PROTOCOLMINOR; + tls_TLSPlaintext_header.TLSPlaintext__length = h16ton16( // TLS Handshake header; 4 bytes fixed - sizeof(TLSHandshake_header) + + sizeof(tls_Handshake_header) + // ClientHello message; 41 bytes minimum - (uint16_t)n24toh32(TLSHandshake_header.Handshake__length)); + (uint16_t)n24toh32(tls_Handshake_header.Handshake__length)); i = 0; #if 0 /* Write TLS record header */ - r = write(tls_in, &TLSPlaintext_header, sizeof(TLSPlaintext_header)); + r = write(tls_in, &tls_TLSPlaintext_header, sizeof(tls_TLSPlaintext_header)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -1051,21 +1246,21 @@ int tls_live(void) /* log */ if (tls_out != -1) { - r = write(tls_out, &TLSPlaintext_header, sizeof(TLSPlaintext_header)); + r = write(tls_out, &tls_TLSPlaintext_header, sizeof(tls_TLSPlaintext_header)); if (r == 0 || r == -1) { perror("write"); return -1; } } #else - assert(sizeof(buffer) >= i + sizeof(TLSPlaintext_header)); - memcpy(buffer + i, &TLSPlaintext_header, sizeof(TLSPlaintext_header)); - i += sizeof(TLSPlaintext_header); + assert(sizeof(buffer) >= i + sizeof(tls_TLSPlaintext_header)); + memcpy(buffer + i, &tls_TLSPlaintext_header, sizeof(tls_TLSPlaintext_header)); + i += sizeof(tls_TLSPlaintext_header); #endif #if 0 /* Write TLS handshake header */ - r = write(tls_in, &TLSHandshake_header, sizeof(TLSHandshake_header)); + r = write(tls_in, &tls_Handshake_header, sizeof(tls_Handshake_header)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -1073,21 +1268,21 @@ int tls_live(void) /* log */ if (tls_out != -1) { - r = write(tls_out, &TLSHandshake_header, sizeof(TLSHandshake_header)); + r = write(tls_out, &tls_Handshake_header, sizeof(tls_Handshake_header)); if (r == 0 || r == -1) { perror("write"); return -1; } } #else - assert(sizeof(buffer) >= i + sizeof(TLSHandshake_header)); - memcpy(buffer + i, &TLSHandshake_header, sizeof(TLSHandshake_header)); - i += sizeof(TLSHandshake_header); + assert(sizeof(buffer) >= i + sizeof(tls_Handshake_header)); + memcpy(buffer + i, &tls_Handshake_header, sizeof(tls_Handshake_header)); + i += sizeof(tls_Handshake_header); #endif #if 0 /* Write TLS ClientHello Version, Random fields */ - r = write(tls_in, &client_hello_intro, sizeof(client_hello_intro)); + r = write(tls_in, &tls_ClientHello_intro, sizeof(tls_ClientHello_intro)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -1095,23 +1290,23 @@ int tls_live(void) /* log */ if (tls_out != -1) { - r = write(tls_out, &client_hello_intro, sizeof(client_hello_intro)); + r = write(tls_out, &tls_ClientHello_intro, sizeof(tls_ClientHello_intro)); if (r == 0 || r == -1) { perror("write"); return -1; } } #else - assert(sizeof(buffer) >= i + sizeof(client_hello_intro)); - memcpy(buffer + i, &client_hello_intro, sizeof(client_hello_intro)); - i += sizeof(client_hello_intro); + assert(sizeof(buffer) >= i + sizeof(tls_ClientHello_intro)); + memcpy(buffer + i, &tls_ClientHello_intro, sizeof(tls_ClientHello_intro)); + i += sizeof(tls_ClientHello_intro); #endif #if 0 /* Write TLS ClientHello Session ID */ - r = write(tls_in, &client_hello_session, - sizeof(client_hello_session.session_id_length) + - client_hello_session.session_id_length); + r = write(tls_in, &tls_ClientHello_session, + sizeof(tls_ClientHello_session.session_id_length) + + tls_ClientHello_session.session_id_length); if (r == 0 || r == -1) { perror("write"); return -1; @@ -1119,9 +1314,9 @@ int tls_live(void) /* log */ if (tls_out != -1) { - r = write(tls_out, &client_hello_session, - sizeof(client_hello_session.session_id_length) + - client_hello_session.session_id_length); + r = write(tls_out, &tls_ClientHello_session, + sizeof(tls_ClientHello_session.session_id_length) + + tls_ClientHello_session.session_id_length); if (r == 0 || r == -1) { perror("write"); return -1; @@ -1129,20 +1324,20 @@ int tls_live(void) } #else assert(sizeof(buffer) >= i + - sizeof(client_hello_session.session_id_length) + - client_hello_session.session_id_length); - memcpy(buffer + i, &client_hello_session, - sizeof(client_hello_session.session_id_length) + - client_hello_session.session_id_length); - i += sizeof(client_hello_session.session_id_length) + - client_hello_session.session_id_length; + sizeof(tls_ClientHello_session.session_id_length) + + tls_ClientHello_session.session_id_length); + memcpy(buffer + i, &tls_ClientHello_session, + sizeof(tls_ClientHello_session.session_id_length) + + tls_ClientHello_session.session_id_length); + i += sizeof(tls_ClientHello_session.session_id_length) + + tls_ClientHello_session.session_id_length; #endif #if 0 /* Write TLS ClientHello Ciphersuites */ - r = write(tls_in, &client_hello_ciphersuites, - sizeof(client_hello_ciphersuites.cipher_suites_length) + - n16toh16(client_hello_ciphersuites.cipher_suites_length)); + r = write(tls_in, &tls_ClientHello_ciphersuites, + sizeof(tls_ClientHello_ciphersuites.cipher_suites_length) + + n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -1150,9 +1345,9 @@ int tls_live(void) /* log */ if (tls_out != -1) { - r = write(tls_out, &client_hello_ciphersuites, - sizeof(client_hello_ciphersuites.cipher_suites_length) + - n16toh16(client_hello_ciphersuites.cipher_suites_length)); + r = write(tls_out, &tls_ClientHello_ciphersuites, + sizeof(tls_ClientHello_ciphersuites.cipher_suites_length) + + n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length)); if (r == 0 || r == -1) { perror("write"); return -1; @@ -1160,21 +1355,21 @@ int tls_live(void) } #else assert(sizeof(buffer) >= i + - sizeof(client_hello_ciphersuites.cipher_suites_length) + - n16toh16(client_hello_ciphersuites.cipher_suites_length)); - memcpy(buffer + i, &client_hello_ciphersuites, - sizeof(client_hello_ciphersuites.cipher_suites_length) + - n16toh16(client_hello_ciphersuites.cipher_suites_length)); - i += sizeof(client_hello_ciphersuites.cipher_suites_length) + - n16toh16(client_hello_ciphersuites.cipher_suites_length); + sizeof(tls_ClientHello_ciphersuites.cipher_suites_length) + + n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length)); + memcpy(buffer + i, &tls_ClientHello_ciphersuites, + sizeof(tls_ClientHello_ciphersuites.cipher_suites_length) + + n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length)); + i += sizeof(tls_ClientHello_ciphersuites.cipher_suites_length) + + n16toh16(tls_ClientHello_ciphersuites.cipher_suites_length); #endif #if 0 /* Write TLS ClientHello Compression methods */ - r = write(tls_in, &client_hello_compression, - sizeof(client_hello_compression.compression_methods_length) + - client_hello_compression.compression_methods_length); + r = write(tls_in, &tls_ClientHello_compression, + sizeof(tls_ClientHello_compression.compression_methods_length) + + tls_ClientHello_compression.compression_methods_length); if (r == 0 || r == -1) { perror("write"); return -1; @@ -1182,9 +1377,9 @@ int tls_live(void) /* log */ if (tls_out != -1) { - r = write(tls_out, &client_hello_compression, - sizeof(client_hello_compression.compression_methods_length) + - client_hello_compression.compression_methods_length); + r = write(tls_out, &tls_ClientHello_compression, + sizeof(tls_ClientHello_compression.compression_methods_length) + + tls_ClientHello_compression.compression_methods_length); if (r == 0 || r == -1) { perror("write"); return -1; @@ -1192,13 +1387,13 @@ int tls_live(void) } #else assert(sizeof(buffer) >= i + - sizeof(client_hello_compression.compression_methods_length) + - client_hello_compression.compression_methods_length); - memcpy(buffer + i, &client_hello_compression, - sizeof(client_hello_compression.compression_methods_length) + - client_hello_compression.compression_methods_length); - i += sizeof(client_hello_compression.compression_methods_length) + - client_hello_compression.compression_methods_length; + sizeof(tls_ClientHello_compression.compression_methods_length) + + tls_ClientHello_compression.compression_methods_length); + memcpy(buffer + i, &tls_ClientHello_compression, + sizeof(tls_ClientHello_compression.compression_methods_length) + + tls_ClientHello_compression.compression_methods_length); + i += sizeof(tls_ClientHello_compression.compression_methods_length) + + tls_ClientHello_compression.compression_methods_length; #endif r = write(tls_in, buffer, i); @@ -1313,12 +1508,19 @@ int tls_set_suites(uint16_t *suites, uint16_t suite_count) return 0; } -int tls_set_cb_cert(int (*handler)(uint8_t *, uint32_t)) +int tls_set_callback_handshake_certificate(int (*handler)(uint8_t *, uint32_t)) { tls_callbacks[SSL3_RT_HANDSHAKE][SSL3_MT_CERTIFICATE] = handler; return 0; } +int tls_set_callback_handshake_server_key_exchange( + int (*handler)(uint8_t *, uint32_t)) +{ + tls_callbacks[SSL3_RT_HANDSHAKE][SSL3_MT_SERVER_KEY_EXCHANGE] = handler; + return 0; +} + int tls_error() { return error_tls; diff --git a/scan/src/tls.h b/scan/src/tls.h index 9e214d3..666fcfa 100644 --- a/scan/src/tls.h +++ b/scan/src/tls.h @@ -6,24 +6,44 @@ #include "ciphersuites.h" /* converts 16 bits in host byte order to 16 bits in network byte order */ +#if !__BIG_ENDIAN__ #define h16ton16(n) \ ((uint16_t) (((uint16_t) n) << 8) | (uint16_t) (((uint16_t) n) >> 8)) +#else +#define h16ton16(n) (n) +#endif #define n16toh16(buf) h16ton16(buf) /* converts 24 bits in network byte order to 32 bits in host byte order */ +#if !__BIG_ENDIAN__ #define n24toh32(buf) \ (((uint32_t) *(((uint8_t*)buf) + 0)) << 16 |\ ((uint32_t) *(((uint8_t*)buf) + 1)) << 8 |\ ((uint32_t) *(((uint8_t*)buf) + 2)) << 0) +#else +#define n24toh32(buf) \ +(((uint32_t) *(((uint8_t*)buf) + 0)) >> 16 |\ + ((uint32_t) *(((uint8_t*)buf) + 1)) >> 8 |\ + ((uint32_t) *(((uint8_t*)buf) + 2)) >> 0) +#endif /* convers 24 bits in host byte order to 32 bits in network byte order */ +#if !__BIG_ENDIAN__ #define h24ton24(n,buf) \ {\ *(((uint8_t*)buf) + 0) = (uint8_t) (((uint32_t)n) >> 16);\ *(((uint8_t*)buf) + 1) = (uint8_t) (((uint32_t)n) >> 8);\ *(((uint8_t*)buf) + 2) = (uint8_t) (((uint32_t)n) >> 0);\ } +#else +#define h24ton24(n,buf) \ +{\ +*(((uint8_t*)buf) + 0) = (uint8_t) (((uint32_t)n) >> 0);\ +*(((uint8_t*)buf) + 1) = (uint8_t) (((uint32_t)n) >> 8);\ +*(((uint8_t*)buf) + 2) = (uint8_t) (((uint32_t)n) >> 16);\ +} +#endif /* @@ -47,7 +67,7 @@ struct __attribute__((__packed__)) uint8_t TLSPlaintext__versionMajor; uint8_t TLSPlaintext__versionMinor; uint16_t TLSPlaintext__length; -} TLSPlaintext_header = +} tls_TLSPlaintext_header = { .TLSPlaintext__versionMajor = PROTOCOLMAJOR, .TLSPlaintext__versionMinor = PROTOCOLMINOR @@ -67,7 +87,7 @@ struct __attribute__((__packed__)) /* Alert 2 bytes */ uint8_t Alert__level; /* AlertLevel */ uint8_t Alert__description; /* AlertDescription */ -} TLSAlert_header; +} tls_Alert; /* HandshakeType */ #define SSL3_MT_HELLO_REQUEST 0 @@ -86,7 +106,7 @@ struct __attribute__((__packed__)) /* Handshake 4 bytes */ uint8_t Handshake__type; /* HandshakeType */ uint8_t Handshake__length[3]; -} TLSHandshake_header; +} tls_Handshake_header; /* ClientHello */ @@ -96,7 +116,7 @@ struct __attribute__((__packed__)) uint8_t client_version_minor; uint32_t random_gmt_unix_time; uint8_t random_random_bytes[28]; -} client_hello_intro = +} tls_ClientHello_intro = { .client_version_major = PROTOCOLMAJOR, .client_version_minor = PROTOCOLMINOR @@ -106,7 +126,7 @@ struct __attribute__((__packed__)) { uint8_t session_id_length; uint8_t session_id[32]; -} client_hello_session = +} tls_ClientHello_session = { .session_id_length = 0 }; @@ -115,7 +135,7 @@ struct __attribute__((__packed__)) { uint16_t cipher_suites_length; uint16_t cipher_suites[(0xFFFF - 1)/sizeof(uint16_t)]; -} client_hello_ciphersuites = +} tls_ClientHello_ciphersuites = { .cipher_suites_length = 0x0200, .cipher_suites[0] = h16ton16(CIPHERSUITEMANDATORY) @@ -125,7 +145,7 @@ struct __attribute__((__packed__)) { uint8_t compression_methods_length; uint8_t compression_methods[0xFF]; -} client_hello_compression = +} tls_ClientHello_compression = { .compression_methods_length = 0x1, .compression_methods[0] = 0x0 @@ -145,7 +165,7 @@ struct __attribute__((__packed__)) uint16_t cipher_suites[1]; uint8_t compression_methods_length; uint8_t compression_methods[1]; -} client_hello_min = +} tls_ClientHello_min = { .session_id_length = 0, .cipher_suites_length = 0x0200, @@ -160,23 +180,23 @@ struct __attribute__((__packed__)) uint8_t server_version_minor; uint32_t random_gmt_unix_time; uint8_t random_random_bytes[28]; -} server_hello_intro; +} tls_ServerHello_intro; struct __attribute__((__packed__)) { uint8_t session_id_length; uint8_t session_id[32]; -} server_hello_session; +} tls_ServerHello_session; struct __attribute__((__packed__)) { uint16_t cipher_suite; -} server_hello_ciphersuite; +} tls_ServerHello_ciphersuite; struct __attribute__((__packed__)) { uint8_t compression_method; -} server_hello_compression; +} tls_ServerHello_compression; /* Smallest ServerHello */ @@ -190,18 +210,26 @@ struct __attribute__((__packed__)) uint8_t session_id_length; uint16_t cipher_suite; uint8_t compression_method; -} server_hello_min = +} tls_ServerHello_min = { .session_id_length = 0 }; +/* Extensions */ + +struct __attribute__((__packed__)) +{ + uint16_t extensions_length; + uint8_t extensions[0xFFFF]; +} tls_extensions; + /* Certificate */ struct __attribute__((__packed__)) { uint8_t certificate_length[3]; uint8_t certificate[0xFFFFFF]; -} asn1certificate; +} tls_ASN1Cert; /* Smallest ASN1 Certificate */ @@ -209,7 +237,7 @@ struct __attribute__((__packed__)) { uint8_t certificate_length[3]; uint8_t certificate[1]; -} asn1certificate_min = +} tls_ASN1Cert_min = { .certificate_length = {0x00, 0x00, 0x01} }; @@ -218,30 +246,100 @@ struct __attribute__((__packed__)) { uint8_t certificate_list_length[3]; uint8_t certificate_list[0xFFFFFF]; -} certificate; +} tls_Certificate; /* Smallest Certificate */ struct __attribute__((__packed__)) { uint8_t certificate_list_length[3]; -} certificate_min = +} tls_Certificate_min = { .certificate_list_length = {0x00, 0x00, 0x00} }; -/* Extension */ +/* Ephemeral DH parameters */ struct __attribute__((__packed__)) { - uint16_t extensions_length; - uint8_t extensions[0xFFFF]; -} extensions; + uint16_t dh_p_length; + uint8_t dh_p[0xFFFF]; + uint16_t dh_g_length; + uint8_t dh_g[0xFFFF]; + uint16_t dh_Ys_length; + uint8_t dh_Ys[0xFFFF]; +} tls_ServerDHParams; + +/* Digital signature */ + +#define TLS_HASH_ALGORITHMS_MAX 6 + +const char * tls_HashAlgorithmNames[TLS_HASH_ALGORITHMS_MAX + 1] = { + "none", /* 0 */ + "md5", /* 1 */ + "sha1", /* 2 */ + "sha224", /* 3 */ + "sha256", /* 4 */ + "sha384", /* 5 */ + "sha512", /* 6 */ +}; + +#define TLS_HASH_ALGORITHM_TXT(n) \ + (((n) >= 0 && (n) <= TLS_HASH_ALGORITHMS_MAX) ? \ + tls_HashAlgorithmNames[(n)] : "ERR_NOT_IMPLEMENTED") + +#define TLS_SIGNATURE_ALGORITHMS_MAX 3 + +const char * tls_SignatureAlgorithmNames[TLS_SIGNATURE_ALGORITHMS_MAX + 1] = { + "anonymous", /* 0 */ + "rsa", /* 1 */ + "dsa", /* 2 */ + "ecdsa", /* 3 */ +}; + +#define TLS_SIGNATURE_ALGORITHM_TXT(n) \ + (((n) >= 0 && (n) <= TLS_SIGNATURE_ALGORITHMS_MAX) ? \ + tls_SignatureAlgorithmNames[(n)] : "ERR_NOT_IMPLEMENTED") + +struct __attribute__((__packed__)) +{ + uint8_t algorithm_hash; + uint8_t algorithm_signature; + uint16_t signature_length; + uint8_t signature[0xFFFF]; +} tls_DigitallySigned; + +/* + * struct { + * select (KeyExchangeAlgorithm) { + * case dh_anon: + * ServerDHParams params; + * case dhe_dss: + * case dhe_rsa: + * ServerDHParams params; + * digitally-signed struct { + * opaque client_random[32]; + * opaque server_random[32]; + * ServerDHParams params; + * } signed_params; + * case rsa: + * case dh_dss: + * case dh_rsa: + * struct {}; + * // message is omitted for rsa, dh_dss, and dh_rsa + * // may be extended, e.g., for ECDH -- see [TLSECC] + * }; + * } ServerKeyExchange; + */ +struct __attribute__((__packed__)) { + void *params; + void *signed_params; +} tls_ServerKeyExchange; /* Auxiliary decoding functions and utilities */ -char *TLSContentType(uint8_t n) +char *tls_ContentType(uint8_t n) { switch (n) { /* 20*/ @@ -263,7 +361,7 @@ char *TLSContentType(uint8_t n) return ""; } -char *AlertLevel(uint8_t n) +char *tls_AlertLevel(uint8_t n) { switch(n) { /* 1 */ @@ -279,7 +377,7 @@ char *AlertLevel(uint8_t n) return ""; } -char *AlertDescription(uint8_t n) +char *tls_AlertDescription(uint8_t n) { switch(n) { /* 0 */ @@ -328,7 +426,7 @@ char *AlertDescription(uint8_t n) return ""; } -char *TLSHandshakeType(uint8_t n) +char *tls_HandshakeType(uint8_t n) { switch(n) { /* 0 */ diff --git a/scan/src/tls_api.h b/scan/src/tls_api.h index f56440f..37311ae 100644 --- a/scan/src/tls_api.h +++ b/scan/src/tls_api.h @@ -21,8 +21,40 @@ int tls_set_out (int fd); int tls_set_suites (uint16_t *suites, uint16_t suite_count); /* Configuration. Optional. Set a callback function to be invoked * for each certificate of a Certificate handshake message. */ -int tls_set_cb_cert ( - int (*handler)(uint8_t *certificate, uint32_t certificate_length)); +int tls_set_callback_handshake_certificate (int (*handler)( + uint8_t *certificate, uint32_t certificate_length)); +/* Configuration. Optional. Set a callback function to be invoked + * for each ServerKeyExchange handshake message. It is the responsibility + * of the function's implementation to correctly parse the message structure + * based on the key exchange algorithm. + */ +struct __attribute__((__packed__)) ServerDHParams { + uint16_t dh_p_length; + uint8_t dh_p[0xFFFF]; + uint16_t dh_g_length; + uint8_t dh_g[0xFFFF]; + uint16_t dh_Ys_length; + uint8_t dh_Ys[0xFFFF]; +}; +struct __attribute__((__packed__)) Signature { + uint8_t algorithm_hash; + uint8_t algorithm_signature; + uint16_t signature_length; + uint8_t signature[0xFFFF]; +}; +#define SERVER_KEYEXCHANGE_UNKNOWN 0x0 +#define SERVER_KEYEXCHANGE_DHPARAMS 0x7 +struct __attribute__((__packed__)) ServerKeyExchange_DHparams { + struct ServerDHParams *params; +}; +#define SERVER_KEYEXCHANGE_DHPARAMS_SIGNATURE (\ + 0x3 | SERVER_KEYEXCHANGE_DHPARAMS) +struct __attribute__((__packed__)) ServerKeyExchange_DHparams_signature { + struct ServerDHParams *params; + struct DigitallySigned *signed_params; +}; +int tls_set_callback_handshake_server_key_exchange (int (*handler)( + uint8_t *ServerKeyExchange, uint32_t ServerKeyExchangeType)); /* Execution. Live mode. Read from tls_in (logically a socket) and