]> git.ipfire.org Git - people/ms/suricata.git/commitdiff
app-layer-tls: decode certificate serial number
authorMats Klepsland <mats.klepsland@gmail.com>
Tue, 17 Jan 2017 08:20:25 +0000 (09:20 +0100)
committerVictor Julien <victor@inliniac.net>
Tue, 21 Feb 2017 08:57:55 +0000 (09:57 +0100)
src/app-layer-ssl.c
src/app-layer-ssl.h
src/app-layer-tls-handshake.c
src/util-decode-der-get.c
src/util-decode-der-get.h

index 58f54feea67c94cd7349cf135a658e6b52dd4dfb..f6839adc5ff2a91324641807cda560c6b95593aa 100644 (file)
@@ -1540,6 +1540,8 @@ void SSLStateFree(void *p)
         SCFree(ssl_state->client_connp.cert0_subject);
     if (ssl_state->client_connp.cert0_issuerdn)
         SCFree(ssl_state->client_connp.cert0_issuerdn);
+    if (ssl_state->server_connp.cert0_serial)
+        SCFree(ssl_state->server_connp.cert0_serial);
     if (ssl_state->client_connp.cert0_fingerprint)
         SCFree(ssl_state->client_connp.cert0_fingerprint);
     if (ssl_state->client_connp.sni)
index d2279e2f2b43638b4f78e8b04e16b6704be3e061..f23757836683a8f09e05e5db952c2ec84dcb08fe 100644 (file)
@@ -149,6 +149,7 @@ typedef struct SSLStateConnp_ {
 
     char *cert0_subject;
     char *cert0_issuerdn;
+    char *cert0_serial;
     time_t cert0_not_before;
     time_t cert0_not_after;
     char *cert0_fingerprint;
index 9ae3a1080164fc1565a80cb11ed2dd0ab125e385..6c3226f2d5bcd6515da4a0e7fad11305e94ac411 100644 (file)
@@ -177,6 +177,21 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input,
                 }
             }
 
+            rc = Asn1DerGetSerial(cert, buffer, sizeof(buffer), &errcode);
+            if (rc != 0) {
+                TLSCertificateErrCodeToWarning(ssl_state, errcode);
+            } else {
+                if (i == 0) {
+                    if (ssl_state->server_connp.cert0_serial == NULL) {
+                        ssl_state->server_connp.cert0_serial = SCStrdup(buffer);
+                    }
+                    if (ssl_state->server_connp.cert0_serial == NULL) {
+                        DerFree(cert);
+                        return -1;
+                    }
+                }
+            }
+
             rc = Asn1DerGetValidity(cert, &not_before, &not_after, &errcode);
             if (rc != 0) {
                 TLSCertificateErrCodeToWarning(ssl_state, errcode);
index fc132cf45e2d5125d0b811e7793b13c2547cc252..3e90788f745952122589d829287c03927d4e1df2 100644 (file)
@@ -37,6 +37,7 @@
 #include "util-decode-der.h"
 #include "util-decode-der-get.h"
 
+static const uint8_t SEQ_IDX_SERIAL[] = { 0, 0 };
 static const uint8_t SEQ_IDX_ISSUER[] = { 0, 2 };
 static const uint8_t SEQ_IDX_VALIDITY[] = { 0, 3 };
 static const uint8_t SEQ_IDX_SUBJECT[] = { 0, 4 };
@@ -241,6 +242,50 @@ validity_error:
     return rc;
 }
 
+int Asn1DerGetSerial(const Asn1Generic *cert, char *buffer, uint32_t length,
+                       uint32_t *errcode)
+{
+    const Asn1Generic *node;
+    uint32_t node_len, i;
+    int rc = -1;
+
+    if (errcode)
+        *errcode = ERR_DER_MISSING_ELEMENT;
+
+    buffer[0] = '\0';
+
+    node = Asn1DerGet(cert, SEQ_IDX_SERIAL, sizeof(SEQ_IDX_SERIAL), errcode);
+    if ((node == NULL) || node->type != ASN1_INTEGER || node->str == NULL)
+        goto serial_error;
+
+    node_len = strlen(node->str);
+
+    /* make sure the buffer is big enough */
+    if (node_len + (node_len / 2) > length)
+        goto serial_error;
+
+    /* format serial number (e.g. XX:XX:XX:XX:XX) */
+    for (i = 0; i < node_len; i++) {
+        char c[3];
+        /* insert separator before each even number */
+        if (((i % 2) == 0) && (i != 0)) {
+            snprintf(c, sizeof(c), ":%c", node->str[i]);
+        } else {
+            snprintf(c, sizeof(c), "%c", node->str[i]);
+        }
+
+        strlcat(buffer, c, length);
+    }
+
+    if (errcode)
+        *errcode = 0;
+
+    rc = 0;
+
+serial_error:
+    return rc;
+}
+
 int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length,
                        uint32_t *errcode)
 {
index 2d2168aeb3f3be28b9539d22c5ab31a34c72b7a5..bed1cfebedba8070e550939b62a208fba2346edc 100644 (file)
@@ -38,6 +38,7 @@
 const Asn1Generic * Asn1DerGet(const Asn1Generic *top, const uint8_t *seq_index, const uint32_t seqsz, uint32_t *errcode);
 
 int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length, uint32_t *errcode);
+int Asn1DerGetSerial(const Asn1Generic *cert, char *buffer, uint32_t length, uint32_t *errcode);
 int Asn1DerGetValidity(const Asn1Generic *cert, time_t *not_before, time_t *not_after, uint32_t *errcode);
 int Asn1DerGetSubjectDN(const Asn1Generic *cert, char *buffer, uint32_t length, uint32_t *errcode);