Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/libressl/src/tls/tls_ocsp.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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 | return (calloc(1, sizeof(struct tls_ocsp))); executed 8 times by 1 test: return (calloc(1, sizeof(struct tls_ocsp))); Executed by:
| 8 | ||||||||||||||||||||||||
41 | } | - | ||||||||||||||||||||||||
42 | - | |||||||||||||||||||||||||
43 | void | - | ||||||||||||||||||||||||
44 | tls_ocsp_free(struct tls_ocsp *ocsp) | - | ||||||||||||||||||||||||
45 | { | - | ||||||||||||||||||||||||
46 | if (ocsp == NULL)
| 8-78 | ||||||||||||||||||||||||
47 | return; executed 78 times by 2 tests: return; Executed by:
| 78 | ||||||||||||||||||||||||
48 | - | |||||||||||||||||||||||||
49 | X509_free(ocsp->main_cert); | - | ||||||||||||||||||||||||
50 | free(ocsp->ocsp_result); | - | ||||||||||||||||||||||||
51 | free(ocsp->ocsp_url); | - | ||||||||||||||||||||||||
52 | - | |||||||||||||||||||||||||
53 | free(ocsp); | - | ||||||||||||||||||||||||
54 | } executed 8 times by 1 test: end of block Executed by:
| 8 | ||||||||||||||||||||||||
55 | - | |||||||||||||||||||||||||
56 | static int | - | ||||||||||||||||||||||||
57 | tls_ocsp_asn1_parse_time(struct tls *ctx, ASN1_GENERALIZEDTIME *gt, time_t *gt_time) | - | ||||||||||||||||||||||||
58 | { | - | ||||||||||||||||||||||||
59 | struct tm tm; | - | ||||||||||||||||||||||||
60 | - | |||||||||||||||||||||||||
61 | if (gt == NULL)
| 0 | ||||||||||||||||||||||||
62 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
63 | /* RFC 6960 specifies that all times in OCSP must be GENERALIZEDTIME */ | - | ||||||||||||||||||||||||
64 | if (ASN1_time_parse(gt->data, gt->length, &tm,
| 0 | ||||||||||||||||||||||||
65 | V_ASN1_GENERALIZEDTIME) == -1)
| 0 | ||||||||||||||||||||||||
66 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
67 | if ((*gt_time = timegm(&tm)) == -1)
| 0 | ||||||||||||||||||||||||
68 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
69 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
70 | } | - | ||||||||||||||||||||||||
71 | - | |||||||||||||||||||||||||
72 | static int | - | ||||||||||||||||||||||||
73 | tls_ocsp_fill_info(struct tls *ctx, int response_status, int cert_status, | - | ||||||||||||||||||||||||
74 | int crl_reason, ASN1_GENERALIZEDTIME *revtime, | - | ||||||||||||||||||||||||
75 | ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd) | - | ||||||||||||||||||||||||
76 | { | - | ||||||||||||||||||||||||
77 | struct tls_ocsp_result *info = NULL; | - | ||||||||||||||||||||||||
78 | - | |||||||||||||||||||||||||
79 | free(ctx->ocsp->ocsp_result); | - | ||||||||||||||||||||||||
80 | ctx->ocsp->ocsp_result = NULL; | - | ||||||||||||||||||||||||
81 | - | |||||||||||||||||||||||||
82 | if ((info = calloc(1, sizeof (struct tls_ocsp_result))) == NULL) {
| 0 | ||||||||||||||||||||||||
83 | tls_set_error(ctx, "calloc"); | - | ||||||||||||||||||||||||
84 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
85 | } | - | ||||||||||||||||||||||||
86 | info->response_status = response_status; | - | ||||||||||||||||||||||||
87 | info->cert_status = cert_status; | - | ||||||||||||||||||||||||
88 | info->crl_reason = crl_reason; | - | ||||||||||||||||||||||||
89 | if (info->response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
| 0 | ||||||||||||||||||||||||
90 | info->result_msg = | - | ||||||||||||||||||||||||
91 | OCSP_response_status_str(info->response_status); | - | ||||||||||||||||||||||||
92 | } else if (info->cert_status != V_OCSP_CERTSTATUS_REVOKED) { never executed: end of block
| 0 | ||||||||||||||||||||||||
93 | info->result_msg = OCSP_cert_status_str(info->cert_status); | - | ||||||||||||||||||||||||
94 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
95 | info->result_msg = OCSP_crl_reason_str(info->crl_reason); | - | ||||||||||||||||||||||||
96 | } never executed: end of block | 0 | ||||||||||||||||||||||||
97 | info->revocation_time = info->this_update = info->next_update = -1; | - | ||||||||||||||||||||||||
98 | if (revtime != NULL &&
| 0 | ||||||||||||||||||||||||
99 | tls_ocsp_asn1_parse_time(ctx, revtime, &info->revocation_time) != 0) {
| 0 | ||||||||||||||||||||||||
100 | tls_set_error(ctx, | - | ||||||||||||||||||||||||
101 | "unable to parse revocation time in OCSP reply"); | - | ||||||||||||||||||||||||
102 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
103 | } | - | ||||||||||||||||||||||||
104 | if (thisupd != NULL &&
| 0 | ||||||||||||||||||||||||
105 | tls_ocsp_asn1_parse_time(ctx, thisupd, &info->this_update) != 0) {
| 0 | ||||||||||||||||||||||||
106 | tls_set_error(ctx, | - | ||||||||||||||||||||||||
107 | "unable to parse this update time in OCSP reply"); | - | ||||||||||||||||||||||||
108 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
109 | } | - | ||||||||||||||||||||||||
110 | if (nextupd != NULL &&
| 0 | ||||||||||||||||||||||||
111 | tls_ocsp_asn1_parse_time(ctx, nextupd, &info->next_update) != 0) {
| 0 | ||||||||||||||||||||||||
112 | tls_set_error(ctx, | - | ||||||||||||||||||||||||
113 | "unable to parse next update time in OCSP reply"); | - | ||||||||||||||||||||||||
114 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
115 | } | - | ||||||||||||||||||||||||
116 | ctx->ocsp->ocsp_result = info; | - | ||||||||||||||||||||||||
117 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
118 | - | |||||||||||||||||||||||||
119 | err: | - | ||||||||||||||||||||||||
120 | free(info); | - | ||||||||||||||||||||||||
121 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
122 | } | - | ||||||||||||||||||||||||
123 | - | |||||||||||||||||||||||||
124 | static OCSP_CERTID * | - | ||||||||||||||||||||||||
125 | tls_ocsp_get_certid(X509 *main_cert, STACK_OF(X509) *extra_certs, | - | ||||||||||||||||||||||||
126 | SSL_CTX *ssl_ctx) | - | ||||||||||||||||||||||||
127 | { | - | ||||||||||||||||||||||||
128 | X509_NAME *issuer_name; | - | ||||||||||||||||||||||||
129 | X509 *issuer; | - | ||||||||||||||||||||||||
130 | X509_STORE_CTX storectx; | - | ||||||||||||||||||||||||
131 | X509_OBJECT tmpobj; | - | ||||||||||||||||||||||||
132 | OCSP_CERTID *cid = NULL; | - | ||||||||||||||||||||||||
133 | X509_STORE *store; | - | ||||||||||||||||||||||||
134 | - | |||||||||||||||||||||||||
135 | if ((issuer_name = X509_get_issuer_name(main_cert)) == NULL)
| 0 | ||||||||||||||||||||||||
136 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
137 | - | |||||||||||||||||||||||||
138 | if (extra_certs != NULL) {
| 0 | ||||||||||||||||||||||||
139 | issuer = X509_find_by_subject(extra_certs, issuer_name); | - | ||||||||||||||||||||||||
140 | if (issuer != NULL)
| 0 | ||||||||||||||||||||||||
141 | return OCSP_cert_to_id(NULL, main_cert, issuer); never executed: return OCSP_cert_to_id( ((void *)0) , main_cert, issuer); | 0 | ||||||||||||||||||||||||
142 | } never executed: end of block | 0 | ||||||||||||||||||||||||
143 | - | |||||||||||||||||||||||||
144 | if ((store = SSL_CTX_get_cert_store(ssl_ctx)) == NULL)
| 0 | ||||||||||||||||||||||||
145 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
146 | if (X509_STORE_CTX_init(&storectx, store, main_cert, extra_certs) != 1)
| 0 | ||||||||||||||||||||||||
147 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
148 | if (X509_STORE_get_by_subject(&storectx, X509_LU_X509, issuer_name,
| 0 | ||||||||||||||||||||||||
149 | &tmpobj) == 1) {
| 0 | ||||||||||||||||||||||||
150 | cid = OCSP_cert_to_id(NULL, main_cert, tmpobj.data.x509); | - | ||||||||||||||||||||||||
151 | X509_OBJECT_free_contents(&tmpobj); | - | ||||||||||||||||||||||||
152 | } never executed: end of block | 0 | ||||||||||||||||||||||||
153 | X509_STORE_CTX_cleanup(&storectx); | - | ||||||||||||||||||||||||
154 | return cid; never executed: return cid; | 0 | ||||||||||||||||||||||||
155 | } | - | ||||||||||||||||||||||||
156 | - | |||||||||||||||||||||||||
157 | struct tls_ocsp * | - | ||||||||||||||||||||||||
158 | tls_ocsp_setup_from_peer(struct tls *ctx) | - | ||||||||||||||||||||||||
159 | { | - | ||||||||||||||||||||||||
160 | struct tls_ocsp *ocsp = NULL; | - | ||||||||||||||||||||||||
161 | STACK_OF(OPENSSL_STRING) *ocsp_urls = NULL; | - | ||||||||||||||||||||||||
162 | - | |||||||||||||||||||||||||
163 | if ((ocsp = tls_ocsp_new()) == NULL)
| 0-8 | ||||||||||||||||||||||||
164 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
165 | - | |||||||||||||||||||||||||
166 | /* steal state from ctx struct */ | - | ||||||||||||||||||||||||
167 | ocsp->main_cert = SSL_get_peer_certificate(ctx->ssl_conn); | - | ||||||||||||||||||||||||
168 | ocsp->extra_certs = SSL_get_peer_cert_chain(ctx->ssl_conn); | - | ||||||||||||||||||||||||
169 | if (ocsp->main_cert == NULL) {
| 4 | ||||||||||||||||||||||||
170 | tls_set_errorx(ctx, "no peer certificate for OCSP"); | - | ||||||||||||||||||||||||
171 | goto err; executed 4 times by 1 test: goto err; Executed by:
| 4 | ||||||||||||||||||||||||
172 | } | - | ||||||||||||||||||||||||
173 | - | |||||||||||||||||||||||||
174 | ocsp_urls = X509_get1_ocsp(ocsp->main_cert); | - | ||||||||||||||||||||||||
175 | if (ocsp_urls == NULL) {
| 0-4 | ||||||||||||||||||||||||
176 | tls_set_errorx(ctx, "no OCSP URLs in peer certificate"); | - | ||||||||||||||||||||||||
177 | goto err; executed 4 times by 1 test: goto err; Executed by:
| 4 | ||||||||||||||||||||||||
178 | } | - | ||||||||||||||||||||||||
179 | - | |||||||||||||||||||||||||
180 | ocsp->ocsp_url = strdup(sk_OPENSSL_STRING_value(ocsp_urls, 0)); never executed: __retval = (char *) memcpy (__retval, ((OPENSSL_STRING)sk_value(((_STACK*) (1 ? ocsp_urls : (struct stack_st_OPENSSL_STRING*)0)), 0)) , __len);
| 0 | ||||||||||||||||||||||||
181 | if (ocsp->ocsp_url == NULL) {
| 0 | ||||||||||||||||||||||||
182 | tls_set_errorx(ctx, "out of memory"); | - | ||||||||||||||||||||||||
183 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
184 | } | - | ||||||||||||||||||||||||
185 | - | |||||||||||||||||||||||||
186 | X509_email_free(ocsp_urls); | - | ||||||||||||||||||||||||
187 | return ocsp; never executed: return ocsp; | 0 | ||||||||||||||||||||||||
188 | - | |||||||||||||||||||||||||
189 | err: | - | ||||||||||||||||||||||||
190 | tls_ocsp_free(ocsp); | - | ||||||||||||||||||||||||
191 | X509_email_free(ocsp_urls); | - | ||||||||||||||||||||||||
192 | return NULL; executed 8 times by 1 test: return ((void *)0) ; Executed by:
| 8 | ||||||||||||||||||||||||
193 | } | - | ||||||||||||||||||||||||
194 | - | |||||||||||||||||||||||||
195 | static int | - | ||||||||||||||||||||||||
196 | tls_ocsp_verify_response(struct tls *ctx, OCSP_RESPONSE *resp) | - | ||||||||||||||||||||||||
197 | { | - | ||||||||||||||||||||||||
198 | OCSP_BASICRESP *br = NULL; | - | ||||||||||||||||||||||||
199 | ASN1_GENERALIZEDTIME *revtime = NULL, *thisupd = NULL, *nextupd = NULL; | - | ||||||||||||||||||||||||
200 | OCSP_CERTID *cid = NULL; | - | ||||||||||||||||||||||||
201 | STACK_OF(X509) *combined = NULL; | - | ||||||||||||||||||||||||
202 | int response_status=0, cert_status=0, crl_reason=0; | - | ||||||||||||||||||||||||
203 | int ret = -1; | - | ||||||||||||||||||||||||
204 | unsigned long flags; | - | ||||||||||||||||||||||||
205 | - | |||||||||||||||||||||||||
206 | if ((br = OCSP_response_get1_basic(resp)) == NULL) {
| 0 | ||||||||||||||||||||||||
207 | tls_set_errorx(ctx, "cannot load ocsp reply"); | - | ||||||||||||||||||||||||
208 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
209 | } | - | ||||||||||||||||||||||||
210 | - | |||||||||||||||||||||||||
211 | /* | - | ||||||||||||||||||||||||
212 | * Skip validation of 'extra_certs' as this should be done | - | ||||||||||||||||||||||||
213 | * already as part of main handshake. | - | ||||||||||||||||||||||||
214 | */ | - | ||||||||||||||||||||||||
215 | flags = OCSP_TRUSTOTHER; | - | ||||||||||||||||||||||||
216 | - | |||||||||||||||||||||||||
217 | /* now verify */ | - | ||||||||||||||||||||||||
218 | if (OCSP_basic_verify(br, ctx->ocsp->extra_certs,
| 0 | ||||||||||||||||||||||||
219 | SSL_CTX_get_cert_store(ctx->ssl_ctx), flags) != 1) {
| 0 | ||||||||||||||||||||||||
220 | tls_set_error(ctx, "ocsp verify failed"); | - | ||||||||||||||||||||||||
221 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
222 | } | - | ||||||||||||||||||||||||
223 | - | |||||||||||||||||||||||||
224 | /* signature OK, look inside */ | - | ||||||||||||||||||||||||
225 | response_status = OCSP_response_status(resp); | - | ||||||||||||||||||||||||
226 | if (response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
| 0 | ||||||||||||||||||||||||
227 | tls_set_errorx(ctx, "ocsp verify failed: response - %s", | - | ||||||||||||||||||||||||
228 | OCSP_response_status_str(response_status)); | - | ||||||||||||||||||||||||
229 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
230 | } | - | ||||||||||||||||||||||||
231 | - | |||||||||||||||||||||||||
232 | cid = tls_ocsp_get_certid(ctx->ocsp->main_cert, | - | ||||||||||||||||||||||||
233 | ctx->ocsp->extra_certs, ctx->ssl_ctx); | - | ||||||||||||||||||||||||
234 | if (cid == NULL) {
| 0 | ||||||||||||||||||||||||
235 | tls_set_errorx(ctx, "ocsp verify failed: no issuer cert"); | - | ||||||||||||||||||||||||
236 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
237 | } | - | ||||||||||||||||||||||||
238 | - | |||||||||||||||||||||||||
239 | if (OCSP_resp_find_status(br, cid, &cert_status, &crl_reason,
| 0 | ||||||||||||||||||||||||
240 | &revtime, &thisupd, &nextupd) != 1) {
| 0 | ||||||||||||||||||||||||
241 | tls_set_errorx(ctx, "ocsp verify failed: no result for cert"); | - | ||||||||||||||||||||||||
242 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
243 | } | - | ||||||||||||||||||||||||
244 | - | |||||||||||||||||||||||||
245 | if (OCSP_check_validity(thisupd, nextupd, JITTER_SEC,
| 0 | ||||||||||||||||||||||||
246 | MAXAGE_SEC) != 1) {
| 0 | ||||||||||||||||||||||||
247 | tls_set_errorx(ctx, | - | ||||||||||||||||||||||||
248 | "ocsp verify failed: ocsp response not current"); | - | ||||||||||||||||||||||||
249 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
250 | } | - | ||||||||||||||||||||||||
251 | - | |||||||||||||||||||||||||
252 | if (tls_ocsp_fill_info(ctx, response_status, cert_status,
| 0 | ||||||||||||||||||||||||
253 | crl_reason, revtime, thisupd, nextupd) != 0)
| 0 | ||||||||||||||||||||||||
254 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
255 | - | |||||||||||||||||||||||||
256 | /* finally can look at status */ | - | ||||||||||||||||||||||||
257 | if (cert_status != V_OCSP_CERTSTATUS_GOOD && cert_status !=
| 0 | ||||||||||||||||||||||||
258 | V_OCSP_CERTSTATUS_UNKNOWN) {
| 0 | ||||||||||||||||||||||||
259 | tls_set_errorx(ctx, "ocsp verify failed: revoked cert - %s", | - | ||||||||||||||||||||||||
260 | OCSP_crl_reason_str(crl_reason)); | - | ||||||||||||||||||||||||
261 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
262 | } | - | ||||||||||||||||||||||||
263 | ret = 0; | - | ||||||||||||||||||||||||
264 | - | |||||||||||||||||||||||||
265 | err: code before this statement never executed: err: | 0 | ||||||||||||||||||||||||
266 | sk_X509_free(combined); | - | ||||||||||||||||||||||||
267 | OCSP_CERTID_free(cid); | - | ||||||||||||||||||||||||
268 | OCSP_BASICRESP_free(br); | - | ||||||||||||||||||||||||
269 | return ret; never executed: return ret; | 0 | ||||||||||||||||||||||||
270 | } | - | ||||||||||||||||||||||||
271 | - | |||||||||||||||||||||||||
272 | /* | - | ||||||||||||||||||||||||
273 | * Process a raw OCSP response from an OCSP server request. | - | ||||||||||||||||||||||||
274 | * OCSP details can then be retrieved with tls_peer_ocsp_* functions. | - | ||||||||||||||||||||||||
275 | * returns 0 if certificate ok, -1 otherwise. | - | ||||||||||||||||||||||||
276 | */ | - | ||||||||||||||||||||||||
277 | static int | - | ||||||||||||||||||||||||
278 | tls_ocsp_process_response_internal(struct tls *ctx, const unsigned char *response, | - | ||||||||||||||||||||||||
279 | size_t size) | - | ||||||||||||||||||||||||
280 | { | - | ||||||||||||||||||||||||
281 | int ret; | - | ||||||||||||||||||||||||
282 | OCSP_RESPONSE *resp; | - | ||||||||||||||||||||||||
283 | - | |||||||||||||||||||||||||
284 | resp = d2i_OCSP_RESPONSE(NULL, &response, size); | - | ||||||||||||||||||||||||
285 | if (resp == NULL) {
| 0 | ||||||||||||||||||||||||
286 | tls_ocsp_free(ctx->ocsp); | - | ||||||||||||||||||||||||
287 | ctx->ocsp = NULL; | - | ||||||||||||||||||||||||
288 | tls_set_error(ctx, "unable to parse OCSP response"); | - | ||||||||||||||||||||||||
289 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
290 | } | - | ||||||||||||||||||||||||
291 | ret = tls_ocsp_verify_response(ctx, resp); | - | ||||||||||||||||||||||||
292 | OCSP_RESPONSE_free(resp); | - | ||||||||||||||||||||||||
293 | return ret; never executed: return ret; | 0 | ||||||||||||||||||||||||
294 | } | - | ||||||||||||||||||||||||
295 | - | |||||||||||||||||||||||||
296 | /* TLS handshake verification callback for stapled requests */ | - | ||||||||||||||||||||||||
297 | int | - | ||||||||||||||||||||||||
298 | tls_ocsp_verify_cb(SSL *ssl, void *arg) | - | ||||||||||||||||||||||||
299 | { | - | ||||||||||||||||||||||||
300 | const unsigned char *raw = NULL; | - | ||||||||||||||||||||||||
301 | int size, res = -1; | - | ||||||||||||||||||||||||
302 | struct tls *ctx; | - | ||||||||||||||||||||||||
303 | - | |||||||||||||||||||||||||
304 | if ((ctx = SSL_get_app_data(ssl)) == NULL)
| 0-4 | ||||||||||||||||||||||||
305 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
306 | - | |||||||||||||||||||||||||
307 | size = SSL_get_tlsext_status_ocsp_resp(ssl, &raw); | - | ||||||||||||||||||||||||
308 | if (size <= 0) {
| 0-4 | ||||||||||||||||||||||||
309 | if (ctx->config->ocsp_require_stapling) {
| 0-4 | ||||||||||||||||||||||||
310 | tls_set_errorx(ctx, "no stapled OCSP response provided"); | - | ||||||||||||||||||||||||
311 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
312 | } | - | ||||||||||||||||||||||||
313 | return 1; executed 4 times by 1 test: return 1; Executed by:
| 4 | ||||||||||||||||||||||||
314 | } | - | ||||||||||||||||||||||||
315 | - | |||||||||||||||||||||||||
316 | tls_ocsp_free(ctx->ocsp); | - | ||||||||||||||||||||||||
317 | if ((ctx->ocsp = tls_ocsp_setup_from_peer(ctx)) == NULL)
| 0 | ||||||||||||||||||||||||
318 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
319 | - | |||||||||||||||||||||||||
320 | if (ctx->config->verify_cert == 0 || ctx->config->verify_time == 0)
| 0 | ||||||||||||||||||||||||
321 | return 1; never executed: return 1; | 0 | ||||||||||||||||||||||||
322 | - | |||||||||||||||||||||||||
323 | res = tls_ocsp_process_response_internal(ctx, raw, size); | - | ||||||||||||||||||||||||
324 | - | |||||||||||||||||||||||||
325 | return (res == 0) ? 1 : 0; never executed: return (res == 0) ? 1 : 0;
| 0 | ||||||||||||||||||||||||
326 | } | - | ||||||||||||||||||||||||
327 | - | |||||||||||||||||||||||||
328 | - | |||||||||||||||||||||||||
329 | /* Staple the OCSP information in ctx->ocsp to the server handshake. */ | - | ||||||||||||||||||||||||
330 | int | - | ||||||||||||||||||||||||
331 | tls_ocsp_stapling_cb(SSL *ssl, void *arg) | - | ||||||||||||||||||||||||
332 | { | - | ||||||||||||||||||||||||
333 | int ret = SSL_TLSEXT_ERR_ALERT_FATAL; | - | ||||||||||||||||||||||||
334 | unsigned char *ocsp_staple = NULL; | - | ||||||||||||||||||||||||
335 | struct tls *ctx; | - | ||||||||||||||||||||||||
336 | - | |||||||||||||||||||||||||
337 | if ((ctx = SSL_get_app_data(ssl)) == NULL)
| 0-4 | ||||||||||||||||||||||||
338 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
339 | - | |||||||||||||||||||||||||
340 | if (ctx->keypair == NULL || ctx->keypair->ocsp_staple == NULL ||
| 0-4 | ||||||||||||||||||||||||
341 | ctx->keypair->ocsp_staple_len == 0)
| 0 | ||||||||||||||||||||||||
342 | return SSL_TLSEXT_ERR_NOACK; executed 4 times by 1 test: return 3; Executed by:
| 4 | ||||||||||||||||||||||||
343 | - | |||||||||||||||||||||||||
344 | if ((ocsp_staple = malloc(ctx->keypair->ocsp_staple_len)) == NULL)
| 0 | ||||||||||||||||||||||||
345 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
346 | - | |||||||||||||||||||||||||
347 | memcpy(ocsp_staple, ctx->keypair->ocsp_staple, | - | ||||||||||||||||||||||||
348 | ctx->keypair->ocsp_staple_len); | - | ||||||||||||||||||||||||
349 | - | |||||||||||||||||||||||||
350 | if (SSL_set_tlsext_status_ocsp_resp(ctx->ssl_conn, ocsp_staple,
| 0 | ||||||||||||||||||||||||
351 | ctx->keypair->ocsp_staple_len) != 1)
| 0 | ||||||||||||||||||||||||
352 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
353 | - | |||||||||||||||||||||||||
354 | ret = SSL_TLSEXT_ERR_OK; | - | ||||||||||||||||||||||||
355 | err: code before this statement never executed: err: | 0 | ||||||||||||||||||||||||
356 | if (ret != SSL_TLSEXT_ERR_OK)
| 0 | ||||||||||||||||||||||||
357 | free(ocsp_staple); never executed: free(ocsp_staple); | 0 | ||||||||||||||||||||||||
358 | - | |||||||||||||||||||||||||
359 | return ret; never executed: return ret; | 0 | ||||||||||||||||||||||||
360 | } | - | ||||||||||||||||||||||||
361 | - | |||||||||||||||||||||||||
362 | /* | - | ||||||||||||||||||||||||
363 | * Public API | - | ||||||||||||||||||||||||
364 | */ | - | ||||||||||||||||||||||||
365 | - | |||||||||||||||||||||||||
366 | /* Retrieve OCSP URL from peer certificate, if present. */ | - | ||||||||||||||||||||||||
367 | const char * | - | ||||||||||||||||||||||||
368 | tls_peer_ocsp_url(struct tls *ctx) | - | ||||||||||||||||||||||||
369 | { | - | ||||||||||||||||||||||||
370 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
371 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
372 | return ctx->ocsp->ocsp_url; never executed: return ctx->ocsp->ocsp_url; | 0 | ||||||||||||||||||||||||
373 | } | - | ||||||||||||||||||||||||
374 | - | |||||||||||||||||||||||||
375 | const char * | - | ||||||||||||||||||||||||
376 | tls_peer_ocsp_result(struct tls *ctx) | - | ||||||||||||||||||||||||
377 | { | - | ||||||||||||||||||||||||
378 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
379 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
380 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
381 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
382 | return ctx->ocsp->ocsp_result->result_msg; never executed: return ctx->ocsp->ocsp_result->result_msg; | 0 | ||||||||||||||||||||||||
383 | } | - | ||||||||||||||||||||||||
384 | - | |||||||||||||||||||||||||
385 | int | - | ||||||||||||||||||||||||
386 | tls_peer_ocsp_response_status(struct tls *ctx) | - | ||||||||||||||||||||||||
387 | { | - | ||||||||||||||||||||||||
388 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
389 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
390 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
391 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
392 | return ctx->ocsp->ocsp_result->response_status; never executed: return ctx->ocsp->ocsp_result->response_status; | 0 | ||||||||||||||||||||||||
393 | } | - | ||||||||||||||||||||||||
394 | - | |||||||||||||||||||||||||
395 | int | - | ||||||||||||||||||||||||
396 | tls_peer_ocsp_cert_status(struct tls *ctx) | - | ||||||||||||||||||||||||
397 | { | - | ||||||||||||||||||||||||
398 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
399 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
400 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
401 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
402 | return ctx->ocsp->ocsp_result->cert_status; never executed: return ctx->ocsp->ocsp_result->cert_status; | 0 | ||||||||||||||||||||||||
403 | } | - | ||||||||||||||||||||||||
404 | - | |||||||||||||||||||||||||
405 | int | - | ||||||||||||||||||||||||
406 | tls_peer_ocsp_crl_reason(struct tls *ctx) | - | ||||||||||||||||||||||||
407 | { | - | ||||||||||||||||||||||||
408 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
409 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
410 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
411 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
412 | return ctx->ocsp->ocsp_result->crl_reason; never executed: return ctx->ocsp->ocsp_result->crl_reason; | 0 | ||||||||||||||||||||||||
413 | } | - | ||||||||||||||||||||||||
414 | - | |||||||||||||||||||||||||
415 | time_t | - | ||||||||||||||||||||||||
416 | tls_peer_ocsp_this_update(struct tls *ctx) | - | ||||||||||||||||||||||||
417 | { | - | ||||||||||||||||||||||||
418 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
419 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
420 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
421 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
422 | return ctx->ocsp->ocsp_result->this_update; never executed: return ctx->ocsp->ocsp_result->this_update; | 0 | ||||||||||||||||||||||||
423 | } | - | ||||||||||||||||||||||||
424 | - | |||||||||||||||||||||||||
425 | time_t | - | ||||||||||||||||||||||||
426 | tls_peer_ocsp_next_update(struct tls *ctx) | - | ||||||||||||||||||||||||
427 | { | - | ||||||||||||||||||||||||
428 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
429 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
430 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
431 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
432 | return ctx->ocsp->ocsp_result->next_update; never executed: return ctx->ocsp->ocsp_result->next_update; | 0 | ||||||||||||||||||||||||
433 | } | - | ||||||||||||||||||||||||
434 | - | |||||||||||||||||||||||||
435 | time_t | - | ||||||||||||||||||||||||
436 | tls_peer_ocsp_revocation_time(struct tls *ctx) | - | ||||||||||||||||||||||||
437 | { | - | ||||||||||||||||||||||||
438 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
439 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
440 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
441 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
442 | return ctx->ocsp->ocsp_result->revocation_time; never executed: return ctx->ocsp->ocsp_result->revocation_time; | 0 | ||||||||||||||||||||||||
443 | } | - | ||||||||||||||||||||||||
444 | - | |||||||||||||||||||||||||
445 | int | - | ||||||||||||||||||||||||
446 | tls_ocsp_process_response(struct tls *ctx, const unsigned char *response, | - | ||||||||||||||||||||||||
447 | size_t size) | - | ||||||||||||||||||||||||
448 | { | - | ||||||||||||||||||||||||
449 | if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0)
| 0 | ||||||||||||||||||||||||
450 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
451 | return tls_ocsp_process_response_internal(ctx, response, size); never executed: return tls_ocsp_process_response_internal(ctx, response, size); | 0 | ||||||||||||||||||||||||
452 | } | - | ||||||||||||||||||||||||
Source code | Switch to Preprocessed file |