From: Eric Leblond Date: Wed, 18 Jul 2012 13:13:49 +0000 (+0200) Subject: tls: keep pointers to all certificates in chain X-Git-Tag: suricata-1.4beta1~69 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=152b4eaf568d1685cd18b76d09f04ba5111da153;p=thirdparty%2Fsuricata.git tls: keep pointers to all certificates in chain When multiple certificates forming a chain are sent. A pointer to the start of each certificate is kept. This will allow treatment on certificates chains. --- diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c index 6c71a44c19..1571636317 100644 --- a/src/app-layer-ssl.c +++ b/src/app-layer-ssl.c @@ -862,6 +862,7 @@ void *SSLStateAlloc(void) memset(ssl_state, 0, sizeof(SSLState)); ((SSLState*)ssl_state)->client_connp.cert_log_flag = 0; ((SSLState*)ssl_state)->server_connp.cert_log_flag = 0; + TAILQ_INIT(&((SSLState*)ssl_state)->server_connp.certs); return ssl_state; } @@ -873,6 +874,7 @@ void *SSLStateAlloc(void) void SSLStateFree(void *p) { SSLState *ssl_state = (SSLState *)p; + SSLCertsChain *item; if (ssl_state->client_connp.trec) SCFree(ssl_state->client_connp.trec); @@ -892,6 +894,13 @@ void SSLStateFree(void *p) if (ssl_state->server_connp.cert0_fingerprint) SCFree(ssl_state->server_connp.cert0_fingerprint); + /* Free certificate chain */ + while ((item = TAILQ_FIRST(&ssl_state->server_connp.certs))) { + TAILQ_REMOVE(&ssl_state->server_connp.certs, item, next); + SCFree(item); + } + TAILQ_INIT(&ssl_state->server_connp.certs); + SCFree(ssl_state); return; diff --git a/src/app-layer-ssl.h b/src/app-layer-ssl.h index 1d6f1f81bb..9ca516f7b4 100644 --- a/src/app-layer-ssl.h +++ b/src/app-layer-ssl.h @@ -27,6 +27,7 @@ #define __APP_LAYER_SSL_H__ #include "decode-events.h" +#include "queue.h" enum { /* TLS protocol messages */ @@ -79,6 +80,13 @@ enum { TLS_VERSION_12 = 0x0303, }; +typedef struct SSLCertsChain_ { + uint8_t *cert_data; + uint32_t cert_len; + TAILQ_ENTRY(SSLCertsChain_) next; +} SSLCertsChain; + + typedef struct SSLStateConnp_ { /* record length */ uint32_t record_length; @@ -108,6 +116,8 @@ typedef struct SSLStateConnp_ { uint8_t *cert_input; uint32_t cert_input_len; + TAILQ_HEAD(, SSLCertsChain_) certs; + uint32_t cert_log_flag; /* buffer for the tls record. diff --git a/src/app-layer-tls-handshake.c b/src/app-layer-tls-handshake.c index 8c086cbeec..a9cffe09bf 100644 --- a/src/app-layer-tls-handshake.c +++ b/src/app-layer-tls-handshake.c @@ -122,6 +122,7 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uin if (rc != 0) { TLSCertificateErrCodeToWarning(ssl_state, errcode); } else { + SSLCertsChain *ncert; //SCLogInfo("TLS Cert %d: %s\n", i, buffer); if (i==0) { ssl_state->server_connp.cert0_subject = SCStrdup(buffer); @@ -130,6 +131,15 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uin return -1; } } + ncert = (SSLCertsChain *)SCMalloc(sizeof(SSLCertsChain)); + if (ncert == NULL) { + DerFree(cert); + return -1; + } + memset(ncert, 0, sizeof(*ncert)); + ncert->cert_data = input; + ncert->cert_len = cur_cert_length; + TAILQ_INSERT_TAIL(&ssl_state->server_connp.certs, ncert, next); } rc = Asn1DerGetIssuerDN(cert, buffer, sizeof(buffer), &errcode); if (rc != 0) {