1 /*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2
13 * as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
25 /**
26 * @file Control Channel Verification Module OpenSSL implementation
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #elif defined(_MSC_VER)
32 #include "config-msvc.h"
33 #endif
34
35 #include "syshead.h"
36
37 #if defined(ENABLE_CRYPTO_OPENSSL)
38
39 #include "ssl_verify_openssl.h"
40
41 #include "error.h"
42 #include "ssl_openssl.h"
43 #include "ssl_verify.h"
44 #include "ssl_verify_backend.h"
45 #include "openssl_compat.h"
46
47 #include <openssl/bn.h>
48 #include <openssl/err.h>
49 #include <openssl/x509v3.h>
50
51 int
verify_callback(int preverify_ok,X509_STORE_CTX * ctx)52 verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
53 {
54 int ret = 0;
55 struct tls_session *session;
56 SSL *ssl;
57 struct gc_arena gc = gc_new();
58
59 /* get the tls_session pointer */
60 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
61 ASSERT(ssl);
62 session = (struct tls_session *) SSL_get_ex_data(ssl, mydata_index);
63 ASSERT(session);
64
65 X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
66 struct buffer cert_hash = x509_get_sha256_fingerprint(current_cert, &gc);
67 cert_hash_remember(session, X509_STORE_CTX_get_error_depth(ctx), &cert_hash);
68
69 /* did peer present cert which was signed by our root cert? */
70 if (!preverify_ok && !session->opt->verify_hash_no_ca)
71 {
72 /* get the X509 name */
73 char *subject = x509_get_subject(current_cert, &gc);
74 char *serial = backend_x509_get_serial(current_cert, &gc);
75
76 if (!subject)
77 {
78 subject = "(Failed to retrieve certificate subject)";
79 }
80
81 /* Log and ignore missing CRL errors */
82 if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL)
83 {
84 msg(D_TLS_DEBUG_LOW, "VERIFY WARNING: depth=%d, %s: %s",
85 X509_STORE_CTX_get_error_depth(ctx),
86 X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)),
87 subject);
88 ret = 1;
89 goto cleanup;
90 }
91
92 /* Remote site specified a certificate, but it's not correct */
93 msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, error=%s: %s, serial=%s",
94 X509_STORE_CTX_get_error_depth(ctx),
95 X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)),
96 subject, serial ? serial : "<not available>");
97
98 ERR_clear_error();
99
100 session->verified = false;
101 goto cleanup;
102 }
103
104 if (SUCCESS != verify_cert(session, current_cert, X509_STORE_CTX_get_error_depth(ctx)))
105 {
106 goto cleanup;
107 }
108
109 ret = 1;
110
111 cleanup:
112 gc_free(&gc);
113
114 return ret;
115 }
116
117 #ifdef ENABLE_X509ALTUSERNAME
118 bool
x509_username_field_ext_supported(const char * fieldname)119 x509_username_field_ext_supported(const char *fieldname)
120 {
121 int nid = OBJ_txt2nid(fieldname);
122 return nid == NID_subject_alt_name || nid == NID_issuer_alt_name;
123 }
124
125 static
126 bool
extract_x509_extension(X509 * cert,char * fieldname,char * out,int size)127 extract_x509_extension(X509 *cert, char *fieldname, char *out, int size)
128 {
129 bool retval = false;
130 char *buf = 0;
131
132 if (!x509_username_field_ext_supported(fieldname))
133 {
134 msg(D_TLS_ERRORS,
135 "ERROR: --x509-username-field 'ext:%s' not supported", fieldname);
136 return false;
137 }
138
139 int nid = OBJ_txt2nid(fieldname);
140 GENERAL_NAMES *extensions = X509_get_ext_d2i(cert, nid, NULL, NULL);
141 if (extensions)
142 {
143 int numalts;
144 int i;
145 /* get amount of alternatives,
146 * RFC2459 claims there MUST be at least
147 * one, but we don't depend on it...
148 */
149
150 numalts = sk_GENERAL_NAME_num(extensions);
151
152 /* loop through all alternatives */
153 for (i = 0; i<numalts; i++)
154 {
155 /* get a handle to alternative name number i */
156 const GENERAL_NAME *name = sk_GENERAL_NAME_value(extensions, i );
157
158 switch (name->type)
159 {
160 case GEN_EMAIL:
161 if (ASN1_STRING_to_UTF8((unsigned char **)&buf, name->d.ia5) < 0)
162 {
163 continue;
164 }
165 if (strlen(buf) != name->d.ia5->length)
166 {
167 msg(D_TLS_ERRORS, "ASN1 ERROR: string contained terminating zero");
168 OPENSSL_free(buf);
169 }
170 else
171 {
172 strncpynt(out, buf, size);
173 OPENSSL_free(buf);
174 retval = true;
175 }
176 break;
177
178 default:
179 msg(D_TLS_DEBUG, "%s: ignoring general name field type %i",
180 __func__, name->type);
181 break;
182 }
183 }
184 GENERAL_NAMES_free(extensions);
185 }
186 return retval;
187 }
188 #endif /* ENABLE_X509ALTUSERNAME */
189
190 /*
191 * Extract a field from an X509 subject name.
192 *
193 * Example:
194 *
195 * /C=US/ST=CO/L=Denver/O=ORG/CN=First-CN/CN=Test-CA/Email=jim@yonan.net
196 *
197 * The common name is 'Test-CA'
198 *
199 * Return true on success, false on error (insufficient buffer size in 'out'
200 * to contain result is grounds for error).
201 */
202 static result_t
extract_x509_field_ssl(X509_NAME * x509,const char * field_name,char * out,int size)203 extract_x509_field_ssl(X509_NAME *x509, const char *field_name, char *out,
204 int size)
205 {
206 int lastpos = -1;
207 int tmp = -1;
208 X509_NAME_ENTRY *x509ne = NULL;
209 ASN1_STRING *asn1 = NULL;
210 unsigned char *buf = NULL;
211 ASN1_OBJECT *field_name_obj = OBJ_txt2obj(field_name, 0);
212
213 if (field_name_obj == NULL)
214 {
215 msg(D_TLS_ERRORS, "Invalid X509 attribute name '%s'", field_name);
216 return FAILURE;
217 }
218
219 ASSERT(size > 0);
220 *out = '\0';
221 do
222 {
223 lastpos = tmp;
224 tmp = X509_NAME_get_index_by_OBJ(x509, field_name_obj, lastpos);
225 } while (tmp > -1);
226
227 ASN1_OBJECT_free(field_name_obj);
228
229 /* Nothing found */
230 if (lastpos == -1)
231 {
232 return FAILURE;
233 }
234
235 x509ne = X509_NAME_get_entry(x509, lastpos);
236 if (!x509ne)
237 {
238 return FAILURE;
239 }
240
241 asn1 = X509_NAME_ENTRY_get_data(x509ne);
242 if (!asn1)
243 {
244 return FAILURE;
245 }
246 if (ASN1_STRING_to_UTF8(&buf, asn1) < 0)
247 {
248 return FAILURE;
249 }
250
251 strncpynt(out, (char *)buf, size);
252
253 {
254 const result_t ret = (strlen((char *)buf) < size) ? SUCCESS : FAILURE;
255 OPENSSL_free(buf);
256 return ret;
257 }
258 }
259
260 result_t
backend_x509_get_username(char * common_name,int cn_len,char * x509_username_field,X509 * peer_cert)261 backend_x509_get_username(char *common_name, int cn_len,
262 char *x509_username_field, X509 *peer_cert)
263 {
264 #ifdef ENABLE_X509ALTUSERNAME
265 if (strncmp("ext:",x509_username_field,4) == 0)
266 {
267 if (!extract_x509_extension(peer_cert, x509_username_field+4, common_name, cn_len))
268 {
269 return FAILURE;
270 }
271 }
272 else if (strcmp(LN_serialNumber, x509_username_field) == 0)
273 {
274 ASN1_INTEGER *asn1_i = X509_get_serialNumber(peer_cert);
275 struct gc_arena gc = gc_new();
276 char *serial = format_hex_ex(asn1_i->data, asn1_i->length,
277 0, 1 | FHE_CAPS, NULL, &gc);
278
279 if (!serial || cn_len <= strlen(serial)+2)
280 {
281 gc_free(&gc);
282 return FAILURE;
283 }
284 openvpn_snprintf(common_name, cn_len, "0x%s", serial);
285 gc_free(&gc);
286 }
287 else
288 #endif
289 if (FAILURE == extract_x509_field_ssl(X509_get_subject_name(peer_cert),
290 x509_username_field, common_name, cn_len))
291 {
292 return FAILURE;
293 }
294
295 return SUCCESS;
296 }
297
298 char *
backend_x509_get_serial(openvpn_x509_cert_t * cert,struct gc_arena * gc)299 backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
300 {
301 ASN1_INTEGER *asn1_i;
302 BIGNUM *bignum;
303 char *openssl_serial, *serial;
304
305 asn1_i = X509_get_serialNumber(cert);
306 bignum = ASN1_INTEGER_to_BN(asn1_i, NULL);
307 openssl_serial = BN_bn2dec(bignum);
308
309 serial = string_alloc(openssl_serial, gc);
310
311 BN_free(bignum);
312 OPENSSL_free(openssl_serial);
313
314 return serial;
315 }
316
317 char *
backend_x509_get_serial_hex(openvpn_x509_cert_t * cert,struct gc_arena * gc)318 backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc)
319 {
320 const ASN1_INTEGER *asn1_i = X509_get_serialNumber(cert);
321
322 return format_hex_ex(asn1_i->data, asn1_i->length, 0, 1, ":", gc);
323 }
324
325 struct buffer
x509_get_sha1_fingerprint(X509 * cert,struct gc_arena * gc)326 x509_get_sha1_fingerprint(X509 *cert, struct gc_arena *gc)
327 {
328 const EVP_MD *sha1 = EVP_sha1();
329 struct buffer hash = alloc_buf_gc(EVP_MD_size(sha1), gc);
330 X509_digest(cert, EVP_sha1(), BPTR(&hash), NULL);
331 ASSERT(buf_inc_len(&hash, EVP_MD_size(sha1)));
332 return hash;
333 }
334
335 struct buffer
x509_get_sha256_fingerprint(X509 * cert,struct gc_arena * gc)336 x509_get_sha256_fingerprint(X509 *cert, struct gc_arena *gc)
337 {
338 const EVP_MD *sha256 = EVP_sha256();
339 struct buffer hash = alloc_buf_gc(EVP_MD_size(sha256), gc);
340 X509_digest(cert, EVP_sha256(), BPTR(&hash), NULL);
341 ASSERT(buf_inc_len(&hash, EVP_MD_size(sha256)));
342 return hash;
343 }
344
345 char *
x509_get_subject(X509 * cert,struct gc_arena * gc)346 x509_get_subject(X509 *cert, struct gc_arena *gc)
347 {
348 BIO *subject_bio = NULL;
349 BUF_MEM *subject_mem;
350 char *subject = NULL;
351
352 subject_bio = BIO_new(BIO_s_mem());
353 if (subject_bio == NULL)
354 {
355 goto err;
356 }
357
358 X509_NAME_print_ex(subject_bio, X509_get_subject_name(cert),
359 0, XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN
360 |ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_ESC_CTRL);
361
362 if (BIO_eof(subject_bio))
363 {
364 goto err;
365 }
366
367 BIO_get_mem_ptr(subject_bio, &subject_mem);
368
369 subject = gc_malloc(subject_mem->length + 1, false, gc);
370
371 memcpy(subject, subject_mem->data, subject_mem->length);
372 subject[subject_mem->length] = '\0';
373
374 err:
375 BIO_free(subject_bio);
376 return subject;
377 }
378
379
380 /*
381 * x509-track implementation -- save X509 fields to environment,
382 * using the naming convention:
383 *
384 * X509_{cert_depth}_{name}={value}
385 *
386 * This function differs from x509_setenv below in the following ways:
387 *
388 * (1) Only explicitly named attributes in xt are saved, per usage
389 * of "x509-track" program options.
390 * (2) Only the level 0 cert info is saved unless the XT_FULL_CHAIN
391 * flag is set in xt->flags (corresponds with prepending a '+'
392 * to the name when specified by "x509-track" program option).
393 * (3) This function supports both X509 subject name fields as
394 * well as X509 V3 extensions.
395 * (4) This function can return the SHA1 fingerprint of a cert, e.g.
396 * x509-track "+SHA1"
397 * will return the SHA1 fingerprint for each certificate in the
398 * peer chain.
399 */
400
401 void
x509_track_add(const struct x509_track ** ll_head,const char * name,int msglevel,struct gc_arena * gc)402 x509_track_add(const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc)
403 {
404 struct x509_track *xt;
405 ALLOC_OBJ_CLEAR_GC(xt, struct x509_track, gc);
406 if (*name == '+')
407 {
408 xt->flags |= XT_FULL_CHAIN;
409 ++name;
410 }
411 xt->name = name;
412 xt->nid = OBJ_txt2nid(name);
413 if (xt->nid != NID_undef)
414 {
415 xt->next = *ll_head;
416 *ll_head = xt;
417 }
418 else
419 {
420 msg(msglevel, "x509_track: no such attribute '%s'", name);
421 }
422 }
423
424 /* worker method for setenv_x509_track */
425 static void
do_setenv_x509(struct env_set * es,const char * name,char * value,int depth)426 do_setenv_x509(struct env_set *es, const char *name, char *value, int depth)
427 {
428 char *name_expand;
429 size_t name_expand_size;
430
431 string_mod(value, CC_ANY, CC_CRLF, '?');
432 msg(D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth);
433 name_expand_size = 64 + strlen(name);
434 name_expand = (char *) malloc(name_expand_size);
435 check_malloc_return(name_expand);
436 openvpn_snprintf(name_expand, name_expand_size, "X509_%d_%s", depth, name);
437 setenv_str(es, name_expand, value);
438 free(name_expand);
439 }
440
441 void
x509_setenv_track(const struct x509_track * xt,struct env_set * es,const int depth,X509 * x509)442 x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, X509 *x509)
443 {
444 struct gc_arena gc = gc_new();
445 X509_NAME *x509_name = X509_get_subject_name(x509);
446 const char nullc = '\0';
447
448 while (xt)
449 {
450 if (depth == 0 || (xt->flags & XT_FULL_CHAIN))
451 {
452 switch (xt->nid)
453 {
454 case NID_sha1:
455 case NID_sha256:
456 {
457 struct buffer fp_buf;
458 char *fp_str = NULL;
459
460 if (xt->nid == NID_sha1)
461 {
462 fp_buf = x509_get_sha1_fingerprint(x509, &gc);
463 }
464 else
465 {
466 fp_buf = x509_get_sha256_fingerprint(x509, &gc);
467 }
468
469 fp_str = format_hex_ex(BPTR(&fp_buf), BLEN(&fp_buf), 0,
470 1 | FHE_CAPS, ":", &gc);
471 do_setenv_x509(es, xt->name, fp_str, depth);
472 }
473 break;
474
475 default:
476 {
477 int i = X509_NAME_get_index_by_NID(x509_name, xt->nid, -1);
478 if (i >= 0)
479 {
480 X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i);
481 if (ent)
482 {
483 ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent);
484 unsigned char *buf = NULL;
485 if (ASN1_STRING_to_UTF8(&buf, val) >= 0)
486 {
487 do_setenv_x509(es, xt->name, (char *)buf, depth);
488 OPENSSL_free(buf);
489 }
490 }
491 }
492 else
493 {
494 i = X509_get_ext_by_NID(x509, xt->nid, -1);
495 if (i >= 0)
496 {
497 X509_EXTENSION *ext = X509_get_ext(x509, i);
498 if (ext)
499 {
500 BIO *bio = BIO_new(BIO_s_mem());
501 if (bio)
502 {
503 if (X509V3_EXT_print(bio, ext, 0, 0))
504 {
505 if (BIO_write(bio, &nullc, 1) == 1)
506 {
507 char *str;
508 BIO_get_mem_data(bio, &str);
509 do_setenv_x509(es, xt->name, str, depth);
510 }
511 }
512 BIO_free(bio);
513 }
514 }
515 }
516 }
517 }
518 }
519 }
520 xt = xt->next;
521 }
522 gc_free(&gc);
523 }
524
525 /*
526 * Save X509 fields to environment, using the naming convention:
527 *
528 * X509_{cert_depth}_{name}={value}
529 */
530 void
x509_setenv(struct env_set * es,int cert_depth,openvpn_x509_cert_t * peer_cert)531 x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert)
532 {
533 int i, n;
534 int fn_nid;
535 ASN1_OBJECT *fn;
536 ASN1_STRING *val;
537 X509_NAME_ENTRY *ent;
538 const char *objbuf;
539 unsigned char *buf = NULL;
540 char *name_expand;
541 size_t name_expand_size;
542 X509_NAME *x509 = X509_get_subject_name(peer_cert);
543
544 n = X509_NAME_entry_count(x509);
545 for (i = 0; i < n; ++i)
546 {
547 ent = X509_NAME_get_entry(x509, i);
548 if (!ent)
549 {
550 continue;
551 }
552 fn = X509_NAME_ENTRY_get_object(ent);
553 if (!fn)
554 {
555 continue;
556 }
557 val = X509_NAME_ENTRY_get_data(ent);
558 if (!val)
559 {
560 continue;
561 }
562 fn_nid = OBJ_obj2nid(fn);
563 if (fn_nid == NID_undef)
564 {
565 continue;
566 }
567 objbuf = OBJ_nid2sn(fn_nid);
568 if (!objbuf)
569 {
570 continue;
571 }
572 if (ASN1_STRING_to_UTF8(&buf, val) < 0)
573 {
574 continue;
575 }
576 name_expand_size = 64 + strlen(objbuf);
577 name_expand = (char *) malloc(name_expand_size);
578 check_malloc_return(name_expand);
579 openvpn_snprintf(name_expand, name_expand_size, "X509_%d_%s", cert_depth,
580 objbuf);
581 string_mod(name_expand, CC_PRINT, CC_CRLF, '_');
582 string_mod((char *)buf, CC_PRINT, CC_CRLF, '_');
583 setenv_str_incr(es, name_expand, (char *)buf);
584 free(name_expand);
585 OPENSSL_free(buf);
586 }
587 }
588
589 result_t
x509_verify_ns_cert_type(openvpn_x509_cert_t * peer_cert,const int usage)590 x509_verify_ns_cert_type(openvpn_x509_cert_t *peer_cert, const int usage)
591 {
592 if (usage == NS_CERT_CHECK_NONE)
593 {
594 return SUCCESS;
595 }
596 if (usage == NS_CERT_CHECK_CLIENT)
597 {
598 /*
599 * Unfortunately, X509_check_purpose() does some weird thing that
600 * prevent it to take a const argument
601 */
602 result_t result = X509_check_purpose(peer_cert, X509_PURPOSE_SSL_CLIENT, 0) ?
603 SUCCESS : FAILURE;
604
605 /*
606 * old versions of OpenSSL allow us to make the less strict check we used to
607 * do. If this less strict check pass, warn user that this might not be the
608 * case when its distribution will update to OpenSSL 1.1
609 */
610 if (result == FAILURE)
611 {
612 ASN1_BIT_STRING *ns;
613 ns = X509_get_ext_d2i(peer_cert, NID_netscape_cert_type, NULL, NULL);
614 result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_CLIENT)) ? SUCCESS : FAILURE;
615 if (result == SUCCESS)
616 {
617 msg(M_WARN, "X509: Certificate is a client certificate yet it's purpose "
618 "cannot be verified (check may fail in the future)");
619 }
620 ASN1_BIT_STRING_free(ns);
621 }
622 return result;
623 }
624 if (usage == NS_CERT_CHECK_SERVER)
625 {
626 /*
627 * Unfortunately, X509_check_purpose() does some weird thing that
628 * prevent it to take a const argument
629 */
630 result_t result = X509_check_purpose(peer_cert, X509_PURPOSE_SSL_SERVER, 0) ?
631 SUCCESS : FAILURE;
632
633 /*
634 * old versions of OpenSSL allow us to make the less strict check we used to
635 * do. If this less strict check pass, warn user that this might not be the
636 * case when its distribution will update to OpenSSL 1.1
637 */
638 if (result == FAILURE)
639 {
640 ASN1_BIT_STRING *ns;
641 ns = X509_get_ext_d2i(peer_cert, NID_netscape_cert_type, NULL, NULL);
642 result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_SERVER)) ? SUCCESS : FAILURE;
643 if (result == SUCCESS)
644 {
645 msg(M_WARN, "X509: Certificate is a server certificate yet it's purpose "
646 "cannot be verified (check may fail in the future)");
647 }
648 ASN1_BIT_STRING_free(ns);
649 }
650 return result;
651 }
652
653 return FAILURE;
654 }
655
656 result_t
x509_verify_cert_ku(X509 * x509,const unsigned * const expected_ku,int expected_len)657 x509_verify_cert_ku(X509 *x509, const unsigned *const expected_ku,
658 int expected_len)
659 {
660 ASN1_BIT_STRING *ku = X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL);
661
662 if (ku == NULL)
663 {
664 msg(D_TLS_ERRORS, "Certificate does not have key usage extension");
665 return FAILURE;
666 }
667
668 if (expected_ku[0] == OPENVPN_KU_REQUIRED)
669 {
670 /* Extension required, value checked by TLS library */
671 ASN1_BIT_STRING_free(ku);
672 return SUCCESS;
673 }
674
675 unsigned nku = 0;
676 for (size_t i = 0; i < 8; i++)
677 {
678 if (ASN1_BIT_STRING_get_bit(ku, i))
679 {
680 nku |= 1 << (7 - i);
681 }
682 }
683
684 /*
685 * Fixup if no LSB bits
686 */
687 if ((nku & 0xff) == 0)
688 {
689 nku >>= 8;
690 }
691
692 msg(D_HANDSHAKE, "Validating certificate key usage");
693 result_t fFound = FAILURE;
694 for (size_t i = 0; fFound != SUCCESS && i < expected_len; i++)
695 {
696 if (expected_ku[i] != 0 && (nku & expected_ku[i]) == expected_ku[i])
697 {
698 fFound = SUCCESS;
699 }
700 }
701
702 if (fFound != SUCCESS)
703 {
704 msg(D_TLS_ERRORS,
705 "ERROR: Certificate has key usage %04x, expected one of:", nku);
706 for (size_t i = 0; i < expected_len && expected_ku[i]; i++)
707 {
708 msg(D_TLS_ERRORS, " * %04x", expected_ku[i]);
709 }
710 }
711
712 ASN1_BIT_STRING_free(ku);
713
714 return fFound;
715 }
716
717 result_t
x509_verify_cert_eku(X509 * x509,const char * const expected_oid)718 x509_verify_cert_eku(X509 *x509, const char *const expected_oid)
719 {
720 EXTENDED_KEY_USAGE *eku = NULL;
721 result_t fFound = FAILURE;
722
723 if ((eku = (EXTENDED_KEY_USAGE *) X509_get_ext_d2i(x509, NID_ext_key_usage,
724 NULL, NULL)) == NULL)
725 {
726 msg(D_HANDSHAKE, "Certificate does not have extended key usage extension");
727 }
728 else
729 {
730 int i;
731
732 msg(D_HANDSHAKE, "Validating certificate extended key usage");
733 for (i = 0; SUCCESS != fFound && i < sk_ASN1_OBJECT_num(eku); i++)
734 {
735 ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(eku, i);
736 char szOid[1024];
737
738 if (SUCCESS != fFound && OBJ_obj2txt(szOid, sizeof(szOid), oid, 0) != -1)
739 {
740 msg(D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s",
741 szOid, expected_oid);
742 if (!strcmp(expected_oid, szOid))
743 {
744 fFound = SUCCESS;
745 }
746 }
747 if (SUCCESS != fFound && OBJ_obj2txt(szOid, sizeof(szOid), oid, 1) != -1)
748 {
749 msg(D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s",
750 szOid, expected_oid);
751 if (!strcmp(expected_oid, szOid))
752 {
753 fFound = SUCCESS;
754 }
755 }
756 }
757 }
758
759 if (eku != NULL)
760 {
761 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
762 }
763
764 return fFound;
765 }
766
767 result_t
x509_write_pem(FILE * peercert_file,X509 * peercert)768 x509_write_pem(FILE *peercert_file, X509 *peercert)
769 {
770 if (PEM_write_X509(peercert_file, peercert) < 0)
771 {
772 msg(M_NONFATAL, "Failed to write peer certificate in PEM format");
773 return FAILURE;
774 }
775 return SUCCESS;
776 }
777
778 bool
tls_verify_crl_missing(const struct tls_options * opt)779 tls_verify_crl_missing(const struct tls_options *opt)
780 {
781 if (!opt->crl_file || (opt->ssl_flags & SSLF_CRL_VERIFY_DIR))
782 {
783 return false;
784 }
785
786 X509_STORE *store = SSL_CTX_get_cert_store(opt->ssl_ctx.ctx);
787 if (!store)
788 {
789 crypto_msg(M_FATAL, "Cannot get certificate store");
790 }
791
792 STACK_OF(X509_OBJECT) *objs = X509_STORE_get0_objects(store);
793 for (int i = 0; i < sk_X509_OBJECT_num(objs); i++)
794 {
795 X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i);
796 ASSERT(obj);
797 if (X509_OBJECT_get_type(obj) == X509_LU_CRL)
798 {
799 return false;
800 }
801 }
802 return true;
803 }
804
805 #endif /* defined(ENABLE_CRYPTO_OPENSSL) */
806