]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/danetest.c
Remove BIO_seek/BIO_tell from evp_test.c
[thirdparty/openssl.git] / test / danetest.c
CommitLineData
440e5d80
RS
1/*
2 * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
170b7358 3 *
440e5d80
RS
4 * 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
170b7358
VD
8 */
9
10#include <stdio.h>
11#include <string.h>
12#include <ctype.h>
13#include <limits.h>
14#include <errno.h>
15
16#include <openssl/crypto.h>
17#include <openssl/evp.h>
18#include <openssl/x509.h>
19#include <openssl/ssl.h>
20#include <openssl/err.h>
21#include <openssl/conf.h>
22#ifndef OPENSSL_NO_ENGINE
23#include <openssl/engine.h>
24#endif
25
26#include "../e_os.h"
27
18295f0c
RL
28#define _UC(c) ((unsigned char)(c))
29
170b7358
VD
30static const char *progname;
31
32/*
33 * Forward declaration, of function that uses internal interfaces, from headers
34 * included at the end of this module.
35 */
36static void store_ctx_dane_init(X509_STORE_CTX *, SSL *);
37
38static int saved_errno;
39
40static void save_errno(void)
41{
42 saved_errno = errno;
43}
44
45static int restore_errno(void)
46{
47 int ret = errno;
48 errno = saved_errno;
49 return ret;
50}
51
71405d68 52static void test_usage(void)
170b7358
VD
53{
54 fprintf(stderr, "usage: %s: danetest basedomain CAfile tlsafile\n", progname);
55}
56
57static void print_errors(void)
58{
59 unsigned long err;
60 char buffer[1024];
61 const char *file;
62 const char *data;
63 int line;
64 int flags;
65
66 while ((err = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
67 ERR_error_string_n(err, buffer, sizeof(buffer));
68 if (flags & ERR_TXT_STRING)
69 fprintf(stderr, "Error: %s:%s:%d:%s\n", buffer, file, line, data);
70 else
71 fprintf(stderr, "Error: %s:%s:%d\n", buffer, file, line);
72 }
73}
74
75static int verify_chain(SSL *ssl, STACK_OF(X509) *chain)
76{
e5a5e3f3 77 int ret = -1;
170b7358
VD
78 X509_STORE_CTX *store_ctx;
79 SSL_CTX *ssl_ctx = SSL_get_SSL_CTX(ssl);
80 X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
81 int store_ctx_idx = SSL_get_ex_data_X509_STORE_CTX_idx();
82 X509 *cert = sk_X509_value(chain, 0);
83
84 if ((store_ctx = X509_STORE_CTX_new()) == NULL)
85 return -1;
86
87 if (!X509_STORE_CTX_init(store_ctx, store, cert, chain))
e5a5e3f3
F
88 goto end;
89 if (!X509_STORE_CTX_set_ex_data(store_ctx, store_ctx_idx, ssl))
90 goto end;
170b7358
VD
91
92 X509_STORE_CTX_set_default(store_ctx,
93 SSL_is_server(ssl) ? "ssl_client" : "ssl_server");
94 X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(store_ctx),
95 SSL_get0_param(ssl));
96 store_ctx_dane_init(store_ctx, ssl);
97
98 if (SSL_get_verify_callback(ssl))
dccd20d1 99 X509_STORE_CTX_set_verify_cb(store_ctx, SSL_get_verify_callback(ssl));
170b7358
VD
100
101 ret = X509_verify_cert(store_ctx);
102
103 SSL_set_verify_result(ssl, X509_STORE_CTX_get_error(store_ctx));
104 X509_STORE_CTX_cleanup(store_ctx);
e5a5e3f3 105end:
170b7358
VD
106 X509_STORE_CTX_free(store_ctx);
107
108 return (ret);
109}
110
02b91dcf 111static STACK_OF(X509) *load_chain(BIO *fp, int nelem)
170b7358
VD
112{
113 int count;
114 char *name = 0;
115 char *header = 0;
116 unsigned char *data = 0;
117 long len;
dccd20d1 118 char *errtype = 0; /* if error: cert or pkey? */
170b7358
VD
119 STACK_OF(X509) *chain;
120 typedef X509 *(*d2i_X509_t)(X509 **, const unsigned char **, long);
121
122 if ((chain = sk_X509_new_null()) == 0) {
dccd20d1
F
123 perror("malloc");
124 exit(1);
170b7358
VD
125 }
126
127 for (count = 0;
dccd20d1 128 count < nelem && errtype == 0
02b91dcf 129 && PEM_read_bio(fp, &name, &header, &data, &len);
dccd20d1
F
130 ++count) {
131 const unsigned char *p = data;
132
133 if (strcmp(name, PEM_STRING_X509) == 0
134 || strcmp(name, PEM_STRING_X509_TRUSTED) == 0
135 || strcmp(name, PEM_STRING_X509_OLD) == 0) {
136 d2i_X509_t d = strcmp(name, PEM_STRING_X509_TRUSTED) ?
137 d2i_X509_AUX : d2i_X509;
138 X509 *cert = d(0, &p, len);
139
140 if (cert == 0 || (p - data) != len)
141 errtype = "certificate";
142 else if (sk_X509_push(chain, cert) == 0) {
143 perror("malloc");
144 goto err;
145 }
146 } else {
147 fprintf(stderr, "unexpected chain file object: %s\n", name);
148 goto err;
149 }
150
151 /*
152 * If any of these were null, PEM_read() would have failed.
153 */
154 OPENSSL_free(name);
155 OPENSSL_free(header);
156 OPENSSL_free(data);
170b7358
VD
157 }
158
159 if (errtype) {
dccd20d1 160 fprintf(stderr, "error reading: malformed %s\n", errtype);
170b7358
VD
161 goto err;
162 }
49445f21 163
170b7358
VD
164 if (count == nelem) {
165 ERR_clear_error();
166 return chain;
167 }
168
169err:
170 /* Some other PEM read error */
171 sk_X509_pop_free(chain, X509_free);
172 print_errors();
173 return NULL;
174}
175
02b91dcf 176static char *read_to_eol(BIO *f)
170b7358
VD
177{
178 static char buf[1024];
179 int n;
180
02b91dcf 181 if (!BIO_gets(f, buf, sizeof(buf)))
170b7358
VD
182 return NULL;
183
184 n = strlen(buf);
185
186 if (buf[n-1] != '\n') {
187 if (n+1 == sizeof(buf)) {
188 fprintf(stderr, "%s: warning: input too long\n", progname);
189 } else {
190 fprintf(stderr, "%s: warning: EOF before newline\n", progname);
191 }
192 return NULL;
193 }
194
195 /* Trim trailing whitespace */
18295f0c 196 while (n > 0 && isspace(_UC(buf[n-1])))
170b7358
VD
197 buf[--n] = '\0';
198
199 return buf;
200}
201
202/*
203 * Hex decoder that tolerates optional whitespace
204 */
205static ossl_ssize_t hexdecode(const char *in, void *result)
206{
207 unsigned char **out = (unsigned char **)result;
208 unsigned char *ret = OPENSSL_malloc(strlen(in)/2);
209 unsigned char *cp = ret;
210 uint8_t byte;
211 int nibble = 0;
212
213 if (ret == NULL)
214 return -1;
215
216 for (byte = 0; *in; ++in) {
49445f21 217 int x;
170b7358 218
18295f0c 219 if (isspace(_UC(*in)))
170b7358 220 continue;
49445f21
RS
221 x = OPENSSL_hexchar2int(*in);
222 if (x < 0) {
170b7358
VD
223 OPENSSL_free(ret);
224 return 0;
225 }
49445f21 226 byte |= (char)x;
170b7358
VD
227 if ((nibble ^= 1) == 0) {
228 *cp++ = byte;
229 byte = 0;
230 } else {
231 byte <<= 4;
232 }
233 }
234 if (nibble != 0) {
235 OPENSSL_free(ret);
236 return 0;
237 }
238
239 return cp - (*out = ret);
240}
241
242static ossl_ssize_t checked_uint8(const char *in, void *out)
243{
244 uint8_t *result = (uint8_t *)out;
245 const char *cp = in;
246 char *endp;
247 long v;
248 int e;
249
250 save_errno();
251 v = strtol(cp, &endp, 10);
252 e = restore_errno();
253
254 if (((v == LONG_MIN || v == LONG_MAX) && e == ERANGE) ||
18295f0c 255 endp == cp || !isspace(_UC(*endp)) ||
170b7358
VD
256 v != (*(uint8_t *)result = (uint8_t) v)) {
257 return -1;
258 }
18295f0c 259 for (cp = endp; isspace(_UC(*cp)); ++cp)
170b7358
VD
260 continue;
261 return cp - in;
262}
263
bbd86bf5
RS
264struct tlsa_field {
265 void *var;
266 const char *name;
267 ossl_ssize_t (*parser)(const char *, void *);
268};
269
170b7358
VD
270static int tlsa_import_rr(SSL *ssl, const char *rrdata)
271{
bbd86bf5
RS
272 static uint8_t usage;
273 static uint8_t selector;
274 static uint8_t mtype;
275 static unsigned char *data = NULL;
276 static struct tlsa_field tlsa_fields[] = {
170b7358
VD
277 { &usage, "usage", checked_uint8 },
278 { &selector, "selector", checked_uint8 },
279 { &mtype, "mtype", checked_uint8 },
280 { &data, "data", hexdecode },
281 { NULL, }
282 };
bbd86bf5 283 int ret;
170b7358 284 struct tlsa_field *f;
bbd86bf5
RS
285 const char *cp = rrdata;
286 ossl_ssize_t len = 0;
170b7358
VD
287
288 for (f = tlsa_fields; f->var; ++f) {
289 if ((len = f->parser(cp += len, f->var)) <= 0) {
290 fprintf(stderr, "%s: warning: bad TLSA %s field in: %s\n",
291 progname, f->name, rrdata);
292 return 0;
293 }
294 }
295 ret = SSL_dane_tlsa_add(ssl, usage, selector, mtype, data, len);
296 OPENSSL_free(data);
297
298 if (ret == 0) {
299 print_errors();
300 fprintf(stderr, "%s: warning: unusable TLSA rrdata: %s\n",
301 progname, rrdata);
302 return 0;
303 }
304 if (ret < 0) {
305 fprintf(stderr, "%s: warning: error loading TLSA rrdata: %s\n",
306 progname, rrdata);
307 return 0;
308 }
309 return ret;
310}
311
312static int allws(const char *cp)
313{
314 while (*cp)
18295f0c 315 if (!isspace(_UC(*cp++)))
170b7358
VD
316 return 0;
317 return 1;
318}
319
320static int test_tlsafile(SSL_CTX *ctx, const char *basename,
02b91dcf 321 BIO *f, const char *path)
170b7358
VD
322{
323 char *line;
324 int testno = 0;
325 int ret = 1;
326 SSL *ssl;
327
328 while (ret > 0 && (line = read_to_eol(f)) != NULL) {
329 STACK_OF(X509) *chain;
330 int ntlsa;
331 int ncert;
5ae4ceb9 332 int noncheck;
170b7358
VD
333 int want;
334 int want_depth;
335 int off;
336 int i;
337 int ok;
338 int err;
339 int mdpth;
340
341 if (*line == '\0' || *line == '#')
342 continue;
343
344 ++testno;
5ae4ceb9
VD
345 if (sscanf(line, "%d %d %d %d %d%n",
346 &ntlsa, &ncert, &noncheck, &want, &want_depth, &off) != 5
170b7358
VD
347 || !allws(line + off)) {
348 fprintf(stderr, "Expected tlsa count, cert count and result"
349 " at test %d of %s\n", testno, path);
350 return 0;
351 }
352
353 if ((ssl = SSL_new(ctx)) == NULL)
354 return -1;
355 SSL_set_connect_state(ssl);
356 if (SSL_dane_enable(ssl, basename) <= 0) {
357 SSL_free(ssl);
358 return -1;
359 }
5ae4ceb9
VD
360 if (noncheck)
361 SSL_dane_set_flags(ssl, DANE_FLAG_NO_DANE_EE_NAMECHECKS);
170b7358
VD
362
363 for (i = 0; i < ntlsa; ++i) {
364 if ((line = read_to_eol(f)) == NULL || !tlsa_import_rr(ssl, line)) {
365 SSL_free(ssl);
366 return 0;
367 }
368 }
369
370 /* Don't report old news */
371 ERR_clear_error();
372 chain = load_chain(f, ncert);
373 if (chain == NULL) {
374 SSL_free(ssl);
375 return -1;
376 }
377
378 ok = verify_chain(ssl, chain);
379 sk_X509_pop_free(chain, X509_free);
380 err = SSL_get_verify_result(ssl);
c0a445a9
VD
381 /*
382 * Peek under the hood, normally TLSA match data is hidden when
383 * verification fails, we can obtain any suppressed data by setting the
384 * verification result to X509_V_OK before looking.
385 */
386 SSL_set_verify_result(ssl, X509_V_OK);
170b7358 387 mdpth = SSL_get0_dane_authority(ssl, NULL, NULL);
c0a445a9
VD
388 /* Not needed any more, but lead by example and put the error back. */
389 SSL_set_verify_result(ssl, err);
170b7358
VD
390 SSL_free(ssl);
391
392 if (ok < 0) {
393 ret = 0;
394 fprintf(stderr, "verify_chain internal error in %s test %d\n",
395 path, testno);
396 print_errors();
397 continue;
398 }
399 if (err != want || (want == 0 && !ok)) {
400 ret = 0;
401 if (err != want) {
402 if (want == X509_V_OK)
403 fprintf(stderr, "Verification failure in %s test %d: %d: %s\n",
404 path, testno, err, X509_verify_cert_error_string(err));
405 else
406 fprintf(stderr, "Unexpected error in %s test %d: %d: wanted %d\n",
407 path, testno, err, want);
408 } else {
409 fprintf(stderr, "Verification failure in %s test %d: ok=0\n",
410 path, testno);
411 }
412 print_errors();
413 continue;
414 }
415 if (mdpth != want_depth) {
416 ret = 0;
417 fprintf(stderr, "Wrong match depth, in %s test %d: wanted %d, got: %d\n",
418 path, testno, want_depth, mdpth);
419 }
420 fprintf(stderr, "%s: test %d successful\n", path, testno);
421 }
422 ERR_clear_error();
423
424 return ret;
425}
426
427int main(int argc, char *argv[])
428{
02b91dcf 429 BIO *f;
170b7358
VD
430 BIO *bio_err;
431 SSL_CTX *ctx = NULL;
432 const char *basedomain;
433 const char *CAfile;
434 const char *tlsafile;
bbd86bf5 435 const char *p;
170b7358
VD
436 int ret = 1;
437
bbd86bf5 438 progname = argv[0];
170b7358 439 if (argc != 4) {
71405d68 440 test_usage();
fde2257f 441 EXIT(ret);
170b7358
VD
442 }
443 basedomain = argv[1];
444 CAfile = argv[2];
445 tlsafile = argv[3];
446
d1b10582
VD
447 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
448
bbd86bf5
RS
449 p = getenv("OPENSSL_DEBUG_MEMORY");
450 if (p != NULL && strcmp(p, "on") == 0)
451 CRYPTO_set_mem_debug(1);
e51511ce 452 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
bbd86bf5 453
02b91dcf 454 f = BIO_new_file(tlsafile, "r");
170b7358
VD
455 if (f == NULL) {
456 fprintf(stderr, "%s: Error opening tlsa record file: '%s': %s\n",
457 progname, tlsafile, strerror(errno));
fde2257f 458 EXIT(ret);
170b7358
VD
459 }
460
170b7358
VD
461 ctx = SSL_CTX_new(TLS_client_method());
462 if (SSL_CTX_dane_enable(ctx) <= 0) {
463 print_errors();
464 goto end;
465 }
466 if (!SSL_CTX_load_verify_locations(ctx, CAfile, NULL)) {
467 print_errors();
468 goto end;
469 }
470 if ((SSL_CTX_dane_mtype_set(ctx, EVP_sha512(), 2, 1)) <= 0) {
471 print_errors();
472 goto end;
473 }
474 if ((SSL_CTX_dane_mtype_set(ctx, EVP_sha256(), 1, 2)) <= 0) {
475 print_errors();
476 goto end;
477 }
478
8da94770 479 if (test_tlsafile(ctx, basedomain, f, tlsafile) <= 0) {
170b7358
VD
480 print_errors();
481 goto end;
482 }
483
484 ret = 0;
485
486end:
487
02b91dcf 488 BIO_free(f);
170b7358
VD
489 SSL_CTX_free(ctx);
490
c2e27310 491#ifndef OPENSSL_NO_CRYPTO_MDEBUG
541e9565
DSH
492 if (CRYPTO_mem_leaks(bio_err) <= 0)
493 ret = 1;
7b0a09f9 494#endif
170b7358
VD
495 BIO_free(bio_err);
496 EXIT(ret);
497}
498
499#include <internal/dane.h>
500
501static void store_ctx_dane_init(X509_STORE_CTX *store_ctx, SSL *ssl)
502{
503 X509_STORE_CTX_set0_dane(store_ctx, SSL_get0_dane(ssl));
504}