conversation_add_proto_data(conversation, proto_dtls, ssl_session);
/* we need to know witch side of conversation is speaking */
- if (ssl_packet_from_server(dtls_associations, pinfo->srcport, pinfo->ptype == PT_TCP)) {
+ if (ssl_packet_from_server(ssl_session, dtls_associations, pinfo)) {
dummy.addr = pinfo->src;
dummy.port = pinfo->srcport;
}
}
/* retrive decoder for this packet direction */
- if ((direction = ssl_packet_from_server(dtls_associations, pinfo->srcport, pinfo->ptype == PT_TCP)) != 0) {
+ if ((direction = ssl_packet_from_server(ssl, dtls_associations, pinfo)) != 0) {
ssl_debug_printf("decrypt_dtls_record: using server decoder\n");
decoder = ssl->server;
}
record_length = tvb_get_ntohs(tvb, offset + 11);
if(ssl){
- if(ssl_packet_from_server(dtls_associations, pinfo->srcport, pinfo->ptype == PT_TCP)){
+ if(ssl_packet_from_server(ssl, dtls_associations, pinfo)){
if (ssl->server) {
ssl->server->seq=(guint32)sequence_number;
ssl->server->epoch=epoch;
}
}
- ssl_debug_printf("pcry_private_decrypt: stripping %d bytes, decr_len %zd\n",
+ ssl_debug_printf("pcry_private_decrypt: stripping %d bytes, decr_len %d\n",
rc, decr_len);
ssl_print_data("decrypted_unstrip_pre_master", decr_data_ptr, decr_len);
g_memmove(decr_data_ptr, &decr_data_ptr[rc], decr_len - rc);
/* if master_key is not yet generate, create it now*/
if (!(ssl_session->state & SSL_MASTER_SECRET)) {
ssl_debug_printf("ssl_generate_keyring_material:PRF(pre_master_secret)\n");
+ ssl_print_string("pre master secret",&ssl_session->pre_master_secret);
+ ssl_print_string("client random",&ssl_session->client_random);
+ ssl_print_string("server random",&ssl_session->server_random);
if (PRF(ssl_session,&ssl_session->pre_master_secret,"master secret",
&ssl_session->client_random,
&ssl_session->server_random, &ssl_session->master_secret)) {
g_free((Ssl_private_key_t*)key);
}
+gint
+ssl_find_private_key(SslDecryptSession *ssl_session, GHashTable *key_hash, GTree* associations, packet_info *pinfo) {
+ SslService dummy;
+ char ip_addr_any[] = {0,0,0,0};
+ guint32 port = 0;
+ Ssl_private_key_t * private_key;
+
+ /* we need to know which side of the conversation is speaking */
+ if (ssl_packet_from_server(ssl_session, associations, pinfo)) {
+ dummy.addr = pinfo->src;
+ dummy.port = port = pinfo->srcport;
+ } else {
+ dummy.addr = pinfo->dst;
+ dummy.port = port = pinfo->destport;
+ }
+ ssl_debug_printf("ssl_find_private_key server %s:%u\n",
+ address_to_str(&dummy.addr),dummy.port);
+
+ /* try to retrieve private key for this service. Do it now 'cause pinfo
+ * is not always available
+ * Note that with HAVE_LIBGNUTLS undefined private_key is allways 0
+ * and thus decryption never engaged*/
+
+
+ ssl_session->private_key = 0;
+ private_key = g_hash_table_lookup(key_hash, &dummy);
+
+ if (!private_key) {
+ ssl_debug_printf("ssl_find_private_key can't find private key for this server! Try it again with universal port 0\n");
+
+ dummy.port = 0;
+ private_key = g_hash_table_lookup(key_hash, &dummy);
+ }
+
+ if (!private_key) {
+ ssl_debug_printf("ssl_find_private_key can't find private key for this server (universal port)! Try it again with universal address 0.0.0.0\n");
+
+ dummy.addr.type = AT_IPv4;
+ dummy.addr.len = 4;
+ dummy.addr.data = ip_addr_any;
+
+ dummy.port = port;
+ private_key = g_hash_table_lookup(key_hash, &dummy);
+ }
+
+ if (!private_key) {
+ ssl_debug_printf("ssl_find_private_key can't find any private key!\n");
+ } else {
+ ssl_session->private_key = private_key->sexp_pkey;
+ }
+
+ return 0;
+}
+
void
ssl_lib_init(void)
{
{
}
+gint
+ssl_find_private_key(SslDecryptSession *ssl_session _U_, GHashTable *key_hash _U_, GTree* associations _U_, packet_info *pinfo _U_)
+{
+}
+
int
ssl_find_cipher(int num,SslCipherSuite* cs)
{
ssl_session->client_data_for_iv.data = ssl_session->_client_data_for_iv;
ssl_session->app_data_segment.data=NULL;
ssl_session->app_data_segment.data_len=0;
+ SET_ADDRESS(&ssl_session->srv_addr, AT_NONE, 0, NULL);
+ ssl_session->srv_ptype = PT_NONE;
+ ssl_session->srv_port = 0;
+}
+
+void
+ssl_set_server(SslDecryptSession* ssl, address *addr, port_type ptype, guint32 port)
+{
+ SE_COPY_ADDRESS(&ssl->srv_addr, addr);
+ ssl->srv_ptype = ptype;
+ ssl->srv_port = port;
}
/* Hash Functions for TLS/DTLS sessions table and private keys table*/
}
int
-ssl_packet_from_server(GTree* associations, guint port, gboolean tcp)
+ssl_packet_from_server(SslDecryptSession* ssl, GTree* associations, packet_info *pinfo)
{
- register gint ret;
- ret = ssl_association_find(associations, port, tcp) != 0;
+ gint ret;
+ if (ssl && (ssl->srv_ptype != PT_NONE)) {
+ ret = (ssl->srv_ptype == pinfo->ptype) && (ssl->srv_port == pinfo->srcport) && ADDRESSES_EQUAL(&ssl->srv_addr, &pinfo->src);
+ } else {
+ ret = ssl_association_find(associations, pinfo->srcport, pinfo->ptype == PT_TCP) != 0;
+ }
ssl_debug_printf("packet_from_server: is from server - %s\n", (ret)?"TRUE":"FALSE");
return ret;
guint16 version_netorder;
StringInfo app_data_segment;
+ address srv_addr;
+ port_type srv_ptype;
+ guint srv_port;
+
} SslDecryptSession;
typedef struct _SslAssociation {
extern void
ssl_session_init(SslDecryptSession* ssl);
+/** Set server address and port */
+extern void
+ssl_set_server(SslDecryptSession* ssl, address *addr, port_type ptype, guint32 port);
+
/** set the data and len for the stringInfo buffer. buf should be big enough to
* contain the provided data
@param buf the buffer to update
extern void
ssl_free_key(Ssl_private_key_t* key);
+/* Find private key in associations */
+extern gint
+ssl_find_private_key(SslDecryptSession *ssl_session, GHashTable *key_hash, GTree* associations, packet_info *pinfo);
+
/* Search for the specified cipher souite id
@param num the id of the cipher suite to be searched
@param cs pointer to the cipher suite struct to be filled
ssl_assoc_from_key_list(gpointer key _U_, gpointer data, gpointer user_data);
extern gint
-ssl_packet_from_server(GTree* associations, guint port, gboolean tcp);
+ssl_packet_from_server(SslDecryptSession* ssl, GTree* associations, packet_info *pinfo);
/* add to packet data a newly allocated tvb with the specified real data*/
extern void
gboolean need_desegmentation;
SslDecryptSession* ssl_session;
guint* conv_version;
- Ssl_private_key_t * private_key;
- guint32 port;
ti = NULL;
ssl_tree = NULL;
offset = 0;
first_record_in_frame = TRUE;
ssl_session = NULL;
- port = 0;
ssl_debug_printf("\ndissect_ssl enter frame #%u (%s)\n", pinfo->fd->num, (pinfo->fd->flags.visited)?"already visited":"first time");
if (conv_data != NULL)
ssl_session = conv_data;
else {
- SslService dummy;
- char ip_addr_any[] = {0,0,0,0};
-
ssl_session = se_alloc0(sizeof(SslDecryptSession));
ssl_session_init(ssl_session);
ssl_session->version = SSL_VER_UNKNOWN;
conversation_add_proto_data(conversation, proto_ssl, ssl_session);
-
- /* we need to know which side of the conversation is speaking */
- if (ssl_packet_from_server(ssl_associations, pinfo->srcport, pinfo->ptype == PT_TCP)) {
- dummy.addr = pinfo->src;
- dummy.port = port = pinfo->srcport;
- } else {
- dummy.addr = pinfo->dst;
- dummy.port = port = pinfo->destport;
- }
- ssl_debug_printf("dissect_ssl server %s:%u\n",
- address_to_str(&dummy.addr),dummy.port);
-
- /* try to retrieve private key for this service. Do it now 'cause pinfo
- * is not always available
- * Note that with HAVE_LIBGNUTLS undefined private_key is allways 0
- * and thus decryption never engaged*/
-
-
- ssl_session->private_key = 0;
- private_key = g_hash_table_lookup(ssl_key_hash, &dummy);
-
- if (!private_key) {
- ssl_debug_printf("dissect_ssl can't find private key for this server! Try it again with universal port 0\n");
-
- dummy.port = 0;
- private_key = g_hash_table_lookup(ssl_key_hash, &dummy);
- }
-
- if (!private_key) {
- ssl_debug_printf("dissect_ssl can't find private key for this server (universal port)! Try it again with universal address 0.0.0.0\n");
-
- dummy.addr.type = AT_IPv4;
- dummy.addr.len = 4;
- dummy.addr.data = ip_addr_any;
-
- dummy.port = port;
- private_key = g_hash_table_lookup(ssl_key_hash, &dummy);
- }
-
- if (!private_key) {
- ssl_debug_printf("dissect_ssl can't find any private key!\n");
- } else {
- ssl_session->private_key = private_key->sexp_pkey;
- }
-
}
conv_version =& ssl_session->version;
/* try decryption only the first time we see this packet
- * (to keep cipher synchronized) and only if we have
- * the server private key*/
+ * (to keep cipher synchronized) */
if (pinfo->fd->flags.visited)
ssl_session = NULL;
* add decrypted data to this packet info */
ssl_debug_printf("decrypt_ssl3_record: app_data len %d ssl, state 0x%02X\n",
record_length, ssl->state);
- direction = ssl_packet_from_server(ssl_associations, pinfo->srcport, pinfo->ptype == PT_TCP);
+ direction = ssl_packet_from_server(ssl, ssl_associations, pinfo);
/* retrieve decoder for this packet direction */
if (direction != 0) {
col_append_str(pinfo->cinfo, COL_INFO, "Change Cipher Spec");
dissect_ssl3_change_cipher_spec(tvb, ssl_record_tree,
offset, conv_version, content_type);
- if (ssl) ssl_change_cipher(ssl, ssl_packet_from_server(ssl_associations, pinfo->srcport, pinfo->ptype == PT_TCP));
+ if (ssl) ssl_change_cipher(ssl, ssl_packet_from_server(ssl, ssl_associations, pinfo));
break;
case SSL_ID_ALERT:
{
compression_methods_length = 0;
start_offset = offset;
+ if (ssl) {
+ ssl_set_server(ssl, &pinfo->dst, pinfo->ptype, pinfo->destport);
+ ssl_find_private_key(ssl, ssl_key_hash, ssl_associations, pinfo);
+ }
+
if (tree || ssl)
{
/* show the client version */
return;
}
+ if (ssl) {
+ ssl_set_server(ssl, &pinfo->dst, pinfo->ptype, pinfo->destport);
+ ssl_find_private_key(ssl, ssl_key_hash, ssl_associations, pinfo);
+ }
+
if (tree || ssl)
{
/* show the version */
tvb_memcpy(tvb, &ssl->client_random.data[32 - max], offset, max);
ssl->client_random.data_len = 32;
ssl->state |= SSL_CLIENT_RANDOM;
-
+ ssl_debug_printf("dissect_ssl2_hnd_client_hello found CLIENT RANDOM -> state 0x%02X\n", ssl->state);
}
offset += challenge_length;
}
ssl_debug_printf(" conversation = %p, ssl_session = %p\n", (void *)conversation, (void *)ssl);
+ ssl_set_server(ssl, addr_srv, ptype, port_srv);
+
/* version */
if ((ssl->version==SSL_VER_UNKNOWN) && (version!=SSL_VER_UNKNOWN)) {
switch (version) {