GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libtls/tls_ocsp.c Lines: 35 207 16.9 %
Date: 2017-11-13 Branches: 12 122 9.8 %

Line Branch Exec Source
1
/*
2
 * Copyright (c) 2015 Marko Kreen <markokr@gmail.com>
3
 * Copyright (c) 2016 Bob Beck <beck@openbsd.org>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
#include <sys/types.h>
19
20
#include <arpa/inet.h>
21
#include <netinet/in.h>
22
23
#include <openssl/err.h>
24
#include <openssl/ocsp.h>
25
#include <openssl/x509.h>
26
27
#include <tls.h>
28
#include "tls_internal.h"
29
30
#define MAXAGE_SEC (14*24*60*60)
31
#define JITTER_SEC (60)
32
33
/*
34
 * State for request.
35
 */
36
37
static struct tls_ocsp *
38
tls_ocsp_new(void)
39
{
40
48
	return (calloc(1, sizeof(struct tls_ocsp)));
41
}
42
43
void
44
tls_ocsp_free(struct tls_ocsp *ocsp)
45
{
46
516
	if (ocsp == NULL)
47
		return;
48
49
24
	X509_free(ocsp->main_cert);
50
24
	ocsp->main_cert = NULL;
51
24
	free(ocsp->ocsp_result);
52
24
	ocsp->ocsp_result = NULL;
53
24
	free(ocsp->ocsp_url);
54
24
	ocsp->ocsp_url = NULL;
55
24
	free(ocsp);
56
282
}
57
58
static int
59
tls_ocsp_asn1_parse_time(struct tls *ctx, ASN1_GENERALIZEDTIME *gt, time_t *gt_time)
60
{
61
	struct tm tm;
62
63
	if (gt == NULL)
64
		return -1;
65
	/* RFC 6960 specifies that all times in OCSP must be GENERALIZEDTIME */
66
	if (ASN1_time_parse(gt->data, gt->length, &tm,
67
		V_ASN1_GENERALIZEDTIME) == -1)
68
		return -1;
69
	if ((*gt_time = timegm(&tm)) == -1)
70
		return -1;
71
	return 0;
72
}
73
74
static int
75
tls_ocsp_fill_info(struct tls *ctx, int response_status, int cert_status,
76
    int crl_reason, ASN1_GENERALIZEDTIME *revtime,
77
    ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd)
78
{
79
	struct tls_ocsp_result *info = NULL;
80
81
	free(ctx->ocsp->ocsp_result);
82
	ctx->ocsp->ocsp_result = NULL;
83
84
	if ((info = calloc(1, sizeof (struct tls_ocsp_result))) == NULL) {
85
		tls_set_error(ctx, "calloc");
86
		return -1;
87
	}
88
	info->response_status = response_status;
89
	info->cert_status = cert_status;
90
	info->crl_reason = crl_reason;
91
	if (info->response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
92
		info->result_msg =
93
		    OCSP_response_status_str(info->response_status);
94
	} else if (info->cert_status != V_OCSP_CERTSTATUS_REVOKED) {
95
		info->result_msg = OCSP_cert_status_str(info->cert_status);
96
	} else {
97
		info->result_msg = OCSP_crl_reason_str(info->crl_reason);
98
	}
99
	info->revocation_time = info->this_update = info->next_update = -1;
100
	if (revtime != NULL &&
101
	    tls_ocsp_asn1_parse_time(ctx, revtime, &info->revocation_time) != 0) {
102
		tls_set_error(ctx,
103
		    "unable to parse revocation time in OCSP reply");
104
		goto error;
105
	}
106
	if (thisupd != NULL &&
107
	    tls_ocsp_asn1_parse_time(ctx, thisupd, &info->this_update) != 0) {
108
		tls_set_error(ctx,
109
		    "unable to parse this update time in OCSP reply");
110
		goto error;
111
	}
112
	if (nextupd != NULL &&
113
	    tls_ocsp_asn1_parse_time(ctx, nextupd, &info->next_update) != 0) {
114
		tls_set_error(ctx,
115
		    "unable to parse next update time in OCSP reply");
116
		goto error;
117
	}
118
	ctx->ocsp->ocsp_result = info;
119
	return 0;
120
 error:
121
	free(info);
122
	return -1;
123
}
124
125
static OCSP_CERTID *
126
tls_ocsp_get_certid(X509 *main_cert, STACK_OF(X509) *extra_certs,
127
    SSL_CTX *ssl_ctx)
