]> git.ipfire.org Git - people/ms/suricata.git/commitdiff
DER: remove the C parser for DER
authorPierre Chifflier <chifflier@wzdftpd.net>
Mon, 9 Mar 2020 19:35:27 +0000 (20:35 +0100)
committerPierre Chifflier <chifflier@wzdftpd.net>
Mon, 23 Mar 2020 15:54:20 +0000 (16:54 +0100)
configure.ac
src/Makefile.am
src/app-layer-ssl.c
src/suricata.c
src/util-decode-der-get.c [deleted file]
src/util-decode-der-get.h [deleted file]
src/util-decode-der.c [deleted file]
src/util-decode-der.h [deleted file]

index 0d73ef77415f939a5b55900da189d3676b265f57..dd053c134b97b023ce11f800bd32e88b3612a2e1 100644 (file)
         AC_DEFINE([AFLFUZZ_APPLAYER], [1], [Enable --afl-$proto-request commandline option])
         AC_DEFINE([AFLFUZZ_MIME], [1], [Enable --afl-mime commandline option])
         AC_DEFINE([AFLFUZZ_DECODER], [1], [Enable --afl-decoder-$proto commandline option])
-        AC_DEFINE([AFLFUZZ_DER], [1], [Enable --afl-der commandline option])
         AC_DEFINE([AFLFUZZ_RULES], [1], [Enable --afl-rules commandline option])
 
         # test for AFL PERSISTANT_MODE support
index 6788ee2dc082651e7c6ce1816ecbe0349f5e2772..28cf620071ca04b708ff0a7b3b14468be4600d8e 100755 (executable)
@@ -444,8 +444,6 @@ util-daemon.c util-daemon.h \
 util-debug.c util-debug.h \
 util-debug-filters.c util-debug-filters.h \
 util-decode-asn1.c util-decode-asn1.h \
-util-decode-der.c util-decode-der.h \
-util-decode-der-get.c util-decode-der-get.h \
 util-decode-mime.c util-decode-mime.h \
 util-detect.c util-detect.h \
 util-device.c util-device.h \
index 8b3e43b2cad629172e0f9c21f8ea137cbb522c96..e5e66194823bac5847367f06be9ca4722882a2fb 100644 (file)
@@ -43,8 +43,6 @@
 #include "conf.h"
 
 #include "util-crypt.h"
-#include "util-decode-der.h"
-#include "util-decode-der-get.h"
 #include "util-spm.h"
 #include "util-unittest.h"
 #include "util-debug.h"
@@ -355,36 +353,6 @@ void SSLVersionToString(uint16_t version, char *buffer)
     }
 }
 
-static void TlsDecodeHSCertificateErrSetEvent(SSLState *ssl_state, uint32_t err)
-{
-    switch (err) {
-        case ERR_DER_UNKNOWN_ELEMENT:
-            SSLSetEvent(ssl_state,
-                        TLS_DECODER_EVENT_CERTIFICATE_UNKNOWN_ELEMENT);
-            break;
-        case ERR_DER_ELEMENT_SIZE_TOO_BIG:
-        case ERR_DER_INVALID_SIZE:
-        case ERR_DER_RECURSION_LIMIT:
-            SSLSetEvent(ssl_state,
-                        TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH);
-            break;
-        case ERR_DER_UNSUPPORTED_STRING:
-            SSLSetEvent(ssl_state,
-                        TLS_DECODER_EVENT_CERTIFICATE_INVALID_STRING);
-            break;
-        case ERR_DER_MISSING_ELEMENT:
-            SSLSetEvent(ssl_state,
-                        TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT);
-            break;
-        case ERR_DER_INVALID_TAG:
-        case ERR_DER_INVALID_OBJECT:
-        case ERR_DER_GENERIC:
-        default:
-            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_CERTIFICATE);
-            break;
-    }
-}
-
 static inline int TlsDecodeHSCertificateFingerprint(SSLState *ssl_state,
                                                     const uint8_t *input,
                                                     uint32_t cert_len)
@@ -464,7 +432,7 @@ static int TlsDecodeHSCertificate(SSLState *ssl_state,
 
             x509 = rs_x509_decode(input, cert_len);
             if (x509 == NULL) {
-                TlsDecodeHSCertificateErrSetEvent(ssl_state, ERR_DER_GENERIC);
+                SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_CERTIFICATE);
                 goto next;
             }
 
index 89e9cc69d9519b1b1949bf634864bb1fa3fef0c0..a60fa74b7fa9c1d5fb873a47b4d2d52ea26987e5 100644 (file)
 #include "app-layer-smb.h"
 #include "app-layer-dcerpc.h"
 
-#include "util-decode-der.h"
 #include "util-ebpf.h"
 #include "util-radix-tree.h"
 #include "util-host-os-info.h"
@@ -1403,12 +1402,6 @@ static void ParseCommandLineAFL(const char *opt_name, char *opt_arg)
         else
             exit(DecoderParseDataFromFileSerie(opt_arg, DecodeERSPAN));
     } else
