ct_test.c 19.3 KB
Newer Older
1
/*
2
 * Tests the Certificate Transparency public API.
3
 *
R
Rob Percival 已提交
4
 * Author:      Rob Percival (robpercival@google.com)
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
 *
 * ====================================================================
 * Copyright (c) 2016 The OpenSSL Project.    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. All advertising materials mentioning features or use of this
 *        software must display the following acknowledgment:
 *        "This product includes software developed by the OpenSSL Project
 *        for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *        endorse or promote products derived from this software without
 *        prior written permission. For written permission, please contact
 *        licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *        nor may "OpenSSL" appear in their names without prior written
 *        permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *        acknowledgment:
 *        "This product includes software developed by the OpenSSL Project
 *        for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT AS IS'' AND ANY
 * EXPRESSED 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 OpenSSL PROJECT OR
 * ITS CONTRIBUTORS 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.
 * ====================================================================
 */

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

60
#include <openssl/ct.h>
61
#include <openssl/err.h>
62
#include <openssl/pem.h>
63 64
#include <openssl/x509.h>
#include <openssl/x509v3.h>
65 66
#include "testutil.h"

67
#ifndef OPENSSL_NO_CT
68 69 70 71

/* Used when declaring buffers to read text files into */
#define CT_TEST_MAX_FILE_SIZE 8096

72 73
static char *certs_dir = NULL;
static char *ct_dir = NULL;
74

75 76
typedef struct ct_test_fixture {
    const char *test_case_name;
R
Rob Percival 已提交
77 78
    /* The CT log store to use during tests */
    CTLOG_STORE* ctlog_store;
79
    /* Set the following to test handling of SCTs in X509 certificates */
80 81 82
    const char *certs_dir;
    char *certificate_file;
    char *issuer_file;
R
Rob Percival 已提交
83
    int expected_sct_count;
84
    /* Set the following to test handling of SCTs in TLS format */
85
    const unsigned char *tls_sct;
86
    size_t tls_sct_len;
R
Rob Percival 已提交
87
    SCT *sct;
88 89 90 91 92
    /*
     * A file to load the expected SCT text from.
     * This text will be compared to the actual text output during the test.
     * A maximum of |CT_TEST_MAX_FILE_SIZE| bytes will be read of this file.
     */
93 94
    const char *sct_dir;
    const char *sct_text_file;
R
Rob Percival 已提交
95 96
    /* Whether to test the validity of the SCT(s) */
    int test_validity;
97 98 99 100 101 102 103

} CT_TEST_FIXTURE;

static CT_TEST_FIXTURE set_up(const char *const test_case_name)
{
    CT_TEST_FIXTURE fixture;
    int setup_ok = 1;
R
Rob Percival 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116
    CTLOG_STORE *ctlog_store = CTLOG_STORE_new();

    if (ctlog_store == NULL) {
        setup_ok = 0;
        fprintf(stderr, "Failed to create a new CT log store\n");
        goto end;
    }

    if (CTLOG_STORE_load_default_file(ctlog_store) != 1) {
        setup_ok = 0;
        fprintf(stderr, "Failed to load CT log list\n");
        goto end;
    }
117 118 119

    memset(&fixture, 0, sizeof(fixture));
    fixture.test_case_name = test_case_name;
R
Rob Percival 已提交
120
    fixture.ctlog_store = ctlog_store;
121

R
Rob Percival 已提交
122
end:
123 124 125 126 127 128 129 130
    if (!setup_ok) {
        exit(EXIT_FAILURE);
    }
    return fixture;
}

static void tear_down(CT_TEST_FIXTURE fixture)
{
R
Rob Percival 已提交
131
    CTLOG_STORE_free(fixture.ctlog_store);
R
Rob Percival 已提交
132
    SCT_free(fixture.sct);
133 134 135
    ERR_print_errors_fp(stderr);
}