128
{
129
	X509_NAME *issuer_name;
130
	X509 *issuer;
131
	X509_STORE_CTX storectx;
132
	X509_OBJECT tmpobj;
133
	OCSP_CERTID *cid = NULL;
134
	X509_STORE *store;
135
136
	if ((issuer_name = X509_get_issuer_name(main_cert)) == NULL)
137
		return NULL;
138
139
	if (extra_certs != NULL) {
140
		issuer = X509_find_by_subject(extra_certs, issuer_name);
141
		if (issuer != NULL)
142
			return OCSP_cert_to_id(NULL, main_cert, issuer);
143
	}
144
145
	if ((store = SSL_CTX_get_cert_store(ssl_ctx)) == NULL)
146
		return NULL;
147
	if (X509_STORE_CTX_init(&storectx, store, main_cert, extra_certs) != 1)
148
		return NULL;
149
	if (X509_STORE_get_by_subject(&storectx, X509_LU_X509, issuer_name,
150
		&tmpobj) == 1) {
151
		cid = OCSP_cert_to_id(NULL, main_cert, tmpobj.data.x509);
152
		X509_OBJECT_free_contents(&tmpobj);
153
	}
154
	X509_STORE_CTX_cleanup(&storectx);
155
	return cid;
156
}
157
158
struct tls_ocsp *
159
tls_ocsp_setup_from_peer(struct tls *ctx)
160
{
161
	struct tls_ocsp *ocsp = NULL;
162
	STACK_OF(OPENSSL_STRING) *ocsp_urls = NULL;
163
164
48
	if ((ocsp = tls_ocsp_new()) == NULL)
165
		goto failed;
166
167
	/* steal state from ctx struct */
168
24
	ocsp->main_cert = SSL_get_peer_certificate(ctx->ssl_conn);
169
24
	ocsp->extra_certs = SSL_get_peer_cert_chain(ctx->ssl_conn);
170
24
	if (ocsp->main_cert == NULL) {
171
12
		tls_set_errorx(ctx, "no peer certificate for OCSP");
172
12
		goto failed;
173
	}
174
175
12
	ocsp_urls = X509_get1_ocsp(ocsp->main_cert);
176
12
	if (ocsp_urls == NULL) {
177
12
		tls_set_errorx(ctx, "no OCSP URLs in peer certificate");
178
12
		goto failed;
179
	}
180
181
	ocsp->ocsp_url = strdup(sk_OPENSSL_STRING_value(ocsp_urls, 0));
182
	if (ocsp->ocsp_url == NULL) {
183
		tls_set_errorx(ctx, "out of memory");
184
		goto failed;
185
	}
186
187
	X509_email_free(ocsp_urls);
188
	return ocsp;
189
190
 failed:
191
24
	tls_ocsp_free(ocsp);
192
24
	X509_email_free(ocsp_urls);
193
24
	return NULL;
194
24
}
195
196
static int
197
tls_ocsp_verify_response(struct tls *ctx, OCSP_RESPONSE *resp)
198
{
199
	OCSP_BASICRESP *br = NULL;
200
	ASN1_GENERALIZEDTIME *revtime = NULL, *thisupd = NULL, *nextupd = NULL;
201
	OCSP_CERTID *cid = NULL;
202
	STACK_OF(X509) *combined = NULL;
203
	int response_status=0, cert_status=0, crl_reason=0;
204
	int ret = -1;
205
	unsigned long flags;
206
207
	if ((br = OCSP_response_get1_basic(resp)) == NULL) {
208
		tls_set_errorx(ctx, "cannot load ocsp reply");
209
		goto error;
210
	}
211
212
	/*
213
	 * Skip validation of 'extra_certs' as this should be done
214
	 * already as part of main handshake.
215
	 */
216
	flags = OCSP_TRUSTOTHER;
217
218
	/* now verify */
219
	if (OCSP_basic_verify(br, ctx->ocsp->extra_certs,
220
		SSL_CTX_get_cert_store(ctx->ssl_ctx), flags) != 1) {
221
		tls_set_error(ctx, "ocsp verify failed");
222
		goto error;
223
	}
224
225
	/* signature OK, look inside */
226
	response_status = OCSP_response_status(resp);
227
	if (response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
228
		tls_set_errorx(ctx, "ocsp verify failed: response - %s",
229
		    OCSP_response_status_str(response_status));
230
		goto error;
231
	}
232
233
	cid = tls_ocsp_get_certid(ctx->ocsp->main_cert,
234
	    ctx->ocsp->extra_certs, ctx->ssl_ctx);
235
	if (cid == NULL) {
236
		tls_set_errorx(ctx, "ocsp verify failed: no issuer cert");
237
		goto error;
238
	}
239
240
	if (OCSP_resp_find_status(br, cid, &cert_status, &crl_reason,
241
	    &revtime, &thisupd, &nextupd) != 1) {
242
		tls_set_errorx(ctx, "ocsp verify failed: no result for cert");
243
		goto error;
244
	}
245
246
	if (OCSP_check_validity(thisupd, nextupd, JITTER_SEC,
247
	    MAXAGE_SEC) != 1) {
248
		tls_set_errorx(ctx,
249
		    "ocsp verify failed: ocsp response not current");
250
		goto error;
251
	}
252
253
	if (tls_ocsp_fill_info(ctx, response_status, cert_status,
254
	    crl_reason, revtime, thisupd, nextupd) != 0)
255
		goto error;
256
257
	/* finally can look at status */
258
	if (cert_status != V_OCSP_CERTSTATUS_GOOD && cert_status !=
259
	    V_OCSP_CERTSTATUS_UNKNOWN) {
260
		tls_set_errorx(ctx, "ocsp verify failed: revoked cert - %s",
261
			       OCSP_crl_reason_str(crl_reason));
262
		goto error;
263
	}
264
	ret = 0;
265
266
 error:
267
	sk_X509_free(combined);
268
	OCSP_CERTID_free(cid);
269
	OCSP_BASICRESP_free(br);
270
	return ret;
271
}
272
273
/*
274
 * Process a raw OCSP response from an OCSP server request.
275
 * OCSP details can then be retrieved with tls_peer_ocsp_* functions.
276
 * returns 0 if certificate ok, -1 otherwise.
277
 */
