blob: ac89f57847028cf421897485f502a6c2a1abf914 [file] [log] [blame]
Rob Percival5dc31222016-02-22 16:51:44 +00001/*
Rich Salz440e5d82016-05-17 14:20:24 -04002 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
Rob Percival5dc31222016-02-22 16:51:44 +00003 *
Rich Salz440e5d82016-05-17 14:20:24 -04004 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
Rob Percival5dc31222016-02-22 16:51:44 +00008 */
9
10#include <ctype.h>
Rob Percivalebcb5362016-11-15 10:42:57 +000011#include <math.h>
Rob Percival5dc31222016-02-22 16:51:44 +000012#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15
Rob Percival0cea8832016-02-25 18:11:16 +000016#include <openssl/ct.h>
Richard Levitte17436ce2016-02-26 08:57:06 +010017#include <openssl/err.h>
Rob Percival2b2b9682016-03-07 17:58:49 +000018#include <openssl/pem.h>
Richard Levitte17436ce2016-02-26 08:57:06 +010019#include <openssl/x509.h>
20#include <openssl/x509v3.h>
Rob Percival5dc31222016-02-22 16:51:44 +000021#include "testutil.h"
Emilia Kaspere364c3b2016-11-07 16:53:15 +010022#include "test_main_custom.h"
Rob Percival5dc31222016-02-22 16:51:44 +000023
Rob Percival11c8bc42016-03-07 17:58:14 +000024#ifndef OPENSSL_NO_CT
Rob Percival5dc31222016-02-22 16:51:44 +000025/* Used when declaring buffers to read text files into */
26#define CT_TEST_MAX_FILE_SIZE 8096
27
Richard Levitte67336ea2016-03-09 17:24:34 +010028static char *certs_dir = NULL;
29static char *ct_dir = NULL;
Richard Levittec469a9a2016-03-09 14:10:05 +010030
Rob Percival5dc31222016-02-22 16:51:44 +000031typedef struct ct_test_fixture {
32 const char *test_case_name;
Rob Percival1fa9ffd2016-09-08 16:02:46 +010033 /* The current time in milliseconds */
34 uint64_t epoch_time_in_ms;
Rob Percival7d054e52016-02-29 17:33:02 +000035 /* The CT log store to use during tests */
36 CTLOG_STORE* ctlog_store;
Rob Percival5dc31222016-02-22 16:51:44 +000037 /* Set the following to test handling of SCTs in X509 certificates */
Richard Levittec469a9a2016-03-09 14:10:05 +010038 const char *certs_dir;
39 char *certificate_file;
40 char *issuer_file;
Rob Percival1fa9ffd2016-09-08 16:02:46 +010041 /* Expected number of SCTs */
Rob Percival7d054e52016-02-29 17:33:02 +000042 int expected_sct_count;
Rob Percival1fa9ffd2016-09-08 16:02:46 +010043 /* Expected number of valid SCTS */
44 int expected_valid_sct_count;
Rob Percival5dc31222016-02-22 16:51:44 +000045 /* Set the following to test handling of SCTs in TLS format */
Rob Percival4fc31f72016-06-07 17:38:14 +010046 const unsigned char *tls_sct_list;
47 size_t tls_sct_list_len;
48 STACK_OF(SCT) *sct_list;
Rob Percival5dc31222016-02-22 16:51:44 +000049 /*
50 * A file to load the expected SCT text from.
51 * This text will be compared to the actual text output during the test.
52 * A maximum of |CT_TEST_MAX_FILE_SIZE| bytes will be read of this file.
53 */
Richard Levittec469a9a2016-03-09 14:10:05 +010054 const char *sct_dir;
55 const char *sct_text_file;
Rob Percival7d054e52016-02-29 17:33:02 +000056 /* Whether to test the validity of the SCT(s) */
57 int test_validity;
Rob Percival5dc31222016-02-22 16:51:44 +000058} CT_TEST_FIXTURE;
59
60static CT_TEST_FIXTURE set_up(const char *const test_case_name)
61{
62 CT_TEST_FIXTURE fixture;
63 int setup_ok = 1;
Emilia Kasper50eadf22016-04-08 16:19:00 +020064
65 memset(&fixture, 0, sizeof(fixture));
66
Rob Percival765731a2016-10-19 15:40:46 +010067 fixture.test_case_name = test_case_name;
68 fixture.epoch_time_in_ms = 1473269626000; /* Sep 7 17:33:46 2016 GMT */
69 fixture.ctlog_store = CTLOG_STORE_new();
Rob Percival7d054e52016-02-29 17:33:02 +000070
Rob Percival765731a2016-10-19 15:40:46 +010071 if (fixture.ctlog_store == NULL) {
Rob Percival7d054e52016-02-29 17:33:02 +000072 setup_ok = 0;
73 fprintf(stderr, "Failed to create a new CT log store\n");
74 goto end;
75 }
76
Rob Percival765731a2016-10-19 15:40:46 +010077 if (CTLOG_STORE_load_default_file(fixture.ctlog_store) != 1) {
Rob Percival7d054e52016-02-29 17:33:02 +000078 setup_ok = 0;
79 fprintf(stderr, "Failed to load CT log list\n");
80 goto end;
81 }
Rob Percival5dc31222016-02-22 16:51:44 +000082
Rob Percival7d054e52016-02-29 17:33:02 +000083end:
Rob Percival5dc31222016-02-22 16:51:44 +000084 if (!setup_ok) {
Rob Percival765731a2016-10-19 15:40:46 +010085 CTLOG_STORE_free(fixture.ctlog_store);
Rob Percival5dc31222016-02-22 16:51:44 +000086 exit(EXIT_FAILURE);
87 }
88 return fixture;
89}
90
91static void tear_down(CT_TEST_FIXTURE fixture)
92{
Rob Percival7d054e52016-02-29 17:33:02 +000093 CTLOG_STORE_free(fixture.ctlog_store);
Rob Percival4fc31f72016-06-07 17:38:14 +010094 SCT_LIST_free(fixture.sct_list);
Rob Percival5dc31222016-02-22 16:51:44 +000095}
96
Richard Levittec469a9a2016-03-09 14:10:05 +010097static char *mk_file_path(const char *dir, const char *file)
Rob Percival5dc31222016-02-22 16:51:44 +000098{
Richard Levittec469a9a2016-03-09 14:10:05 +010099 char *full_file = NULL;
100 size_t full_file_l = 0;
101 const char *sep = "";
102#ifndef OPENSSL_SYS_VMS
103 sep = "/";
104#endif
105
106 full_file_l = strlen(dir) + strlen(sep) + strlen(file) + 1;
107 full_file = OPENSSL_zalloc(full_file_l);
108 if (full_file != NULL) {
109 OPENSSL_strlcpy(full_file, dir, full_file_l);
110 OPENSSL_strlcat(full_file, sep, full_file_l);
111 OPENSSL_strlcat(full_file, file, full_file_l);
112 }
113
114 return full_file;
115}
116
117static X509 *load_pem_cert(const char *dir, const char *file)
118{
Rob Percival5dc31222016-02-22 16:51:44 +0000119 X509 *cert = NULL;
Richard Levittec469a9a2016-03-09 14:10:05 +0100120 char *file_path = mk_file_path(dir, file);
Rob Percival5dc31222016-02-22 16:51:44 +0000121
Richard Levittec469a9a2016-03-09 14:10:05 +0100122 if (file_path != NULL) {
123 BIO *cert_io = BIO_new_file(file_path, "r");
124 OPENSSL_free(file_path);
Rob Percival5dc31222016-02-22 16:51:44 +0000125
Richard Levittec469a9a2016-03-09 14:10:05 +0100126 if (cert_io != NULL)
127 cert = PEM_read_bio_X509(cert_io, NULL, NULL, NULL);
Rob Percival5dc31222016-02-22 16:51:44 +0000128
Richard Levittec469a9a2016-03-09 14:10:05 +0100129 BIO_free(cert_io);
130 }
Rob Percival5dc31222016-02-22 16:51:44 +0000131 return cert;
132}
133
Richard Levittec469a9a2016-03-09 14:10:05 +0100134static int read_text_file(const char *dir, const char *file,
135 char *buffer, int buffer_length)
Rob Percival5dc31222016-02-22 16:51:44 +0000136{
Rob Percival5dc31222016-02-22 16:51:44 +0000137 int result = -1;
Richard Levittec469a9a2016-03-09 14:10:05 +0100138 char *file_path = mk_file_path(dir, file);
Rob Percival5dc31222016-02-22 16:51:44 +0000139
Richard Levittec469a9a2016-03-09 14:10:05 +0100140 if (file_path != NULL) {
141 BIO *file_io = BIO_new_file(file_path, "r");
142 OPENSSL_free(file_path);
143
144 if (file_io != NULL) {
145 result = BIO_read(file_io, buffer, buffer_length);
146 BIO_free(file_io);
147 }
Rob Percival5dc31222016-02-22 16:51:44 +0000148 }
149
150 return result;
151}
152
Rob Percival4fc31f72016-06-07 17:38:14 +0100153static int compare_sct_list_printout(STACK_OF(SCT) *sct,
Rob Percival5dc31222016-02-22 16:51:44 +0000154 const char *expected_output)
155{
156 BIO *text_buffer = NULL;
157 char *actual_output = NULL;
158 int result = 1;
159
160 text_buffer = BIO_new(BIO_s_mem());
161 if (text_buffer == NULL) {
162 fprintf(stderr, "Unable to allocate buffer\n");
163 goto end;
164 }
165
Rob Percival4fc31f72016-06-07 17:38:14 +0100166 SCT_LIST_print(sct, text_buffer, 0, "\n", NULL);
Rob Percival5dc31222016-02-22 16:51:44 +0000167
168 /* Append null terminator because we're about to use the buffer contents
169 * as a string. */
170 if (BIO_write(text_buffer, "\0", 1) != 1) {
171 fprintf(stderr, "Failed to append null terminator to SCT text\n");
172 goto end;
173 }
174
175 BIO_get_mem_data(text_buffer, &actual_output);
176 result = strcmp(actual_output, expected_output);
177
178 if (result != 0) {
179 fprintf(stderr,
180 "Expected SCT printout:\n%s\nActual SCT printout:\n%s\n",
181 expected_output, actual_output);
182 }
183
184end:
185 BIO_free(text_buffer);
186 return result;
187}
188
189static int compare_extension_printout(X509_EXTENSION *extension,
190 const char *expected_output)
191{
192 BIO *text_buffer = NULL;
193 char *actual_output = NULL;
194 int result = 1;
195
196 text_buffer = BIO_new(BIO_s_mem());
197 if (text_buffer == NULL) {
198 fprintf(stderr, "Unable to allocate buffer\n");
199 goto end;
200 }
201
202 if (!X509V3_EXT_print(text_buffer, extension, X509V3_EXT_DEFAULT, 0)) {
203 fprintf(stderr, "Failed to print extension\n");
204 goto end;
205 }
206
207 /* Append null terminator because we're about to use the buffer contents
208 * as a string. */
209 if (BIO_write(text_buffer, "\0", 1) != 1) {
Rob Percival4fc31f72016-06-07 17:38:14 +0100210 fprintf(stderr,
211 "Failed to append null terminator to extension text\n");
Rob Percival5dc31222016-02-22 16:51:44 +0000212 goto end;
213 }
214
215 BIO_get_mem_data(text_buffer, &actual_output);
216 result = strcmp(actual_output, expected_output);
217
218 if (result != 0) {
219 fprintf(stderr,
220 "Expected SCT printout:\n%s\nActual SCT printout:\n%s\n",
221 expected_output, actual_output);
222 }
223
224end:
225 BIO_free(text_buffer);
226 return result;
227}
228
Rob Percival876a1a82016-06-07 17:56:02 +0100229static int assert_validity(CT_TEST_FIXTURE fixture,
230 STACK_OF(SCT) *scts,
231 CT_POLICY_EVAL_CTX *policy_ctx) {
232 int invalid_sct_count = 0;
233 int valid_sct_count = 0;
234 int i;
235
236 if (SCT_LIST_validate(scts, policy_ctx) < 0) {
237 fprintf(stderr, "Error verifying SCTs\n");
238 return 0;
239 }
240
241 for (i = 0; i < sk_SCT_num(scts); ++i) {
242 SCT *sct_i = sk_SCT_value(scts, i);
243 switch (SCT_get_validation_status(sct_i)) {
244 case SCT_VALIDATION_STATUS_VALID:
245 ++valid_sct_count;
246 break;
247 case SCT_VALIDATION_STATUS_INVALID:
248 ++invalid_sct_count;
249 break;
Rich Salzf3b3d7f2016-08-30 13:31:18 -0400250 case SCT_VALIDATION_STATUS_NOT_SET:
251 case SCT_VALIDATION_STATUS_UNKNOWN_LOG:
252 case SCT_VALIDATION_STATUS_UNVERIFIED:
253 case SCT_VALIDATION_STATUS_UNKNOWN_VERSION:
Rob Percival876a1a82016-06-07 17:56:02 +0100254 /* Ignore other validation statuses. */
255 break;
256 }
257 }
258
Rob Percival1fa9ffd2016-09-08 16:02:46 +0100259 if (valid_sct_count != fixture.expected_valid_sct_count) {
Rob Percival876a1a82016-06-07 17:56:02 +0100260 int unverified_sct_count = sk_SCT_num(scts) -
261 invalid_sct_count - valid_sct_count;
262
263 fprintf(stderr,
264 "%d SCTs failed verification\n"
265 "%d SCTs passed verification (%d expected)\n"
266 "%d SCTs were unverified\n",
267 invalid_sct_count,
268 valid_sct_count,
Rob Percival1fa9ffd2016-09-08 16:02:46 +0100269 fixture.expected_valid_sct_count,
Rob Percival876a1a82016-06-07 17:56:02 +0100270 unverified_sct_count);
271 return 0;
272 }
273
274 return 1;
275}
276
Rob Percival5dc31222016-02-22 16:51:44 +0000277static int execute_cert_test(CT_TEST_FIXTURE fixture)
278{
Emilia Kasperababe862016-04-05 14:29:06 +0200279 int success = 0;
Rob Percival7d054e52016-02-29 17:33:02 +0000280 X509 *cert = NULL, *issuer = NULL;
281 STACK_OF(SCT) *scts = NULL;
Rob Percival5dc31222016-02-22 16:51:44 +0000282 SCT *sct = NULL;
283 char expected_sct_text[CT_TEST_MAX_FILE_SIZE];
284 int sct_text_len = 0;
Rob Percival4fc31f72016-06-07 17:38:14 +0100285 unsigned char *tls_sct_list = NULL;
286 size_t tls_sct_list_len = 0;
Rob Percival7d054e52016-02-29 17:33:02 +0000287 CT_POLICY_EVAL_CTX *ct_policy_ctx = CT_POLICY_EVAL_CTX_new();
Rob Percival5dc31222016-02-22 16:51:44 +0000288
Richard Levittec469a9a2016-03-09 14:10:05 +0100289 if (fixture.sct_text_file != NULL) {
290 sct_text_len = read_text_file(fixture.sct_dir, fixture.sct_text_file,
291 expected_sct_text,
292 CT_TEST_MAX_FILE_SIZE - 1);
Rob Percival5dc31222016-02-22 16:51:44 +0000293
294 if (sct_text_len < 0) {
Rob Percival5dc31222016-02-22 16:51:44 +0000295 fprintf(stderr, "Test data file not found: %s\n",
Richard Levittec469a9a2016-03-09 14:10:05 +0100296 fixture.sct_text_file);
Rob Percival5dc31222016-02-22 16:51:44 +0000297 goto end;
298 }
299
300 expected_sct_text[sct_text_len] = '\0';
301 }
302
Rob Percivala1bb7702016-08-05 14:17:31 +0100303 CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(
304 ct_policy_ctx, fixture.ctlog_store);
Rob Percival7d054e52016-02-29 17:33:02 +0000305
Rob Percival1fa9ffd2016-09-08 16:02:46 +0100306 CT_POLICY_EVAL_CTX_set_time(ct_policy_ctx, fixture.epoch_time_in_ms);
307
Richard Levittec469a9a2016-03-09 14:10:05 +0100308 if (fixture.certificate_file != NULL) {
Rob Percival5dc31222016-02-22 16:51:44 +0000309 int sct_extension_index;
310 X509_EXTENSION *sct_extension = NULL;
Richard Levittec469a9a2016-03-09 14:10:05 +0100311 cert = load_pem_cert(fixture.certs_dir, fixture.certificate_file);
Rob Percival5dc31222016-02-22 16:51:44 +0000312
313 if (cert == NULL) {
Rob Percival5dc31222016-02-22 16:51:44 +0000314 fprintf(stderr, "Unable to load certificate: %s\n",
Richard Levittec469a9a2016-03-09 14:10:05 +0100315 fixture.certificate_file);
Rob Percival5dc31222016-02-22 16:51:44 +0000316 goto end;
317 }
318
Rob Percivala1bb7702016-08-05 14:17:31 +0100319 CT_POLICY_EVAL_CTX_set1_cert(ct_policy_ctx, cert);
Rob Percival7d054e52016-02-29 17:33:02 +0000320
Richard Levittec469a9a2016-03-09 14:10:05 +0100321 if (fixture.issuer_file != NULL) {
322 issuer = load_pem_cert(fixture.certs_dir, fixture.issuer_file);
Rob Percival7d054e52016-02-29 17:33:02 +0000323
324 if (issuer == NULL) {
Rob Percival7d054e52016-02-29 17:33:02 +0000325 fprintf(stderr, "Unable to load issuer certificate: %s\n",
Richard Levittec469a9a2016-03-09 14:10:05 +0100326 fixture.issuer_file);
Rob Percival7d054e52016-02-29 17:33:02 +0000327 goto end;
328 }
329
Rob Percivala1bb7702016-08-05 14:17:31 +0100330 CT_POLICY_EVAL_CTX_set1_issuer(ct_policy_ctx, issuer);
Rob Percival7d054e52016-02-29 17:33:02 +0000331 }
332
333 sct_extension_index =
334 X509_get_ext_by_NID(cert, NID_ct_precert_scts, -1);
Rob Percival5dc31222016-02-22 16:51:44 +0000335 sct_extension = X509_get_ext(cert, sct_extension_index);
336 if (fixture.expected_sct_count > 0) {
337 if (sct_extension == NULL) {
Rob Percival5dc31222016-02-22 16:51:44 +0000338 fprintf(stderr, "SCT extension not found in: %s\n",
Richard Levittec469a9a2016-03-09 14:10:05 +0100339 fixture.certificate_file);
Rob Percival5dc31222016-02-22 16:51:44 +0000340 goto end;
341 }
342
Emilia Kasperababe862016-04-05 14:29:06 +0200343 if (fixture.sct_text_file
344 && compare_extension_printout(sct_extension,
345 expected_sct_text)) {
Rob Percival7d054e52016-02-29 17:33:02 +0000346 goto end;
347 }
348
349 if (fixture.test_validity) {
Rob Percival14db9bb2016-03-08 19:09:06 +0000350 int i;
351
Rob Percival7d054e52016-02-29 17:33:02 +0000352 scts = X509V3_EXT_d2i(sct_extension);
Rob Percival14db9bb2016-03-08 19:09:06 +0000353 for (i = 0; i < sk_SCT_num(scts); ++i) {
354 SCT *sct_i = sk_SCT_value(scts, i);
355
356 if (!SCT_set_source(sct_i, SCT_SOURCE_X509V3_EXTENSION)) {
357 fprintf(stderr,
358 "Error setting SCT source to X509v3 extension\n");
Rob Percival14db9bb2016-03-08 19:09:06 +0000359 goto end;
360 }
Rob Percival5da65ef2016-03-04 19:51:43 +0000361 }
Rob Percival7d054e52016-02-29 17:33:02 +0000362
Rob Percival876a1a82016-06-07 17:56:02 +0100363 if (!assert_validity(fixture, scts, ct_policy_ctx))
Emilia Kasperababe862016-04-05 14:29:06 +0200364 goto end;
Rob Percival5dc31222016-02-22 16:51:44 +0000365 }
366 } else if (sct_extension != NULL) {
Rob Percival7d054e52016-02-29 17:33:02 +0000367 fprintf(stderr,
368 "Expected no SCTs, but found SCT extension in: %s\n",
Richard Levittec469a9a2016-03-09 14:10:05 +0100369 fixture.certificate_file);
Rob Percival5dc31222016-02-22 16:51:44 +0000370 goto end;
371 }
372 }
373
Rob Percival4fc31f72016-06-07 17:38:14 +0100374 if (fixture.tls_sct_list != NULL) {
375 const unsigned char *p = fixture.tls_sct_list;
376 if (o2i_SCT_LIST(&scts, &p, fixture.tls_sct_list_len) == NULL) {
377 fprintf(stderr, "Failed to decode SCTs from TLS format\n");
Rob Percival5dc31222016-02-22 16:51:44 +0000378 goto end;
379 }
380
Viktor Dukhovni43341432016-04-07 14:17:37 -0400381 if (fixture.test_validity && cert != NULL) {
Rob Percival876a1a82016-06-07 17:56:02 +0100382 if (!assert_validity(fixture, scts, ct_policy_ctx))
Viktor Dukhovni43341432016-04-07 14:17:37 -0400383 goto end;
Viktor Dukhovni43341432016-04-07 14:17:37 -0400384 }
385
Emilia Kasperababe862016-04-05 14:29:06 +0200386 if (fixture.sct_text_file
Rob Percival4fc31f72016-06-07 17:38:14 +0100387 && compare_sct_list_printout(scts, expected_sct_text)) {
Rob Percival5dc31222016-02-22 16:51:44 +0000388 goto end;
389 }
390
Rob Percival4fc31f72016-06-07 17:38:14 +0100391 tls_sct_list_len = i2o_SCT_LIST(scts, &tls_sct_list);
392 if (tls_sct_list_len != fixture.tls_sct_list_len ||
393 memcmp(fixture.tls_sct_list, tls_sct_list, tls_sct_list_len) != 0) {
394 fprintf(stderr,
395 "Failed to encode SCTs into TLS format correctly\n");
Rob Percival5dc31222016-02-22 16:51:44 +0000396 goto end;
397 }
398 }
Emilia Kasperababe862016-04-05 14:29:06 +0200399 success = 1;
Rob Percival5dc31222016-02-22 16:51:44 +0000400
401end:
402 X509_free(cert);
Rob Percival7d054e52016-02-29 17:33:02 +0000403 X509_free(issuer);
404 SCT_LIST_free(scts);
Rob Percival5dc31222016-02-22 16:51:44 +0000405 SCT_free(sct);
Rob Percival7d054e52016-02-29 17:33:02 +0000406 CT_POLICY_EVAL_CTX_free(ct_policy_ctx);
Rob Percival4fc31f72016-06-07 17:38:14 +0100407 OPENSSL_free(tls_sct_list);
Emilia Kasperababe862016-04-05 14:29:06 +0200408 return success;
Rob Percival5dc31222016-02-22 16:51:44 +0000409}
410
411#define SETUP_CT_TEST_FIXTURE() SETUP_TEST_FIXTURE(CT_TEST_FIXTURE, set_up)
412#define EXECUTE_CT_TEST() EXECUTE_TEST(execute_cert_test, tear_down)
413
414static int test_no_scts_in_certificate()
415{
416 SETUP_CT_TEST_FIXTURE();
Richard Levittec469a9a2016-03-09 14:10:05 +0100417 fixture.certs_dir = certs_dir;
418 fixture.certificate_file = "leaf.pem";
419 fixture.issuer_file = "subinterCA.pem";
Rob Percival5dc31222016-02-22 16:51:44 +0000420 fixture.expected_sct_count = 0;
421 EXECUTE_CT_TEST();
422}
423
424static int test_one_sct_in_certificate()
425{
426 SETUP_CT_TEST_FIXTURE();
Richard Levittec469a9a2016-03-09 14:10:05 +0100427 fixture.certs_dir = certs_dir;
428 fixture.certificate_file = "embeddedSCTs1.pem";
429 fixture.issuer_file = "embeddedSCTs1_issuer.pem";
Rob Percival5dc31222016-02-22 16:51:44 +0000430 fixture.expected_sct_count = 1;
Richard Levittec469a9a2016-03-09 14:10:05 +0100431 fixture.sct_dir = certs_dir;
432 fixture.sct_text_file = "embeddedSCTs1.sct";
Rob Percival5dc31222016-02-22 16:51:44 +0000433 EXECUTE_CT_TEST();
434}
435
436static int test_multiple_scts_in_certificate()
437{
438 SETUP_CT_TEST_FIXTURE();
Richard Levittec469a9a2016-03-09 14:10:05 +0100439 fixture.certs_dir = certs_dir;
440 fixture.certificate_file = "embeddedSCTs3.pem";
441 fixture.issuer_file = "embeddedSCTs3_issuer.pem";
Rob Percival5dc31222016-02-22 16:51:44 +0000442 fixture.expected_sct_count = 3;
Richard Levittec469a9a2016-03-09 14:10:05 +0100443 fixture.sct_dir = certs_dir;
444 fixture.sct_text_file = "embeddedSCTs3.sct";
Rob Percival5dc31222016-02-22 16:51:44 +0000445 EXECUTE_CT_TEST();
446}
447
Rob Percival7d054e52016-02-29 17:33:02 +0000448static int test_verify_one_sct()
449{
450 SETUP_CT_TEST_FIXTURE();
Richard Levittec469a9a2016-03-09 14:10:05 +0100451 fixture.certs_dir = certs_dir;
452 fixture.certificate_file = "embeddedSCTs1.pem";
453 fixture.issuer_file = "embeddedSCTs1_issuer.pem";
Rob Percival1fa9ffd2016-09-08 16:02:46 +0100454 fixture.expected_sct_count = fixture.expected_valid_sct_count = 1;
Rob Percival7d054e52016-02-29 17:33:02 +0000455 fixture.test_validity = 1;
456 EXECUTE_CT_TEST();
457}
458
459static int test_verify_multiple_scts()
460{
461 SETUP_CT_TEST_FIXTURE();
Richard Levittec469a9a2016-03-09 14:10:05 +0100462 fixture.certs_dir = certs_dir;
463 fixture.certificate_file = "embeddedSCTs3.pem";
464 fixture.issuer_file = "embeddedSCTs3_issuer.pem";
Rob Percival1fa9ffd2016-09-08 16:02:46 +0100465 fixture.expected_sct_count = fixture.expected_valid_sct_count = 3;
466 fixture.test_validity = 1;
467 EXECUTE_CT_TEST();
468}
469
470static int test_verify_fails_for_future_sct()
471{
472 SETUP_CT_TEST_FIXTURE();
473 fixture.epoch_time_in_ms = 1365094800000; /* Apr 4 17:00:00 2013 GMT */
474 fixture.certs_dir = certs_dir;
475 fixture.certificate_file = "embeddedSCTs1.pem";
476 fixture.issuer_file = "embeddedSCTs1_issuer.pem";
477 fixture.expected_sct_count = 1;
478 fixture.expected_valid_sct_count = 0;
Rob Percival7d054e52016-02-29 17:33:02 +0000479 fixture.test_validity = 1;
480 EXECUTE_CT_TEST();
481}
482
Rob Percival5dc31222016-02-22 16:51:44 +0000483static int test_decode_tls_sct()
484{
Rob Percival4fc31f72016-06-07 17:38:14 +0100485 const unsigned char tls_sct_list[] = "\x00\x78" /* length of list */
486 "\x00\x76"
487 "\x00" /* version */
Rob Percival5dc31222016-02-22 16:51:44 +0000488 /* log ID */
489 "\xDF\x1C\x2E\xC1\x15\x00\x94\x52\x47\xA9\x61\x68\x32\x5D\xDC\x5C\x79"
490 "\x59\xE8\xF7\xC6\xD3\x88\xFC\x00\x2E\x0B\xBD\x3F\x74\xD7\x64"
491 "\x00\x00\x01\x3D\xDB\x27\xDF\x93" /* timestamp */
492 "\x00\x00" /* extensions length */
493 "" /* extensions */
494 "\x04\x03" /* hash and signature algorithms */
495 "\x00\x47" /* signature length */
Rob Percivaldc919c62016-03-09 02:46:15 +0000496 /* signature */
Rob Percival5dc31222016-02-22 16:51:44 +0000497 "\x30\x45\x02\x20\x48\x2F\x67\x51\xAF\x35\xDB\xA6\x54\x36\xBE\x1F\xD6"
498 "\x64\x0F\x3D\xBF\x9A\x41\x42\x94\x95\x92\x45\x30\x28\x8F\xA3\xE5\xE2"
499 "\x3E\x06\x02\x21\x00\xE4\xED\xC0\xDB\x3A\xC5\x72\xB1\xE2\xF5\xE8\xAB"
500 "\x6A\x68\x06\x53\x98\x7D\xCF\x41\x02\x7D\xFE\xFF\xA1\x05\x51\x9D\x89"
Rob Percivaldc919c62016-03-09 02:46:15 +0000501 "\xED\xBF\x08";
502
503 SETUP_CT_TEST_FIXTURE();
Rob Percival4fc31f72016-06-07 17:38:14 +0100504 fixture.tls_sct_list = tls_sct_list;
505 fixture.tls_sct_list_len = 0x7a;
Richard Levittec469a9a2016-03-09 14:10:05 +0100506 fixture.sct_dir = ct_dir;
507 fixture.sct_text_file = "tls1.sct";
Rob Percival5dc31222016-02-22 16:51:44 +0000508 EXECUTE_CT_TEST();
509}
510
511static int test_encode_tls_sct()
512{
Rob Percivalf7a39a52016-09-07 17:47:56 +0100513 const char log_id[] = "3xwuwRUAlFJHqWFoMl3cXHlZ6PfG04j8AC4LvT9012Q=";
514 const uint64_t timestamp = 1;
515 const char extensions[] = "";
Rob Percivale2635c42016-10-19 15:39:13 +0100516 const char signature[] = "BAMARzBAMiBIL2dRrzXbplQ2vh/WZA89v5pBQpSVkkUwKI+j5"
517 "eI+BgIhAOTtwNs6xXKx4vXoq2poBlOYfc9BAn3+/6EFUZ2J7b8I";
Rob Percival765731a2016-10-19 15:40:46 +0100518 SCT *sct = NULL;
Rob Percivaldc919c62016-03-09 02:46:15 +0000519
Rob Percival5dc31222016-02-22 16:51:44 +0000520 SETUP_CT_TEST_FIXTURE();
521
Rob Percival765731a2016-10-19 15:40:46 +0100522 fixture.sct_list = sk_SCT_new_null();
523 sct = SCT_new_from_base64(SCT_VERSION_V1, log_id,
524 CT_LOG_ENTRY_TYPE_X509, timestamp,
525 extensions, signature);
Rob Percival4fc31f72016-06-07 17:38:14 +0100526
Rob Percivalf7a39a52016-09-07 17:47:56 +0100527 if (sct == NULL) {
Rob Percival765731a2016-10-19 15:40:46 +0100528 tear_down(fixture);
Rob Percivalf7a39a52016-09-07 17:47:56 +0100529 fprintf(stderr, "Failed to create SCT from base64-encoded test data\n");
530 return 0;
531 }
532
Rob Percival765731a2016-10-19 15:40:46 +0100533 sk_SCT_push(fixture.sct_list, sct);
Richard Levittec469a9a2016-03-09 14:10:05 +0100534 fixture.sct_dir = ct_dir;
535 fixture.sct_text_file = "tls1.sct";
Rob Percival5dc31222016-02-22 16:51:44 +0000536 EXECUTE_CT_TEST();
Rob Percival5dc31222016-02-22 16:51:44 +0000537}
538
Rob Percivalebcb5362016-11-15 10:42:57 +0000539/*
540 * Tests that the CT_POLICY_EVAL_CTX default time is approximately now.
541 * Allow +-10 minutes, as it may compensate for clock skew.
542 */
543static int test_default_ct_policy_eval_ctx_time_is_now()
544{
545 int success = 0;
546 CT_POLICY_EVAL_CTX *ct_policy_ctx = CT_POLICY_EVAL_CTX_new();
547 const time_t default_time = CT_POLICY_EVAL_CTX_get_time(ct_policy_ctx) /
548 1000;
549 const time_t time_tolerance = 600; /* 10 minutes */
550
551 if (fabs(difftime(time(NULL), default_time)) > time_tolerance) {
552 fprintf(stderr,
553 "Default CT_POLICY_EVAL_CTX time is not approximately now.\n");
554 goto end;
555 }
556
557 success = 1;
558end:
559 CT_POLICY_EVAL_CTX_free(ct_policy_ctx);
560 return success;
561}
562
Emilia Kaspere364c3b2016-11-07 16:53:15 +0100563int test_main(int argc, char *argv[])
Rob Percival5dc31222016-02-22 16:51:44 +0000564{
565 int result = 0;
Emilia Kaspere364c3b2016-11-07 16:53:15 +0100566 char *tmp_env;
FdaSilvaYYf0e1fe72016-03-18 23:17:39 +0100567
Richard Levittec469a9a2016-03-09 14:10:05 +0100568 tmp_env = getenv("CT_DIR");
569 ct_dir = OPENSSL_strdup(tmp_env != NULL ? tmp_env : "ct");
570 tmp_env = getenv("CERTS_DIR");
571 certs_dir = OPENSSL_strdup(tmp_env != NULL ? tmp_env : "certs");
Rob Percival5dc31222016-02-22 16:51:44 +0000572
573 ADD_TEST(test_no_scts_in_certificate);
574 ADD_TEST(test_one_sct_in_certificate);
575 ADD_TEST(test_multiple_scts_in_certificate);
Rob Percival7d054e52016-02-29 17:33:02 +0000576 ADD_TEST(test_verify_one_sct);
577 ADD_TEST(test_verify_multiple_scts);
Rob Percival1fa9ffd2016-09-08 16:02:46 +0100578 ADD_TEST(test_verify_fails_for_future_sct);
Rob Percival5dc31222016-02-22 16:51:44 +0000579 ADD_TEST(test_decode_tls_sct);
580 ADD_TEST(test_encode_tls_sct);
Rob Percivalebcb5362016-11-15 10:42:57 +0000581 ADD_TEST(test_default_ct_policy_eval_ctx_time_is_now);
Rob Percival5dc31222016-02-22 16:51:44 +0000582
583 result = run_tests(argv[0]);
Rob Percival5dc31222016-02-22 16:51:44 +0000584
Richard Levittec469a9a2016-03-09 14:10:05 +0100585 OPENSSL_free(ct_dir);
586 OPENSSL_free(certs_dir);
587
Rob Percival5dc31222016-02-22 16:51:44 +0000588 return result;
589}
Richard Levitte42e055e2016-11-10 01:33:54 +0100590#else
591int test_main(int argc, char *argv[])
592{
593 printf("No CT support\n");
594 return 0;
595}
Emilia Kaspere364c3b2016-11-07 16:53:15 +0100596#endif