136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
static char *mk_file_path(const char *dir, const char *file)
{
    char *full_file = NULL;
    size_t full_file_l = 0;
    const char *sep = "";
#ifndef OPENSSL_SYS_VMS
    sep = "/";
#endif

    full_file_l = strlen(dir) + strlen(sep) + strlen(file) + 1;
    full_file = OPENSSL_zalloc(full_file_l);
    if (full_file != NULL) {
        OPENSSL_strlcpy(full_file, dir, full_file_l);
        OPENSSL_strlcat(full_file, sep, full_file_l);
        OPENSSL_strlcat(full_file, file, full_file_l);
    }

    return full_file;
}

static X509 *load_pem_cert(const char *dir, const char *file)
157 158
{
    X509 *cert = NULL;
159
    char *file_path = mk_file_path(dir, file);
160

161 162 163
    if (file_path != NULL) {
        BIO *cert_io = BIO_new_file(file_path, "r");
        OPENSSL_free(file_path);
164

165 166
        if (cert_io != NULL)
            cert = PEM_read_bio_X509(cert_io, NULL, NULL, NULL);
167

168 169
        BIO_free(cert_io);
    }
170 171 172
    return cert;
}

173 174
static int read_text_file(const char *dir, const char *file,
                          char *buffer, int buffer_length)
175 176
{
    int result = -1;
177 178 179 180 181
    char *file_path = mk_file_path(dir, file);

    if (file_path != NULL) {
        BIO *file_io = BIO_new_file(file_path, "r");
        OPENSSL_free(file_path);
182

183 184 185 186
        if (file_io != NULL) {
            result = BIO_read(file_io, buffer, buffer_length);
            BIO_free(file_io);
        }
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
    }

    return result;
}

static int compare_sct_printout(SCT *sct,
    const char *expected_output)
{
    BIO *text_buffer = NULL;
    char *actual_output = NULL;
    int result = 1;

    text_buffer = BIO_new(BIO_s_mem());
    if (text_buffer == NULL) {
        fprintf(stderr, "Unable to allocate buffer\n");
        goto end;
    }

    SCT_print(sct, text_buffer, 0);

    /* Append null terminator because we're about to use the buffer contents
    * as a string. */
    if (BIO_write(text_buffer, "\0", 1) != 1) {
        fprintf(stderr, "Failed to append null terminator to SCT text\n");
        goto end;
    }

    BIO_get_mem_data(text_buffer, &actual_output);
    result = strcmp(actual_output, expected_output);

    if (result != 0) {
        fprintf(stderr,
            "Expected SCT printout:\n%s\nActual SCT printout:\n%s\n",
            expected_output, actual_output);
    }

end:
    BIO_free(text_buffer);
    return result;
}

static int compare_extension_printout(X509_EXTENSION *extension,
                                      const char *expected_output)
{
    BIO *text_buffer = NULL;
    char *actual_output = NULL;
    int result = 1;

    text_buffer = BIO_new(BIO_s_mem());
    if (text_buffer == NULL) {
        fprintf(stderr, "Unable to allocate buffer\n");
        goto end;
    }

    if (!X509V3_EXT_print(text_buffer, extension, X509V3_EXT_DEFAULT, 0)) {
        fprintf(stderr, "Failed to print extension\n");
        goto end;
    }

    /* Append null terminator because we're about to use the buffer contents
     * as a string. */
    if (BIO_write(text_buffer, "\0", 1) != 1) {
        fprintf(stderr, "Failed to append null terminator to extension text\n");
        goto end;
    }

    BIO_get_mem_data(text_buffer, &actual_output);
    result = strcmp(actual_output, expected_output);

    if (result != 0) {
        fprintf(stderr,
                "Expected SCT printout:\n%s\nActual SCT printout:\n%s\n",
                expected_output, actual_output);
    }

end:
    BIO_free(text_buffer);
    return result;
}