278
static int
279
tls_ocsp_process_response_internal(struct tls *ctx, const unsigned char *response,
280
    size_t size)
281
{
282
	int ret;
283
	OCSP_RESPONSE *resp;
284
285
	resp = d2i_OCSP_RESPONSE(NULL, &response, size);
286
	if (resp == NULL) {
287
		tls_ocsp_free(ctx->ocsp);
288
		ctx->ocsp = NULL;
289
		tls_set_error(ctx, "unable to parse OCSP response");
290
		return -1;
291
	}
292
	ret = tls_ocsp_verify_response(ctx, resp);
293
	OCSP_RESPONSE_free(resp);
294
	return ret;
295
}
296
297
/* TLS handshake verification callback for stapled requests */
298
int
299
tls_ocsp_verify_cb(SSL *ssl, void *arg)
300
{
301
24
	const unsigned char *raw = NULL;
302
	int size, res = -1;
303
	struct tls *ctx;
304
305
12
	if ((ctx = SSL_get_app_data(ssl)) == NULL)
306
		return -1;
307
308
12
	size = SSL_get_tlsext_status_ocsp_resp(ssl, &raw);
309
12
	if (size <= 0) {
310
12
		if (ctx->config->ocsp_require_stapling) {
311
			tls_set_errorx(ctx, "no stapled OCSP response provided");
312
			return 0;
313
		}
314
12
		return 1;
315
	}
316
317
	tls_ocsp_free(ctx->ocsp);
318
	if ((ctx->ocsp = tls_ocsp_setup_from_peer(ctx)) == NULL)
319
		return 0;
320
321
	if (ctx->config->verify_cert == 0 || ctx->config->verify_time == 0)
322
		return 1;
323
324
	res = tls_ocsp_process_response_internal(ctx, raw, size);
325
326
	return (res == 0) ? 1 : 0;
327
12
}
328
329
330
/* Staple the OCSP information in ctx->ocsp to the server handshake. */
331
int
332
tls_ocsp_stapling_cb(SSL *ssl, void *arg)
333
{
334
	int ret = SSL_TLSEXT_ERR_ALERT_FATAL;
335
	unsigned char *ocsp_staple = NULL;
336
	struct tls *ctx;
337
338
24
	if ((ctx = SSL_get_app_data(ssl)) == NULL)
339
		goto err;
340
341

24
	if (ctx->keypair == NULL || ctx->keypair->ocsp_staple == NULL ||
342
	    ctx->keypair->ocsp_staple_len == 0)
343
12
		return SSL_TLSEXT_ERR_NOACK;
344
345
	if ((ocsp_staple = malloc(ctx->keypair->ocsp_staple_len)) == NULL)
346
		goto err;
347
348
	memcpy(ocsp_staple, ctx->keypair->ocsp_staple,
349
	    ctx->keypair->ocsp_staple_len);
350
351
	if (SSL_set_tlsext_status_ocsp_resp(ctx->ssl_conn, ocsp_staple,
352
	    ctx->keypair->ocsp_staple_len) != 1)
353
		goto err;
354
355
	ret = SSL_TLSEXT_ERR_OK;
356
 err:
357
	if (ret != SSL_TLSEXT_ERR_OK)
358
		free(ocsp_staple);
359
360
	return ret;
361
12
}
362
363
/*
364
 * Public API
365
 */
