aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2018-03-19 21:41:42 +0100
committerPeter Wu <peter@lekensteyn.nl>2018-03-21 18:12:43 +0000
commiteea63ae2a7f41332ae3b7da39513d184662494a2 (patch)
tree4eb96f418c63c6f8c60c7e85199b1c26d8e3bbce
parent184b943fbd4c113998419ed377f81aad0e2f43b9 (diff)
TLS: allow cipher information to be retrieved
In preparation for QUIC packet decryption, add a method to retrieve the cipher used in a TLS session. (QUIC embeds the TLS handshake.) Change-Id: If58e16bd0a01808dafa455ddc6c67ad23f33d7da Reviewed-on: https://code.wireshark.org/review/26558 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Peter Wu <peter@lekensteyn.nl>
-rw-r--r--epan/dissectors/packet-ssl-utils.c6
-rw-r--r--epan/dissectors/packet-ssl-utils.h5
-rw-r--r--epan/dissectors/packet-ssl.c69
-rw-r--r--epan/dissectors/packet-ssl.h6
4 files changed, 86 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c
index b75c55b2b5..fe7f255e41 100644
--- a/epan/dissectors/packet-ssl-utils.c
+++ b/epan/dissectors/packet-ssl-utils.c
@@ -2405,6 +2405,12 @@ ssl_find_cipher(int num)
return NULL;
}
+int
+ssl_get_cipher_algo(const SslCipherSuite *cipher_suite)
+{
+ return gcry_cipher_map_name(ciphers[cipher_suite->enc - 0x30]);
+}
+
guint
ssl_get_cipher_blocksize(const SslCipherSuite *cipher_suite)
{
diff --git a/epan/dissectors/packet-ssl-utils.h b/epan/dissectors/packet-ssl-utils.h
index 6df90e1563..d861370d7a 100644
--- a/epan/dissectors/packet-ssl-utils.h
+++ b/epan/dissectors/packet-ssl-utils.h
@@ -591,6 +591,11 @@ ssl_cipher_setiv(SSL_CIPHER_CTX *cipher, guchar* iv, gint iv_len);
extern const SslCipherSuite *
ssl_find_cipher(int num);
+
+/** Returns the Libgcrypt cipher identifier or 0 if unavailable. */
+int
+ssl_get_cipher_algo(const SslCipherSuite *cipher_suite);
+
/** Obtains the block size for a CBC block cipher.
* @param cipher_suite a cipher suite as returned by ssl_find_cipher().
* @return the block size of a cipher or 0 if unavailable.
diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c
index fcedd8517c..5b2785472e 100644
--- a/epan/dissectors/packet-ssl.c
+++ b/epan/dissectors/packet-ssl.c
@@ -95,6 +95,10 @@
/* Whether to provide support for authentication in addition to decryption. */
#define HAVE_LIBGCRYPT_AEAD
#endif
+#if GCRYPT_VERSION_NUMBER >= 0x010700 /* 1.7.0 */
+/* Whether AEAD_CHACHA20_POLY1305 can be supported. */
+#define HAVE_LIBGCRYPT_CHACHA20_POLY1305
+#endif
void proto_register_ssl(void);
@@ -3846,6 +3850,71 @@ ssl_looks_like_valid_pct_handshake(tvbuff_t *tvb, const guint32 offset,
return ret;
}
+gboolean
+tls_get_cipher_info(packet_info *pinfo, int *cipher_algo, int *cipher_mode, int *hash_algo)
+{
+ conversation_t *conv = find_conversation_pinfo(pinfo, 0);
+ if (!conv) {
+ return FALSE;
+ }
+
+ void *conv_data = conversation_get_proto_data(conv, proto_ssl);
+ if (conv_data == NULL) {
+ return FALSE;
+ }
+
+ SslDecryptSession *ssl_session = (SslDecryptSession *)conv_data;
+ const SslCipherSuite *suite = ssl_find_cipher(ssl_session->session.cipher);
+ if (!suite) {
+ return FALSE;
+ }
+
+ /* adapted from ssl_cipher_init in packet-ssl-utils.c */
+ static const gint gcry_modes[] = {
+ GCRY_CIPHER_MODE_STREAM,
+ GCRY_CIPHER_MODE_CBC,
+#ifdef HAVE_LIBGCRYPT_AEAD
+ GCRY_CIPHER_MODE_GCM,
+ GCRY_CIPHER_MODE_CCM,
+ GCRY_CIPHER_MODE_CCM,
+#else
+ -1, /* Do not bother with fallback support. */
+ -1,
+ -1,
+#endif
+#ifdef HAVE_LIBGCRYPT_CHACHA20_POLY1305
+ GCRY_CIPHER_MODE_POLY1305,
+#else
+ -1, /* AEAD_CHACHA20_POLY1305 is unsupported. */
+#endif
+ };
+ static const int gcry_mds[] = {
+ GCRY_MD_MD5,
+ GCRY_MD_SHA1,
+ GCRY_MD_SHA256,
+ GCRY_MD_SHA384,
+ -1,
+ };
+ int mode = gcry_modes[suite->mode];
+ int cipher_algo_id = ssl_get_cipher_algo(suite);
+ int hash_algo_id = gcry_mds[suite->dig-DIG_MD5];
+ if (mode == -1 || cipher_algo_id == 0 || hash_algo_id == -1) {
+ /* Identifiers are unusable, fail. */
+ return FALSE;
+ }
+ if (cipher_algo) {
+ *cipher_algo = cipher_algo_id;
+ }
+ if (cipher_mode) {
+ *cipher_mode = mode;
+ }
+ if (hash_algo) {
+ *hash_algo = hash_algo_id;
+ }
+
+ return TRUE;
+}
+
/* TLS Exporters {{{ */
#if GCRYPT_VERSION_NUMBER >= 0x010600 /* 1.6.0 */
/**
diff --git a/epan/dissectors/packet-ssl.h b/epan/dissectors/packet-ssl.h
index 71e365f1d1..02334cff55 100644
--- a/epan/dissectors/packet-ssl.h
+++ b/epan/dissectors/packet-ssl.h
@@ -27,6 +27,12 @@ WS_DLL_PUBLIC void ssl_set_master_secret(guint32 frame_num, address *addr_srv, a
guint32 version, gint cipher, const guchar *_master_secret,
const guchar *_client_random, const guchar *_server_random,
guint32 client_seq, guint32 server_seq);
+/**
+ * Retrieves Libgcrypt identifiers for the current TLS cipher. Only valid after
+ * the Server Hello has been processed and if the current conversation has TLS.
+ */
+extern gboolean
+tls_get_cipher_info(packet_info *pinfo, int *cipher_algo, int *cipher_mode, int *hash_algo);
/**
* Computes the TLS 1.3 "TLS-Exporter(label, context_value, key_length)" value.