static int execute_cert_test(CT_TEST_FIXTURE fixture)
{
R
Rob Percival 已提交
269 270 271
    int test_failed = 0;
    X509 *cert = NULL, *issuer = NULL;
    STACK_OF(SCT) *scts = NULL;
272 273 274
    SCT *sct = NULL;
    char expected_sct_text[CT_TEST_MAX_FILE_SIZE];
    int sct_text_len = 0;
R
Rob Percival 已提交
275 276
    unsigned char *tls_sct = NULL;
    size_t tls_sct_len = 0;
R
Rob Percival 已提交
277
    CT_POLICY_EVAL_CTX *ct_policy_ctx = CT_POLICY_EVAL_CTX_new();
278

279 280 281 282
    if (fixture.sct_text_file != NULL) {
        sct_text_len = read_text_file(fixture.sct_dir, fixture.sct_text_file,
                                      expected_sct_text,
                                      CT_TEST_MAX_FILE_SIZE - 1);
283 284

        if (sct_text_len < 0) {
R
Rob Percival 已提交
285
            test_failed = 1;
286
            fprintf(stderr, "Test data file not found: %s\n",
287
                fixture.sct_text_file);
288 289 290 291 292 293
            goto end;
        }

        expected_sct_text[sct_text_len] = '\0';
    }

R
Rob Percival 已提交
294 295
    CT_POLICY_EVAL_CTX_set0_log_store(ct_policy_ctx, fixture.ctlog_store);

296
    if (fixture.certificate_file != NULL) {
297 298
        int sct_extension_index;
        X509_EXTENSION *sct_extension = NULL;
299
        cert = load_pem_cert(fixture.certs_dir, fixture.certificate_file);
300 301

        if (cert == NULL) {
R
Rob Percival 已提交
302
            test_failed = 1;
303
            fprintf(stderr, "Unable to load certificate: %s\n",
304
                fixture.certificate_file);
305 306 307
            goto end;
        }

R
Rob Percival 已提交
308 309
        CT_POLICY_EVAL_CTX_set0_cert(ct_policy_ctx, cert);

310 311
        if (fixture.issuer_file != NULL) {
            issuer = load_pem_cert(fixture.certs_dir, fixture.issuer_file);
R
Rob Percival 已提交
312 313 314 315

            if (issuer == NULL) {
                test_failed = 1;
                fprintf(stderr, "Unable to load issuer certificate: %s\n",
316
                        fixture.issuer_file);
R
Rob Percival 已提交
317 318 319 320 321 322 323 324
                goto end;
            }

            CT_POLICY_EVAL_CTX_set0_issuer(ct_policy_ctx, issuer);
        }

        sct_extension_index =
                X509_get_ext_by_NID(cert, NID_ct_precert_scts, -1);
325 326 327
        sct_extension = X509_get_ext(cert, sct_extension_index);
        if (fixture.expected_sct_count > 0) {
            if (sct_extension == NULL) {
R
Rob Percival 已提交
328
                test_failed = 1;
329
                fprintf(stderr, "SCT extension not found in: %s\n",
330
                    fixture.certificate_file);
331 332 333
                goto end;
            }

334
            if (fixture.sct_text_file) {
R
Rob Percival 已提交
335
                test_failed = compare_extension_printout(sct_extension,
336
                                                    expected_sct_text);
R
Rob Percival 已提交
337 338 339 340 341 342
                if (test_failed != 0)
                    goto end;
            }

            if (fixture.test_validity) {
                int are_scts_validated = 0;
343 344
                int i;

R
Rob Percival 已提交
345
                scts = X509V3_EXT_d2i(sct_extension);
346 347 348 349 350 351 352 353 354
                for (i = 0; i < sk_SCT_num(scts); ++i) {
                    SCT *sct_i = sk_SCT_value(scts, i);

                    if (!SCT_set_source(sct_i, SCT_SOURCE_X509V3_EXTENSION)) {
                        fprintf(stderr,
                                "Error setting SCT source to X509v3 extension\n");
                        test_failed = 1;
                        goto end;
                    }
355
                }
R
Rob Percival 已提交
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396

                are_scts_validated = SCT_LIST_validate(scts, ct_policy_ctx);
                if (are_scts_validated < 0) {
                    fprintf(stderr, "Error verifying SCTs\n");
                    test_failed = 1;
                } else if (!are_scts_validated) {
                    int invalid_sct_count = 0;
                    int valid_sct_count = 0;

                    for (i = 0; i < sk_SCT_num(scts); ++i) {
                        SCT *sct_i = sk_SCT_value(scts, i);
                        switch (SCT_get_validation_status(sct_i)) {
                        case SCT_VALIDATION_STATUS_VALID:
                            ++valid_sct_count;
                            break;
                        case SCT_VALIDATION_STATUS_INVALID:
                            ++invalid_sct_count;
                            break;
                        default:
                            /* Ignore other validation statuses. */
                            break;
                        }
                    }

                    if (valid_sct_count != fixture.expected_sct_count) {
                        int unverified_sct_count = sk_SCT_num(scts) -
                                invalid_sct_count - valid_sct_count;

                        fprintf(stderr,
                                "%d SCTs failed verification\n"
                                "%d SCTs passed verification (%d expected)\n"
                                "%d SCTs were unverified\n",
                                invalid_sct_count,
                                valid_sct_count,
                                fixture.expected_sct_count,
                                unverified_sct_count);
                    }
                    test_failed = 1;
                }

                if (test_failed != 0)
397 398 399
                    goto end;
            }
        } else if (sct_extension != NULL) {
R
Rob Percival 已提交
400 401 402
            test_failed = 1;
            fprintf(stderr,
                    "Expected no SCTs, but found SCT extension in: %s\n",
403
                    fixture.certificate_file);
404 405 406 407 408 409 410
            goto end;
        }
    }

    if (fixture.tls_sct != NULL) {
        const unsigned char *p = fixture.tls_sct;
        if (o2i_SCT(&sct, &p, fixture.tls_sct_len) == NULL) {
R
Rob Percival 已提交
411
            test_failed = 1;
412 413 414 415
            fprintf(stderr, "Failed to decode SCT from TLS format\n");
            goto end;
        }

416
        if (fixture.sct_text_file) {
R
Rob Percival 已提交
417 418
            test_failed = compare_sct_printout(sct, expected_sct_text);
            if (test_failed != 0)
419 420 421 422 423 424
                goto end;
        }

        tls_sct_len = i2o_SCT(sct, &tls_sct);
        if (tls_sct_len != fixture.tls_sct_len ||
            memcmp(fixture.tls_sct, tls_sct, tls_sct_len) != 0) {
R
Rob Percival 已提交
425
            test_failed = 1;
426 427 428
            fprintf(stderr, "Failed to encode SCT into TLS format correctly\n");
            goto end;
        }
R
Rob Percival 已提交
429 430 431 432 433 434 435 436 437 438 439 440 441

        if (fixture.test_validity && cert != NULL) {
            int is_sct_validated = SCT_validate(sct, ct_policy_ctx);
            if (is_sct_validated < 0) {
                test_failed = 1;
                fprintf(stderr, "Error validating SCT\n");
                goto end;
            } else if (!is_sct_validated) {
                test_failed = 1;
                fprintf(stderr, "SCT failed verification\n");
                goto end;
            }
        }
442 443 444 445
    }

end:
    X509_free(cert);
R
Rob Percival 已提交
446 447
    X509_free(issuer);
    SCT_LIST_free(scts);
448
    SCT_free(sct);
R
Rob Percival 已提交
449
    CT_POLICY_EVAL_CTX_free(ct_policy_ctx);
R
Rob Percival 已提交
450
    OPENSSL_free(tls_sct);
R
Rob Percival 已提交
451
    return test_failed;
452 453 454 455 456 457 458 459
}

