/*
 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL licenses, (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * https://www.openssl.org/source/license.html
 * or in the file LICENSE in the source distribution.
 */

/* Regression tests for ASN.1 parsing bugs. */

#include <stdio.h>
#include <string.h>

#include "testutil.h"

#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "e_os.h"

static const ASN1_ITEM *item_type;
static const char *test_file;

typedef enum {
    ASN1_UNKNOWN,
    ASN1_OK,
    ASN1_BIO,
    ASN1_DECODE,
    ASN1_ENCODE,
    ASN1_COMPARE
} expected_error_t;

typedef struct {
    const char *str;
    expected_error_t code;
} error_enum;

static expected_error_t expected_error = ASN1_UNKNOWN;

typedef struct d2i_test_fixture {
    const char *test_case_name;
} D2I_TEST_FIXTURE;

static D2I_TEST_FIXTURE set_up(const char *const test_case_name)
{
    D2I_TEST_FIXTURE fixture;
    fixture.test_case_name = test_case_name;
    return fixture;
}

static int execute_test(D2I_TEST_FIXTURE fixture)
{
    BIO *bio = NULL;
    ASN1_VALUE *value = NULL;
    int ret = 0;
    unsigned char buf[2048];
    const unsigned char *buf_ptr = buf;
    unsigned char *der = NULL;
    int derlen;
    int len;

    if ((bio = BIO_new_file(test_file, "r")) == NULL)
        return 0;

    if (expected_error == ASN1_BIO) {
        value = ASN1_item_d2i_bio(item_type, bio, NULL);
        if (value == NULL)
            ret = 1;
        goto err;
    }

    /*
     * Unless we are testing it we don't use ASN1_item_d2i_bio because it
     * performs sanity checks on the input and can reject it before the
     * decoder is called.
     */
    len = BIO_read(bio, buf, sizeof buf);
    if (len < 0)
        goto err;

    value = ASN1_item_d2i(NULL, &buf_ptr, len, item_type);
    if (value == NULL) {
        if (expected_error == ASN1_DECODE)
            ret = 1;
        goto err;
    }

    derlen = ASN1_item_i2d(value, &der, item_type);

    if (der == NULL || derlen < 0) {
        if (expected_error == ASN1_ENCODE)
            ret = 1;
        goto err;
    }

    if (derlen != len || memcmp(der, buf, derlen) != 0) {
        if (expected_error == ASN1_COMPARE)
            ret = 1;
        goto err;
    }

    if (expected_error == ASN1_OK)
        ret = 1;

 err:
    /* Don't indicate success for memory allocation errors */
    if (ret == 1 && ERR_GET_REASON(ERR_peek_error()) == ERR_R_MALLOC_FAILURE)
        ret = 0;
    BIO_free(bio);
    OPENSSL_free(der);
    ASN1_item_free(value, item_type);
    return ret;
}

static void tear_down(D2I_TEST_FIXTURE fixture)
{
    ERR_print_errors_fp(stderr);
}

#define SETUP_D2I_TEST_FIXTURE() \
    SETUP_TEST_FIXTURE(D2I_TEST_FIXTURE, set_up)

#define EXECUTE_D2I_TEST() \
    EXECUTE_TEST(execute_test, tear_down)

static int test_bad_asn1()
{
    SETUP_D2I_TEST_FIXTURE();
    EXECUTE_D2I_TEST();
}

/*
 * Usage: d2i_test <type> <file>, e.g.
 * d2i_test generalname bad_generalname.der
 */
int main(int argc, char **argv)
{
    int result = 0;
    const char *test_type_name;
    const char *expected_error_string;

    size_t i;
    static ASN1_ITEM_EXP *items[] = {
        ASN1_ITEM_ref(ASN1_ANY),
        ASN1_ITEM_ref(X509),
        ASN1_ITEM_ref(GENERAL_NAME),
        ASN1_ITEM_ref(ASN1_INTEGER)
    };

    static error_enum expected_errors[] = {
        {"OK", ASN1_OK},
        {"BIO", ASN1_BIO},
        {"decode", ASN1_DECODE},
        {"encode", ASN1_ENCODE},
        {"compare", ASN1_COMPARE}
    };

    if (argc != 4) {
        fprintf(stderr,
                "Usage: d2i_test item_name expected_error file.der\n");
        return 1;
    }

    test_type_name = argv[1];
    expected_error_string = argv[2];
    test_file = argv[3];

    for (i = 0; i < OSSL_NELEM(items); i++) {
        const ASN1_ITEM *it = ASN1_ITEM_ptr(items[i]);
        if (strcmp(test_type_name, it->sname) == 0) {
            item_type = it;
            break;
        }
    }
    if (item_type == NULL) {
        fprintf(stderr, "Unknown type %s\n", test_type_name);
        fprintf(stderr, "Supported types:\n");
        for (i = 0; i < OSSL_NELEM(items); i++) {
            const ASN1_ITEM *it = ASN1_ITEM_ptr(items[i]);
            fprintf(stderr, "\t%s\n", it->sname);
        }
        return 1;
    }

    for (i = 0; i < OSSL_NELEM(expected_errors); i++) {
        if (strcmp(expected_errors[i].str, expected_error_string) == 0) {
            expected_error = expected_errors[i].code;
            break;
        }
    }

    if (expected_error == ASN1_UNKNOWN) {
        fprintf(stderr, "Unknown expected error %s\n", expected_error_string);
        return 1;
    }

    ADD_TEST(test_bad_asn1);

    result = run_tests(argv[0]);

    return result;
}
