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.
pull/34/head
Eric Leblond 13 years ago
parent c4df7a45ae
commit 152b4eaf56

@ -862,6 +862,7 @@ void *SSLStateAlloc(void)
memset(ssl_state, 0, sizeof(SSLState)); memset(ssl_state, 0, sizeof(SSLState));
((SSLState*)ssl_state)->client_connp.cert_log_flag = 0; ((SSLState*)ssl_state)->client_connp.cert_log_flag = 0;
((SSLState*)ssl_state)->server_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; return ssl_state;
} }
@ -873,6 +874,7 @@ void *SSLStateAlloc(void)
void SSLStateFree(void *p) void SSLStateFree(void *p)
{ {
SSLState *ssl_state = (SSLState *)p; SSLState *ssl_state = (SSLState *)p;
SSLCertsChain *item;
if (ssl_state->client_connp.trec) if (ssl_state->client_connp.trec)
SCFree(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) if (ssl_state->server_connp.cert0_fingerprint)
SCFree(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); SCFree(ssl_state);
return; return;

@ -27,6 +27,7 @@
#define __APP_LAYER_SSL_H__ #define __APP_LAYER_SSL_H__
#include "decode-events.h" #include "decode-events.h"
#include "queue.h"
enum { enum {
/* TLS protocol messages */ /* TLS protocol messages */
@ -79,6 +80,13 @@ enum {
TLS_VERSION_12 = 0x0303, TLS_VERSION_12 = 0x0303,
}; };
typedef struct SSLCertsChain_ {
uint8_t *cert_data;
uint32_t cert_len;
TAILQ_ENTRY(SSLCertsChain_) next;
} SSLCertsChain;
typedef struct SSLStateConnp_ { typedef struct SSLStateConnp_ {
/* record length */ /* record length */
uint32_t record_length; uint32_t record_length;
@ -108,6 +116,8 @@ typedef struct SSLStateConnp_ {
uint8_t *cert_input; uint8_t *cert_input;
uint32_t cert_input_len; uint32_t cert_input_len;
TAILQ_HEAD(, SSLCertsChain_) certs;
uint32_t cert_log_flag; uint32_t cert_log_flag;
/* buffer for the tls record. /* buffer for the tls record.

@ -122,6 +122,7 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uin
if (rc != 0) { if (rc != 0) {
TLSCertificateErrCodeToWarning(ssl_state, errcode); TLSCertificateErrCodeToWarning(ssl_state, errcode);
} else { } else {
SSLCertsChain *ncert;
//SCLogInfo("TLS Cert %d: %s\n", i, buffer); //SCLogInfo("TLS Cert %d: %s\n", i, buffer);
if (i==0) { if (i==0) {
ssl_state->server_connp.cert0_subject = SCStrdup(buffer); ssl_state->server_connp.cert0_subject = SCStrdup(buffer);
@ -130,6 +131,15 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uin
return -1; 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); rc = Asn1DerGetIssuerDN(cert, buffer, sizeof(buffer), &errcode);
if (rc != 0) { if (rc != 0) {

Loading…
Cancel
Save