#define SETUP_CT_TEST_FIXTURE() SETUP_TEST_FIXTURE(CT_TEST_FIXTURE, set_up)
#define EXECUTE_CT_TEST() EXECUTE_TEST(execute_cert_test, tear_down)

static int test_no_scts_in_certificate()
{
    SETUP_CT_TEST_FIXTURE();
460 461 462
    fixture.certs_dir = certs_dir;
    fixture.certificate_file = "leaf.pem";
    fixture.issuer_file = "subinterCA.pem";
463 464 465 466 467 468 469
    fixture.expected_sct_count = 0;
    EXECUTE_CT_TEST();
}

static int test_one_sct_in_certificate()
{
    SETUP_CT_TEST_FIXTURE();
470 471 472
    fixture.certs_dir = certs_dir;
    fixture.certificate_file = "embeddedSCTs1.pem";
    fixture.issuer_file = "embeddedSCTs1_issuer.pem";
473
    fixture.expected_sct_count = 1;
474 475
    fixture.sct_dir = certs_dir;
    fixture.sct_text_file = "embeddedSCTs1.sct";
476 477 478 479 480 481
    EXECUTE_CT_TEST();
}

static int test_multiple_scts_in_certificate()
{
    SETUP_CT_TEST_FIXTURE();
482 483 484
    fixture.certs_dir = certs_dir;
    fixture.certificate_file = "embeddedSCTs3.pem";
    fixture.issuer_file = "embeddedSCTs3_issuer.pem";
485
    fixture.expected_sct_count = 3;
486 487
    fixture.sct_dir = certs_dir;
    fixture.sct_text_file = "embeddedSCTs3.sct";
488 489 490
    EXECUTE_CT_TEST();
}