-#endif
-#ifdef AFLFUZZ_DER
-    if(strcmp(opt_name, "afl-der") == 0) {
-        //printf("arg: //%s\n", opt_arg);
-        exit(DerParseDataFromFile(opt_arg));
-    } else
 #endif
     {
         abort();
diff --git a/src/util-decode-der-get.c b/src/util-decode-der-get.c
deleted file mode 100644 (file)
index 3e90788..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Copyright (C) 2011-2012 ANSSI
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * \file
- *
- * \author Pierre Chifflier <pierre.chifflier@ssi.gouv.fr>
- *
- */
-
-#include "suricata-common.h"
-
-#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 };
-
-static const char *Oid2ShortStr(const char *oid)
-{
-    if (strcmp(oid, "1.2.840.113549.1.9.1") == 0)
-        return "emailAddress";
-
-    if (strcmp(oid, "2.5.4.3") == 0)
-        return "CN";
-
-    if (strcmp(oid, "2.5.4.5") == 0)
-        return "serialNumber";
-
-    if (strcmp(oid, "2.5.4.6") == 0)
-        return "C";
-
-    if (strcmp(oid, "2.5.4.7") == 0)
-        return "L";
-
-    if (strcmp(oid, "2.5.4.8") == 0)
-        return "ST";
-
-    if (strcmp(oid, "2.5.4.10") == 0)
-        return "O";
-
-    if (strcmp(oid, "2.5.4.11") == 0)
-        return "OU";
-
-    if (strcmp(oid, "0.9.2342.19200300.100.1.25") == 0)
-        return "DC";
-
-    return "unknown";
-}
-
-static time_t GentimeToTime(char *gentime)
-{
-    time_t time;
-    struct tm tm;
-
-    /* GeneralizedTime values MUST be expressed in Greenwich Mean Time
-     * (Zulu) and MUST include seconds (rfc5280 4.1.2.5.2). It MUST NOT
-     * include fractional seconds. It should therefore be on the format
-     * YYYYmmddHHMMSSZ. */
-    if (strlen(gentime) != 15)
-        goto error;
-
-    memset(&tm, 0, sizeof(tm));
-    strptime(gentime, "%Y%m%d%H%M%SZ", &tm);
-    time = SCMkTimeUtc(&tm);
-
-    if (time < 0)
-        goto error;
-
-    return time;
-
-error:
-    return -1;
-}
-
-static time_t UtctimeToTime(char *utctime)
-{
-    time_t time;
-    unsigned int year;
-    char yy[3];
-    char buf[20];
-
-    /* UTCTime values MUST be expressed in Greenwich Mean Time (Zulu)
-     * and MUST include seconds (rfc5280 4.1.2.5.1). It should
-     * therefore be on the format YYmmddHHMMSSZ. */
-    if (strlen(utctime) != 13)
-        goto error;
-
-    /* UTCTime use two digits to represent the year. The year field (YY)
-     * should be interpreted as 19YY when it is greater than or equal to
-     * 50. If it is less than 50 it should be interpreted as 20YY.
-     * Because of this, GeneralizedTime must be used for dates in the
-     * year 2050 or later. */
-    strlcpy(yy, utctime, sizeof(yy));
-    year = strtol(yy, NULL, 10);
-    if (year >= 50)
-        snprintf(buf, sizeof(buf), "%i%s", 19, utctime);
-    else
-        snprintf(buf, sizeof(buf), "%i%s", 20, utctime);
-
-    time = GentimeToTime(buf);
-    if (time == -1)
-        goto error;
-
-    return time;
-
-error:
-    return -1;
-}
-
-/**
- * \brief Iterate through an ASN.1 structure, following the index sequence.
- *        Context specific elements are skipped.
- *
- * \retval The matching node, or NULL
- */
-const Asn1Generic * Asn1DerGet(const Asn1Generic *top, const uint8_t *seq_index,
-                               const uint32_t seqsz, uint32_t *errcode)
-{
-    const Asn1Generic * node;
-    uint8_t idx, i;
-    uint8_t offset = 0;
-
-    if (errcode)
-        *errcode = ERR_DER_MISSING_ELEMENT;
-
-    node = top;
-    if (node == NULL || seq_index == NULL)
-        return NULL;
-
-    for (offset=0; offset<seqsz; offset++) {
-
-        idx = seq_index[offset];
-        for (i=0; i<idx; i++) {
-            if (node == NULL || node->data == NULL)
-                return NULL;
-
-            /* skip context-specific elements */
-            while (node->data->header.cls == ASN1_CLASS_CONTEXTSPEC) {
-                node = node->next;
-                if (node == NULL || node->data == NULL)
-                    return NULL;
-            }
-
-            node = node->next;
-            if (node == NULL || node->data == NULL)
-                return NULL;
-        }
-
-        /* skip context-specific elements */
-        if (node == NULL || node->data == NULL)
-            return NULL;
-        while (node->data->header.cls == ASN1_CLASS_CONTEXTSPEC) {
-            node = node->next;
-            if (node == NULL || node->data == NULL)
-                return NULL;
-        }
-
-        node = node->data;
-    }
-
-    if (errcode)
-        *errcode = 0;
-
-    return node;
-}
-
-int Asn1DerGetValidity(const Asn1Generic *cert, time_t *not_before,
-                       time_t *not_after, uint32_t *errcode)
-{
-    const Asn1Generic *node, *it;
-    int rc = -1;
-
-    if (errcode)
-        *errcode = ERR_DER_MISSING_ELEMENT;
-
-    node = Asn1DerGet(cert, SEQ_IDX_VALIDITY, sizeof(SEQ_IDX_VALIDITY), errcode);
-    if ((node == NULL) || node->type != ASN1_SEQUENCE)
-        goto validity_error;
-
-    it = node->data;
-    if (it == NULL || it->str == NULL)
-        goto validity_error;
-
-    if (it->type == ASN1_UTCTIME)
-        *not_before = UtctimeToTime(it->str);
-    else if (it->type == ASN1_GENERALIZEDTIME)
-        *not_before = GentimeToTime(it->str);
-    else
-        goto validity_error;
-
-    if (*not_before == -1)
-        goto validity_error;
-
-    if (node->next == NULL)
-        goto validity_error;
-
-    it = node->next->data;
-
-    if (it == NULL || it->str == NULL)
-        goto validity_error;
-
-    if (it->type == ASN1_UTCTIME)
-        *not_after = UtctimeToTime(it->str);
-    else if (it->type == ASN1_GENERALIZEDTIME)
-        *not_after = GentimeToTime(it->str);
-    else
-        goto validity_error;
-
-    if (*not_after == -1)
-        goto validity_error;
-
-    rc = 0;
-
-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)
-{
-    const Asn1Generic *node_oid;
-    const Asn1Generic *node;
-    const Asn1Generic *it;
-    const Asn1Generic *node_set;
-    const Asn1Generic *node_str;
-    const char *shortname;
-    int rc = -1;
-    const char *separator = ", ";
-
-    if (errcode)
-        *errcode = ERR_DER_MISSING_ELEMENT;
-
-    if (length < 10)
-        goto issuer_dn_error;
-
-    buffer[0] = '\0';
-
-    node = Asn1DerGet(cert, SEQ_IDX_ISSUER, sizeof(SEQ_IDX_ISSUER), errcode);
-    if ((node == NULL) || node->type != ASN1_SEQUENCE)
-        goto issuer_dn_error;
-
-    it = node;
-    while (it != NULL) {
-        if (it->data == NULL)
-            goto issuer_dn_error;
-        node_set = it->data;
-        if (node_set->type != ASN1_SET || node_set->data == NULL)
-            goto issuer_dn_error;
-        node = node_set->data;
-        if (node->type != ASN1_SEQUENCE || node->data == NULL)
-            goto issuer_dn_error;
-        node_oid = node->data;
-        if (node_oid->str == NULL || node_oid->type != ASN1_OID)
-            goto issuer_dn_error;
-        shortname = Oid2ShortStr(node_oid->str);
-        if (node->next == NULL)
-            goto issuer_dn_error;
-        node = node->next;
-        node_str = node->data;
-        if (node_str == NULL || node_str->str == NULL)
-            goto issuer_dn_error;
-
-        switch (node_str->type) {
-            case ASN1_PRINTSTRING:
-            case ASN1_IA5STRING:
-            case ASN1_T61STRING:
-            case ASN1_UTF8STRING:
-            case ASN1_OCTETSTRING:
-                strlcat(buffer, shortname, length);
-                strlcat(buffer, "=", length);
-                strlcat(buffer, node_str->str, length);
-                break;
-            default:
-                if (errcode)
-                    *errcode = ERR_DER_UNSUPPORTED_STRING;
-                goto issuer_dn_error;
-        }
-
-        if (strcmp(shortname,"CN") == 0)
-            separator = "/";
-        if (it->next != NULL)
-            strlcat(buffer, separator, length);
-        it = it->next;
-    }
-
-    if (errcode)
-        *errcode = 0;
-
-    rc = 0;
-issuer_dn_error:
-    return rc;
-}
-
-int Asn1DerGetSubjectDN(const Asn1Generic *cert, char *buffer, uint32_t length,
-                        uint32_t *errcode)
-{
-    const Asn1Generic *node_oid;
-    const Asn1Generic *node;
-    const Asn1Generic *it;
-    const Asn1Generic *node_set;
-    const Asn1Generic *node_str;
-    const char *shortname;
-    int rc = -1;
-    const char *separator = ", ";
-
-    if (errcode)
-        *errcode = ERR_DER_MISSING_ELEMENT;
-
-    if (length < 10)
-        goto subject_dn_error;
-
-    buffer[0] = '\0';
-
-    node = Asn1DerGet(cert, SEQ_IDX_SUBJECT, sizeof(SEQ_IDX_SUBJECT), errcode);
-
-    if ((node == NULL) || node->type != ASN1_SEQUENCE)
-        goto subject_dn_error;
-
-    it = node;
-    while (it != NULL) {
-        if (it == NULL || it->data == NULL)
-            goto subject_dn_error;
-        node_set = it->data;
-        if (node_set->type != ASN1_SET || node_set->data == NULL)
-            goto subject_dn_error;
-        node = node_set->data;
-        if (node->type != ASN1_SEQUENCE || node->data == NULL)
-            goto subject_dn_error;
-        node_oid = node->data;
-        if (node_oid->str == NULL || node_oid->type != ASN1_OID)
-            goto subject_dn_error;
-        shortname = Oid2ShortStr(node_oid->str);
-        if (node->next == NULL)
-            goto subject_dn_error;
-        node = node->next;
-        node_str = node->data;
-        if (node_str == NULL || node_str->str == NULL)
-            goto subject_dn_error;
-
-        switch (node_str->type) {
-            case ASN1_PRINTSTRING:
-            case ASN1_IA5STRING:
-            case ASN1_T61STRING:
-            case ASN1_UTF8STRING:
-            case ASN1_OCTETSTRING:
-                strlcat(buffer, shortname, length);
-                strlcat(buffer, "=", length);
-                strlcat(buffer, node_str->str, length);
-                break;
-            default:
-                if (errcode)
-                    *errcode = ERR_DER_UNSUPPORTED_STRING;
-                goto subject_dn_error;
-        }
-
-        if (strcmp(shortname,"CN") == 0)
-            separator = "/";
-        if (it->next != NULL)
-            strlcat(buffer, separator, length);
-        it = it->next;
-    }
-
-    if (errcode)
-        *errcode = 0;
-
-    rc = 0;
-subject_dn_error:
-    return rc;
-}
-
diff --git a/src/util-decode-der-get.h b/src/util-decode-der-get.h
deleted file mode 100644 (file)
index bed1cfe..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2011-2012 ANSSI
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * \file
- *
- * \author Pierre Chifflier <pierre.chifflier@ssi.gouv.fr>
- *
- */
-
-#ifndef __UTIL_DECODE_DER_GET_H__
-#define __UTIL_DECODE_DER_GET_H__
-
-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);
-
-#endif /* __UTIL_DECODE_DER_GET_H__ */
diff --git a/src/util-decode-der.c b/src/util-decode-der.c
deleted file mode 100644 (file)
index dbde764..0000000
+++ /dev/null
@@ -1,1081 +0,0 @@
-/*
- * Copyright (C) 2011-2015 ANSSI
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * \file
- *
- * \author Pierre Chifflier <pierre.chifflier@ssi.gouv.fr>
- *
- */
-
-/*
- * An ASN.1 Parser for DER-encoded structures.
- * This parser is not written to be complete or fast, but is rather
- * focused on stability and security.
- * It does not support all ASN.1 structure, only a meaningful subset
- * to decode x509v3 certificates (See RFC 3280).
- *
- * References (like 8.19.4) are relative to the ISO/IEC 8825-1:2003 document
- *
- */
-
-#include "suricata-common.h"
-#include "util-decode-der.h"
-#include "util-validate.h"
-
-#define MAX_OID_LENGTH 256
-
-static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer,
-                                            uint32_t size, uint8_t depth,
-                                            uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer,
-                                          uint32_t size, uint8_t depth,
-                                          uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer,
-                                            uint32_t size, uint8_t depth,
-                                            uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer,
-                                          uint32_t size, uint8_t depth,
-                                          uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer,
-                                       uint32_t size, uint8_t depth,
-                                       uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer,
-                                              uint32_t size, uint8_t depth,
-                                              uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer,
-                                             uint32_t max_size, uint8_t depth,
-                                             uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer,
-                                      uint32_t size, uint8_t depth,
-                                      uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer,
-                                                  uint32_t size, uint8_t depth,
-                                                  uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer,
-                                           uint32_t size, uint8_t depth,
-                                           uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer,
-                                      uint32_t size, uint8_t depth,
-                                      uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer,
-                                            uint32_t size, uint8_t depth,
-                                            uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer,
-                                          uint32_t size, uint8_t depth,
-                                          uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerGeneralizedTime(const unsigned char *buffer,
-                                                  uint32_t size, uint8_t depth,
-                                                  uint32_t *errcode) __attribute__((nonnull));
-static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer,
-                                          uint32_t max_size, uint8_t depth,
-                                          int seq_index, uint32_t *errcode) __attribute__((nonnull));
-
-static Asn1Generic * Asn1GenericNew(void)
-{
-    Asn1Generic *obj;
-
-    obj = SCMalloc(sizeof(Asn1Generic));
-    if (obj != NULL)
-        memset(obj, 0, sizeof(Asn1Generic));
-
-    return obj;
-}
-
-/**
- * \retval r 0 ok, -1 error
- */
-static int Asn1SequenceAppend(Asn1Generic *seq, Asn1Generic *node)
-{
-    Asn1Generic *it, *new_container;
-
-    if (seq->data == NULL) {
-        seq->data = node;
-        return 0;
-    }
-
-    new_container = Asn1GenericNew();
-    if (new_container == NULL)
-        return -1;
-    new_container->data = node;
-
-    for (it=seq; it->next != NULL; it=it->next)
-        ;
-
-    it->next = new_container;
-    return 0;
-}
-
-/* openssl has set a limit of 30, so stay close to that. */
-#define DER_MAX_RECURSION_DEPTH 32
-
-static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer,
-                                          uint32_t max_size, uint8_t depth,
-                                          int seq_index, uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint32_t numbytes, el_max_size;
-    Asn1ElementType el;
-    uint8_t c;
-    uint32_t i;
-    Asn1Generic *child;
-    uint8_t el_type;
-
-    /* refuse excessive recursion */
-    if (unlikely(depth >= DER_MAX_RECURSION_DEPTH)) {
-        *errcode = ERR_DER_RECURSION_LIMIT;
-        return NULL;
-    }
-    if (max_size < 2) {
-        *errcode = ERR_DER_INVALID_SIZE;
-        return NULL;
-    }
-
-    el.cls = (d_ptr[0] & 0xc0) >> 6;
-    el.pc = (d_ptr[0] & 0x20) >> 5;
-    el.tag = (d_ptr[0] & 0x1f);
-
-    el_type = el.tag;
-
-    if (el.tag == 0x1f) {
-        *errcode = ERR_DER_INVALID_TAG;
-        return NULL;
-    }
-
-    switch (el.cls) {
-        case ASN1_CLASS_CONTEXTSPEC:
-            /* get element type from definition, see:
-               http://www.ietf.org/rfc/rfc3280.txt */
-            if (depth == 2 && el.tag == 0) {
-                /* TBSCertificate */
-                el_type = ASN1_SEQUENCE;
-                break;
-            }
-            if (depth == 2 && el.tag == 1) {
-                /* issuerUniqueID */
-                el_type = ASN1_BITSTRING;
-                break;
-            }
-            if (depth == 2 && el.tag == 2) {
-                /* subjectUniqueID */
-                el_type = ASN1_BITSTRING;
-                break;
-            }
-            if (depth == 2 && el.tag == 3) {
-                /* extensions */
-                el_type = ASN1_SEQUENCE;
-                break;
-            }
-            /* unknown context specific value - do not decode */
-            break;
-    };
-
-    el_max_size = max_size - (d_ptr-buffer);
-    switch (el_type) {
-        case ASN1_INTEGER:
-            child = DecodeAsn1DerInteger(d_ptr, el_max_size, depth+1, errcode);
-            break;
-        case ASN1_BOOLEAN:
-            child = DecodeAsn1DerBoolean(d_ptr, el_max_size, depth+1, errcode);
-            break;
-        case ASN1_NULL:
-            child = DecodeAsn1DerNull(d_ptr, el_max_size, depth+1, errcode);
-            break;
-        case ASN1_BITSTRING:
-            child = DecodeAsn1DerBitstring(d_ptr, el_max_size, depth+1,
-                                           errcode);
-            break;
-        case ASN1_OID:
-            child = DecodeAsn1DerOid(d_ptr, el_max_size, depth+1, errcode);
-            break;
-        case ASN1_IA5STRING:
-            child = DecodeAsn1DerIA5String(d_ptr, el_max_size, depth+1,
-                                           errcode);
-            break;
-        case ASN1_OCTETSTRING:
-            child = DecodeAsn1DerOctetString(d_ptr, el_max_size, depth+1,
-                                             errcode);
-            break;
-        case ASN1_UTF8STRING:
-            child = DecodeAsn1DerUTF8String(d_ptr, el_max_size, depth+1,
-                                            errcode);
-            break;
-        case ASN1_PRINTSTRING:
-            child = DecodeAsn1DerPrintableString(d_ptr, el_max_size, depth+1,
-                                                 errcode);
-            break;
-        case ASN1_SEQUENCE:
-            child = DecodeAsn1DerSequence(d_ptr, el_max_size, depth+1, errcode);
-            break;
-        case ASN1_SET:
-            child = DecodeAsn1DerSet(d_ptr, el_max_size, depth+1, errcode);
-            break;
-        case ASN1_T61STRING:
-            child = DecodeAsn1DerT61String(d_ptr, el_max_size, depth+1,
-                                           errcode);
-            break;
-        case ASN1_UTCTIME:
-            child = DecodeAsn1DerUTCTime(d_ptr, el_max_size, depth+1, errcode);
-            break;
-        case ASN1_GENERALIZEDTIME:
-            child = DecodeAsn1DerGeneralizedTime(d_ptr, el_max_size, depth+1, errcode);
-            break;
-        default:
-            /* unknown ASN.1 type */
-            child = NULL;
-            child = Asn1GenericNew();
-            if (child == NULL)
-                break;
-
-            child->type = el.tag;
-
-            /* total sequence length */
-            const unsigned char * save_d_ptr = d_ptr;
-            d_ptr++;
-            el_max_size--;
-            c = d_ptr[0];
-
-            /* short form 8.1.3.4 */
-            if ((c & (1<<7))>>7 == 0) {
-                child->length = c;
-                d_ptr++;
-            /* long form 8.1.3.5 */
-            } else {
-                numbytes = c & 0x7f;
-                if (2 + numbytes > el_max_size) {
-                    SCFree(child);
-                    *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
-                    return NULL;
-                }
-                child->length = 0;
-                d_ptr++;
-                for (i=0; i<numbytes; i++) {
-                    child->length = child->length<<8 | d_ptr[0];
-                    d_ptr++;
-                }
-            }
-
-            /* fix the length for unknown objects, else sequence parsing
-               will fail */
-            child->length += (d_ptr - save_d_ptr);
-
-            if (child->length > max_size - (d_ptr - buffer)) {
-                *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
-                SCFree(child);
-                return NULL;
-            }
-
-            break;
-    };
-
-    if (child == NULL) {
-        if (*errcode == 0)
-            *errcode = ERR_DER_INVALID_OBJECT;
-        return NULL;
-    }
-
-    /* child length should never be zero */
-    if (child->length == 0) {
-        *errcode = ERR_DER_INVALID_OBJECT;
-        SCFree(child);
-        return NULL;
-    }
-
-    child->header = el;
-    return child;
-}
-
-static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer,
-                                          uint32_t size, uint8_t depth,
-                                          uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint8_t numbytes;
-    uint32_t value;
-    uint32_t i;
-    Asn1Generic *a;
-
-    numbytes = d_ptr[1];
-
-    if ((uint32_t)(numbytes + 2) > size) {
-        *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
-        return NULL;
-    }
-
-    d_ptr += 2;
-
-    value = 0;
-
-    /* Here we need to ensure that numbytes is less than 4
-       so integer affectation is possible. We set the value
-       to 0xffffffff which is by convention the unknown value.
-       In this case, the hexadecimal value must be used. */
-    if (numbytes > 4) {
-        value = 0xffffffff;
-    } else {
-        for (i=0; i<numbytes; i++) {
-            value = value<<8 | d_ptr[i];
-        }
-    }
-
-    a = Asn1GenericNew();
-    if (a == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        return NULL;
-    }
-
-    a->type = ASN1_INTEGER;
-    a->length = (d_ptr - buffer) + numbytes;
-    a->value = value;
-
-    a->str = SCMalloc(2*numbytes + 1);
-    if (a->str == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        SCFree(a);
-        return NULL;
-    }
-
-    for (i=0; i<numbytes; i++) {
-        snprintf(a->str + 2*i, 2*(numbytes-i)+1, "%02X", d_ptr[i]);
-    }
-    a->str[2*numbytes]= '\0';
-
-    return a;
-}
-
-static int DecodeAsn1BuildValue(const unsigned char **d_ptr, uint32_t *val,
-                                uint8_t numbytes, uint32_t *errcode)
-{
-    int i;
-    uint32_t value = 0;
-
-    if (numbytes > 4) {
-        *errcode = ERR_DER_INVALID_SIZE;
-
-        /* too big won't fit: set it to 0xffffffff by convention */
-        value = 0xffffffff;
-        *val = value;
-        return -1;
-    } else {
-        for (i=0; i<numbytes; i++) {
-            value = value<<8 | (*d_ptr)[0];
-            (*d_ptr)++;
-        }
-    }
-
-    *val = value;
-    return 0;
-}
-
-static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer,
-                                          uint32_t size, uint8_t depth,
-                                          uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint8_t numbytes;
-    uint32_t value;
-    Asn1Generic *a;
-
-    numbytes = d_ptr[1];
-    if ((uint32_t)(numbytes + 2) > size) {
-        *errcode = ERR_DER_INVALID_SIZE;
-        return NULL;
-    }
-    d_ptr += 2;
-
-    if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes, errcode) == -1) {
-        return NULL;
-    }
-
-    a = Asn1GenericNew();
-    if (a == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        return NULL;
-    }
-
-    a->type = ASN1_BOOLEAN;
-    a->length = (d_ptr - buffer);
-    a->value = value;
-
-    return a;
-}
-
-static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer,
-                                       uint32_t size, uint8_t depth,
-                                       uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint8_t numbytes;
-    uint32_t value;
-    Asn1Generic *a;
-
-    numbytes = d_ptr[1];
-    if ((uint32_t)(numbytes + 2) > size) {
-        *errcode = ERR_DER_INVALID_SIZE;
-        return NULL;
-    }
-    d_ptr += 2;
-
-    if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes, errcode) == -1) {
-        return NULL;
-    }
-
-    a = Asn1GenericNew();
-    if (a == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        return NULL;
-    }
-
-    a->type = ASN1_NULL;
-    a->length = (d_ptr - buffer);
-    a->value = 0;
-
-    return a;
-}
-
-static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer,
-                                            uint32_t max_size, uint8_t depth,
-                                            uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint32_t length;
-    uint8_t numbytes, c;
-    Asn1Generic *a;
-
-    d_ptr++;
-
-    /* size */
-    c = d_ptr[0];
-    /* short form 8.1.3.4 */
-    if ((c & (1<<7))>>7 == 0) {
-        length = c;
-        d_ptr++;
-    /* long form 8.1.3.5 */
-    } else {
-        numbytes = c & 0x7f;
-        if ((uint32_t)(numbytes + 2) > max_size) {
-            *errcode = ERR_DER_INVALID_SIZE;
-            return NULL;
-        }
-        d_ptr++;
-        if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
-            return NULL;
-        }
-    }
-
-    if ((d_ptr-buffer) + length > max_size) {
-        *errcode = ERR_DER_INVALID_SIZE;
-        return NULL;
-    }
-
-    a = Asn1GenericNew();
-    if (a == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        return NULL;
-    }
-
-    a->type = ASN1_BITSTRING;
-    a->strlen = length;
-
-    a->str = SCMalloc(length);
-    if (a->str == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        SCFree(a);
-        return NULL;
-    }
-    memcpy(a->str, (const char*)d_ptr, length);
-
-    d_ptr += length;
-
-    a->length = (d_ptr - buffer);
-    return a;
-}
-
-static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer,
-                                      uint32_t max_size, uint8_t depth,
-                                      uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint32_t oid_length, oid_value;
-    uint8_t numbytes, c;
-    Asn1Generic *a;
-    uint32_t i;
-
-    d_ptr++;
-
-    /* size */
-    c = d_ptr[0];
-    /* short form 8.1.3.4 */
-    if ((c & (1<<7))>>7 == 0) {
-        oid_length = c;
-        d_ptr++;
-    /* long form 8.1.3.5 */
-    } else {
-        numbytes = c & 0x7f;
-        if ((uint32_t)(numbytes + 2) > max_size) {
-            *errcode = ERR_DER_INVALID_SIZE;
-            return NULL;
-        }
-        d_ptr++;
-        if (DecodeAsn1BuildValue(&d_ptr, &oid_length, numbytes, errcode) == -1) {
-            return NULL;
-        }
-    }
-
-    if (oid_length == 0 || (d_ptr-buffer) + oid_length > max_size) {
-        *errcode = ERR_DER_INVALID_SIZE;
-        return NULL;
-    }
-
-    a = Asn1GenericNew();
-    if (a == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        return NULL;
-    }
-
-    a->type = ASN1_OID;
-
-    a->str = SCMalloc(MAX_OID_LENGTH);
-    if (a->str == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        SCFree(a);
-        return NULL;
-    }
-
-    /* first element = X*40 + Y (See 8.19.4) */
-    snprintf(a->str, MAX_OID_LENGTH, "%d.%d", (d_ptr[0]/40), (d_ptr[0]%40));
-    d_ptr++;
-
-    if (oid_length + (d_ptr-buffer) > max_size) {
-        *errcode = ERR_DER_INVALID_SIZE;
-        SCFree(a->str);
-        SCFree(a);
-        return NULL;
-    }
-
-    /* sub-identifiers are multi-valued, coded and 7 bits, first bit of
-       the 8bits is used to indicate, if a new value is starting */
-    for (i=1; i<oid_length; ) {
-        int s = strlen(a->str);
-        c = d_ptr[0];
-        oid_value = 0;
-        while ( i<oid_length && (c & (1<<7)) == 1<<7 ) {
-            oid_value = oid_value<<7 | (c & ~(1<<7));
-            d_ptr++;
-            c = d_ptr[0];
-            i++;
-        }
-        oid_value = oid_value<<7 | c;
-        d_ptr++;
-        i++;
-        snprintf(a->str + s, MAX_OID_LENGTH - s, ".%d", oid_value);
-    }
-
-    a->length = (d_ptr - buffer);
-    return a;
-}
-
-static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer,
-                                            uint32_t max_size, uint8_t depth,
-                                            uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint32_t length, numbytes;
-    Asn1Generic *a;
-    unsigned char c;
-
-    d_ptr++;
-    max_size--;
-
-    /* total sequence length */
-    c = d_ptr[0];
-    /* short form 8.1.3.4 */
-    if ((c & (1<<7))>>7 == 0) {
-        length = c;
-        d_ptr++;
-        max_size--;
-    /* long form 8.1.3.5 */
-    } else {
-        numbytes = c & 0x7f;
-        if (max_size < 1 + numbytes) {
-            *errcode = ERR_DER_INVALID_SIZE;
-            return NULL;
-        }
-        max_size -= 1 + numbytes;
-        d_ptr++;
-        if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
-            return NULL;
-        }
-    }
-
-    if (length == UINT32_MAX || (d_ptr-buffer) + length > max_size) {
-        *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
-        return NULL;
-    }
-
-    a = Asn1GenericNew();
-    if (a == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        return NULL;
-    }
-
-    a->type = ASN1_IA5STRING;
-    a->strlen = length;
-
-    a->str = SCMalloc(length+1);
-    if (a->str == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        SCFree(a);
-        return NULL;
-    }
-    memcpy(a->str, (const char*)d_ptr, length);
-    a->str[length] = 0;
-
-    d_ptr += length;
-
-    a->length = (d_ptr - buffer);
-    return a;
-}
-
-static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer,
-                                              uint32_t max_size, uint8_t depth,
-                                              uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint32_t length, numbytes;
-    Asn1Generic *a;
-    unsigned char c;
-
-    d_ptr++;
-    max_size--;
-
-    /* total sequence length */
-    c = d_ptr[0];
-    /* short form 8.1.3.4 */
-    if ((c & (1<<7))>>7 == 0) {
-        length = c;
-        d_ptr++;
-        max_size--;
-    /* long form 8.1.3.5 */
-    } else {
-        numbytes = c & 0x7f;
-        if (max_size < 1 + numbytes) {
-            *errcode = ERR_DER_INVALID_SIZE;
-            return NULL;
-        }
-        max_size -= 1 + numbytes;
-        d_ptr++;
-        if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
-            return NULL;
-        }
-    }
-
-    if (length == UINT32_MAX || (d_ptr-buffer) + length > max_size) {
-        *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
-        return NULL;
-    }
-    a = Asn1GenericNew();
-    if (a == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        return NULL;
-    }
-
-    a->type = ASN1_OCTETSTRING;
-    a->strlen = length;
-
-    /* add one to the octet string for the 0. This will then allow us to
-       use the string in printf */
-    a->str = SCMalloc(length + 1);
-    if (a->str == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        SCFree(a);
-        return NULL;
-    }
-    memcpy(a->str, (const char*)d_ptr, length);
-    a->str[length] = 0;
-
-    d_ptr += length;
-
-    a->length = (d_ptr - buffer);
-    return a;
-}
-
-static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer,
-                                             uint32_t max_size, uint8_t depth,
-                                             uint32_t *errcode)
-{
-    Asn1Generic *a = DecodeAsn1DerOctetString(buffer, max_size, depth, errcode);
-    if (a != NULL)
-        a->type = ASN1_UTF8STRING;
-
-    return a;
-}
-
-static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer,
-                                                  uint32_t max_size,
-                                                  uint8_t depth,
-                                                  uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint32_t length, numbytes;
-    Asn1Generic *a;
-    unsigned char c;
-
-    d_ptr++;
-
-    /* total sequence length */
-    c = d_ptr[0];
-    /* short form 8.1.3.4 */
-    if ((c & (1<<7))>>7 == 0) {
-        length = c;
-        d_ptr++;
-    /* long form 8.1.3.5 */
-    } else {
-        numbytes = c & 0x7f;
-        d_ptr++;
-        if (2 + numbytes > max_size) {
-            *errcode = ERR_DER_INVALID_SIZE;
-            return NULL;
-        }
-        if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
-            return NULL;
-        }
-    }
-
-    if (length == UINT32_MAX || (d_ptr-buffer) + length > max_size) {
-        *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
-        return NULL;
-    }
-
-    a = Asn1GenericNew();
-    if (a == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        return NULL;
-    }
-
-    a->type = ASN1_PRINTSTRING;
-    a->strlen = length;
-
-    a->str = SCMalloc(length+1);
-    if (a->str == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        SCFree(a);
-        return NULL;
-    }
-    memcpy(a->str, (const char*)d_ptr, length);
-    a->str[length] = 0;
-
-    d_ptr += length;
-
-    a->length = (d_ptr - buffer);
-    return a;
-}
-
-static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer,
-                                           uint32_t max_size, uint8_t depth,
-                                           uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint32_t d_length, parsed_bytes, numbytes, el_max_size;
-    uint8_t c;
-    uint32_t seq_index;
-    Asn1Generic *node;
-
-    d_ptr++;
-
-    node = Asn1GenericNew();
-    if (node == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        return NULL;
-    }
-
-    node->type = ASN1_SEQUENCE;
-
-    /* total sequence length */
-    c = d_ptr[0];
-    /* short form 8.1.3.4 */
-    if ((c & (1<<7))>>7 == 0) {
-        d_length = c;
-        d_ptr++;
-    /* long form 8.1.3.5 */
-    } else {
-        numbytes = c & 0x7f;
-        d_ptr++;
-        if ( 2 + numbytes > max_size ) {
-            *errcode = ERR_DER_INVALID_SIZE;
-            SCFree(node);
-            return NULL;
-        }
-        if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
-            SCFree(node);
-            return NULL;
-        }
-    }
-    node->length = d_length + (d_ptr - buffer);
-    if (node->length > max_size || node->length < d_length /* wrap */) {
-        *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
-        SCFree(node);
-        return NULL;
-    }
-
-    parsed_bytes = 0;
-    seq_index = 0;
-
-    /* decode child elements */
-    while (parsed_bytes < d_length) {
-        el_max_size = max_size - (d_ptr-buffer);
-
-        Asn1Generic *child = DecodeAsn1DerGeneric(d_ptr,
-                MIN(node->length, el_max_size), depth,
-                seq_index, errcode);
-        if (child == NULL) {
-            if (*errcode != 0) {
-                DerFree(node);
-                return NULL;
-            }
-            break;
-        }
-
-        int ret = Asn1SequenceAppend(node, child);
-        if (ret == -1) {
-            DerFree(child);
-            break;
-        }
-
-        parsed_bytes += child->length;
-        d_ptr += child->length;
-        seq_index++;
-    }
-
-    return (Asn1Generic *)node;
-}
-
-static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer,
-                                      uint32_t max_size, uint8_t depth,
-                                      uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint32_t d_length, numbytes, el_max_size;
-    uint8_t c;
-    uint32_t seq_index;
-    Asn1Generic *node;
-    Asn1Generic *child;
-
-    d_ptr++;
-
-    node = Asn1GenericNew();
-    if (node == NULL) {
-        *errcode = ERR_DER_GENERIC;
-        return NULL;
-    }
-    node->type = ASN1_SET;
-    node->data = NULL;
-
-    /* total sequence length */
-    c = d_ptr[0];
-    /* short form 8.1.3.4 */
-    if ((c & (1<<7))>>7 == 0) {
-        d_length = c;
-        d_ptr++;
-    /* long form 8.1.3.5 */
-    } else {
-        numbytes = c & 0x7f;
-        if (2 + numbytes > max_size) {
-            *errcode = ERR_DER_INVALID_SIZE;
-            SCFree(node);
-            return NULL;
-        }
-        d_ptr++;
-        if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
-            SCFree(node);
-            return NULL;
-        }
-    }
-
-    node->length = d_length + (d_ptr - buffer);
-
-    if (node->length > max_size || node->length < d_length /* wrap */) {
-        *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
-        SCFree(node);
-        return NULL;
-    }
-
-    seq_index = 0;
-
-    el_max_size = max_size - (d_ptr-buffer);
-
-    child = DecodeAsn1DerGeneric(d_ptr, MIN(node->length, el_max_size),
-            depth, seq_index, errcode);
-    if (child == NULL) {
-        DerFree(node);
-        return NULL;
-    }
-
-    node->data = child;
-
-    return (Asn1Generic *)node;
-}
-
-static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer,
-                                            uint32_t max_size, uint8_t depth,
-                                            uint32_t *errcode)
-{
-    Asn1Generic *a;
-
-    a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
-    if (a != NULL)
-        a->type = ASN1_T61STRING;
-
-    return a;
-}
-
-static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer,
-                                          uint32_t max_size, uint8_t depth,
-                                          uint32_t *errcode)
-{
-    Asn1Generic *a;
-
-    a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
-    if (a != NULL)
-        a->type = ASN1_UTCTIME;
-
-    return a;
-}
-
-static Asn1Generic * DecodeAsn1DerGeneralizedTime(const unsigned char *buffer,
-                                                  uint32_t max_size,
-                                                  uint8_t depth,
-                                                  uint32_t *errcode)
-{
-    Asn1Generic *a;
-
-    a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
-    if (a != NULL)
-        a->type = ASN1_GENERALIZEDTIME;
-
-    return a;
-}
-
-/**
- *  \param errcode pointer to error code variable. May not be NULL.
- */
-Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size,
-                        uint32_t *errcode)
-{
-    const unsigned char *d_ptr = buffer;
-    uint32_t d_length, numbytes;
-    Asn1Generic *cert;
-    uint8_t c;
-
-    DEBUG_VALIDATE_BUG_ON(errcode == NULL);
-    *errcode = 0;
-
-    if (size < 2) {
-        *errcode = ERR_DER_INVALID_SIZE;
-        return NULL;
-    }
-
-    /* check that buffer is an ASN.1 structure (basic checks) */
-    if (d_ptr[0] != 0x30 && d_ptr[1] != 0x82) { /* Sequence */
-        *errcode = ERR_DER_UNKNOWN_ELEMENT;
-        return NULL;
-    }
-
-    c = d_ptr[1];
-    if ((c & (1<<7))>>7 != 1) {
-        *errcode = ERR_DER_INVALID_SIZE;
-        return NULL;
-    }
-
-    numbytes = c & 0x7f;
-    d_ptr += 2;
-    if (size < numbytes + 2) {
-        *errcode = ERR_DER_INVALID_SIZE;
-        return NULL;
-    }
-    if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
-        return NULL;
-    }
-
-    if (d_length+(d_ptr-buffer) != size) {
-        *errcode = ERR_DER_INVALID_SIZE;
-        return NULL;
-    }
-
-    cert = DecodeAsn1DerGeneric(buffer, size, 0 /* depth */, 0, errcode);
-
-    return cert;
-}
-
-#ifdef AFLFUZZ_DER
-int DerParseDataFromFile(char *filename)
-{
-    uint8_t buffer[65536];
-    uint32_t errcode = 0;
-
-#ifdef AFLFUZZ_PERSISTANT_MODE
-    while (__AFL_LOOP(1000)) {
-        /* reset state */
-        memset(buffer, 0, sizeof(buffer));
-#endif /* AFLFUZZ_PERSISTANT_MODE */
-
-        FILE *fp = fopen(filename, "r");
-        BUG_ON(fp == NULL);
-
-        size_t result = fread(&buffer, 1, sizeof(buffer), fp);
-        Asn1Generic *a = DecodeDer(buffer, result, &errcode);
-        DerFree(a);
-        fclose(fp);
-
-#ifdef AFLFUZZ_PERSISTANT_MODE
-    }
-#endif /* AFLFUZZ_PERSISTANT_MODE */
-
-    return 0;
-}
-#endif /* AFLFUZZ_DER */
-
-void DerFree(Asn1Generic *a)
-{
-    Asn1Generic *it, *n;
-
-    if (a == NULL)
-        return;
-
-    it = a;
-    while (it) {
-        n = it->next;
-        if (it->data) {
-            DerFree(it->data);
-        }
-        if (it->str)
-            SCFree(it->str);
-        memset(it, 0xff, sizeof(Asn1Generic));
-        SCFree(it);
-        it = n;
-    }
-}
diff --git a/src/util-decode-der.h b/src/util-decode-der.h
deleted file mode 100644 (file)
index 5110a4e..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2011-2012 ANSSI
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * \file
- *
- * \author Pierre Chifflier <pierre.chifflier@ssi.gouv.fr>
- *
- */
-
-#ifndef __UTIL_DECODE_DER_H__
-#define __UTIL_DECODE_DER_H__
-
-#define ASN1_CLASS_UNIVERSAL   0
-#define ASN1_CLASS_APPLICATION 1
-#define ASN1_CLASS_CONTEXTSPEC 2
-#define ASN1_CLASS_PRIVATE     3
-
-#define ASN1_UNKNOWN            0
-#define ASN1_BOOLEAN         0x01
-#define ASN1_INTEGER         0x02
-#define ASN1_BITSTRING       0x03
-#define ASN1_OCTETSTRING     0x04
-#define ASN1_NULL            0x05
-#define ASN1_OID             0x06
-#define ASN1_UTF8STRING      0x0c
-#define ASN1_SEQUENCE        0x10
-#define ASN1_SET             0x11
-#define ASN1_PRINTSTRING     0x13
-#define ASN1_T61STRING       0x14
-#define ASN1_IA5STRING       0x16
-#define ASN1_UTCTIME         0x17
-#define ASN1_GENERALIZEDTIME 0x18
-
-typedef struct Asn1ElementType_ {
-       uint8_t cls:2;
-       uint8_t pc:1;
-       uint8_t tag:5;
-} __attribute__((packed)) Asn1ElementType;
-
-/* Generic ASN.1 element
- * Presence and meaning of fields depends on the header and type values.
- */
-typedef struct Asn1Generic_ {
-       Asn1ElementType header;
-       uint8_t type;
-       uint32_t length; /* length of node, including header */
-
-       struct Asn1Generic_ *data; /* only if type is structured */
-
-       char *str;
-       uint32_t strlen;
-       uint64_t value;
-       struct Asn1Generic_ *next; /* only if type is sequence */
-} Asn1Generic;
-
-/* Generic error (failed allocation, etc.) */
-#define ERR_DER_GENERIC               0x01
-/* Unknown ASN.1 element type */
-#define ERR_DER_UNKNOWN_ELEMENT       0x02
-/* One element requires to read more bytes than available */
-#define ERR_DER_ELEMENT_SIZE_TOO_BIG  0x03
-/* One element size is invalid (e.g more than 4 bytes long) */
-#define ERR_DER_INVALID_SIZE          0x04
-/* Unsupported string type */
-#define ERR_DER_UNSUPPORTED_STRING    0x05
-/* Missing field or element */
-#define ERR_DER_MISSING_ELEMENT       0x06
-/* Generic error */
-#define ERR_DER_RECURSION_LIMIT       0x07
-/* Unexpected or unknown tag */
-#define ERR_DER_INVALID_TAG           0x08
-/* Invalid element: empty object, etc. */
-#define ERR_DER_INVALID_OBJECT        0x09
-
-Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size, uint32_t *errcode) __attribute__((nonnull));
-void DerFree(Asn1Generic *a);
-
-#ifdef AFLFUZZ_DER
-int DerParseDataFromFile(char *filename);
-#endif
-
-#endif /* __UTIL_DECODE_DER_H__ */