366
367
/* Retrieve OCSP URL from peer certificate, if present. */
368
const char *
369
tls_peer_ocsp_url(struct tls *ctx)
370
{
371
	if (ctx->ocsp == NULL)
372
		return NULL;
373
	return ctx->ocsp->ocsp_url;
374
}
375
376
const char *
377
tls_peer_ocsp_result(struct tls *ctx)
378
{
379
	if (ctx->ocsp == NULL)
380
		return NULL;
381
	if (ctx->ocsp->ocsp_result == NULL)
382
		return NULL;
383
	return ctx->ocsp->ocsp_result->result_msg;
384
}
385
386
int
387
tls_peer_ocsp_response_status(struct tls *ctx)
388
{
389
	if (ctx->ocsp == NULL)
390
		return -1;
391
	if (ctx->ocsp->ocsp_result == NULL)
392
		return -1;
393
	return ctx->ocsp->ocsp_result->response_status;
394
}
395
396
int
397
tls_peer_ocsp_cert_status(struct tls *ctx)
398
{
399
	if (ctx->ocsp == NULL)
400
		return -1;
401
	if (ctx->ocsp->ocsp_result == NULL)
402
		return -1;
403
	return ctx->ocsp->ocsp_result->cert_status;
404
}
405
406
int
407
tls_peer_ocsp_crl_reason(struct tls *ctx)
408
{
409
	if (ctx->ocsp == NULL)
410
		return -1;
411
	if (ctx->ocsp->ocsp_result == NULL)
412
		return -1;
413
	return ctx->ocsp->ocsp_result->crl_reason;
414
}
415
416
time_t
417
tls_peer_ocsp_this_update(struct tls *ctx)
418
{
419
	if (ctx->ocsp == NULL)
420
		return -1;
421
	if (ctx->ocsp->ocsp_result == NULL)
422
		return -1;
423
	return ctx->ocsp->ocsp_result->this_update;
424
}
425
426
time_t
427
tls_peer_ocsp_next_update(struct tls *ctx)
428
{
429
	if (ctx->ocsp == NULL)
430
		return -1;
431
	if (ctx->ocsp->ocsp_result == NULL)
432
		return -1;
433
	return ctx->ocsp->ocsp_result->next_update;
434
}
435
436
time_t
437
tls_peer_ocsp_revocation_time(struct tls *ctx)
438
{
439
	if (ctx->ocsp == NULL)
440
		return -1;
441
	if (ctx->ocsp->ocsp_result == NULL)
442
		return -1;
443
	return ctx->ocsp->ocsp_result->revocation_time;
444
}
445
446
int
447
tls_ocsp_process_response(struct tls *ctx, const unsigned char *response,
448
    size_t size)
449
{
450
	if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0)
451
		return -1;
452
	return tls_ocsp_process_response_internal(ctx, response, size);
453
}