R
Rob Percival 已提交
491 492 493
static int test_verify_one_sct()
{
    SETUP_CT_TEST_FIXTURE();
494 495 496
    fixture.certs_dir = certs_dir;
    fixture.certificate_file = "embeddedSCTs1.pem";
    fixture.issuer_file = "embeddedSCTs1_issuer.pem";
R
Rob Percival 已提交
497 498 499 500 501 502 503 504
    fixture.expected_sct_count = 1;
    fixture.test_validity = 1;
    EXECUTE_CT_TEST();
}

static int test_verify_multiple_scts()
{
    SETUP_CT_TEST_FIXTURE();
505 506 507
    fixture.certs_dir = certs_dir;
    fixture.certificate_file = "embeddedSCTs3.pem";
    fixture.issuer_file = "embeddedSCTs3_issuer.pem";
R
Rob Percival 已提交
508 509 510 511 512
    fixture.expected_sct_count = 3;
    fixture.test_validity = 1;
    EXECUTE_CT_TEST();
}

513 514
static int test_decode_tls_sct()
{
515
    const unsigned char tls_sct[] = "\x00" /* version */
516 517 518 519 520 521 522 523
        /* log ID */
        "\xDF\x1C\x2E\xC1\x15\x00\x94\x52\x47\xA9\x61\x68\x32\x5D\xDC\x5C\x79"
        "\x59\xE8\xF7\xC6\xD3\x88\xFC\x00\x2E\x0B\xBD\x3F\x74\xD7\x64"
        "\x00\x00\x01\x3D\xDB\x27\xDF\x93" /* timestamp */
        "\x00\x00" /* extensions length */
        "" /* extensions */
        "\x04\x03" /* hash and signature algorithms */
        "\x00\x47" /* signature length */
524
        /* signature */
525 526 527 528
        "\x30\x45\x02\x20\x48\x2F\x67\x51\xAF\x35\xDB\xA6\x54\x36\xBE\x1F\xD6"
        "\x64\x0F\x3D\xBF\x9A\x41\x42\x94\x95\x92\x45\x30\x28\x8F\xA3\xE5\xE2"
        "\x3E\x06\x02\x21\x00\xE4\xED\xC0\xDB\x3A\xC5\x72\xB1\xE2\xF5\xE8\xAB"
        "\x6A\x68\x06\x53\x98\x7D\xCF\x41\x02\x7D\xFE\xFF\xA1\x05\x51\x9D\x89"
529 530 531 532
        "\xED\xBF\x08";

    SETUP_CT_TEST_FIXTURE();
    fixture.tls_sct = tls_sct;
533
    fixture.tls_sct_len = 118;
534 535
    fixture.sct_dir = ct_dir;
    fixture.sct_text_file = "tls1.sct";
536 537 538 539 540
    EXECUTE_CT_TEST();
}

static int test_encode_tls_sct()
{
541 542 543 544 545 546 547 548 549 550
    const unsigned char log_id[] = "\xDF\x1C\x2E\xC1\x15\x00\x94\x52\x47\xA9"
            "\x61\x68\x32\x5D\xDC\x5C\x79\x59\xE8\xF7\xC6\xD3\x88\xFC\x00\x2E"
            "\x0B\xBD\x3F\x74\xD7\x64";

    const unsigned char signature[] = "\x45\x02\x20\x48\x2F\x67\x51\xAF\x35"
            "\xDB\xA6\x54\x36\xBE\x1F\xD6\x64\x0F\x3D\xBF\x9A\x41\x42\x94\x95"
            "\x92\x45\x30\x28\x8F\xA3\xE5\xE2\x3E\x06\x02\x21\x00\xE4\xED\xC0"
            "\xDB\x3A\xC5\x72\xB1\xE2\xF5\xE8\xAB\x6A\x68\x06\x53\x98\x7D\xCF"
            "\x41\x02\x7D\xFE\xFF\xA1\x05\x51\x9D\x89\xED\xBF\x08";

551 552 553
    SETUP_CT_TEST_FIXTURE();

    SCT *sct = SCT_new();
554
    if (!SCT_set_version(sct, SCT_VERSION_V1)) {
555 556 557
        fprintf(stderr, "Failed to set SCT version\n");
        return 1;
    }
558
    if (!SCT_set1_log_id(sct, log_id, 32)) {
559 560 561
        fprintf(stderr, "Failed to set SCT log ID\n");
        return 1;
    }
562
    SCT_set_timestamp(sct, 1);
563 564 565 566
    if (!SCT_set_signature_nid(sct, NID_ecdsa_with_SHA256)) {
        fprintf(stderr, "Failed to set SCT signature NID\n");
        return 1;
    }
567
    if (!SCT_set1_signature(sct, signature, 71)) {
568 569 570
        fprintf(stderr, "Failed to set SCT signature\n");
        return 1;
    }
571
    fixture.sct = sct;
572 573
    fixture.sct_dir = ct_dir;
    fixture.sct_text_file = "tls1.sct";
574 575 576 577 578 579
    EXECUTE_CT_TEST();
}

int main(int argc, char *argv[])
{
    int result = 0;
580 581 582 583 584 585
    char *tmp_env = NULL;

    tmp_env = getenv("CT_DIR");
    ct_dir = OPENSSL_strdup(tmp_env != NULL ? tmp_env : "ct");
    tmp_env = getenv("CERTS_DIR");
    certs_dir = OPENSSL_strdup(tmp_env != NULL ? tmp_env : "certs");
586 587 588 589

    ADD_TEST(test_no_scts_in_certificate);
    ADD_TEST(test_one_sct_in_certificate);
    ADD_TEST(test_multiple_scts_in_certificate);
R
Rob Percival 已提交
590 591
    ADD_TEST(test_verify_one_sct);
    ADD_TEST(test_verify_multiple_scts);
592 593 594 595 596 597
    ADD_TEST(test_decode_tls_sct);
    ADD_TEST(test_encode_tls_sct);

    result = run_tests(argv[0]);
    ERR_print_errors_fp(stderr);

598 599 600
    OPENSSL_free(ct_dir);
    OPENSSL_free(certs_dir);

601 602 603 604 605 606 607 608 609 610 611
    return result;
}

#else /* OPENSSL_NO_CT */

int main(int argc, char* argv[])
{
    return EXIT_SUCCESS;
}

#endif /* OPENSSL_NO_CT */