OpenVPN
ssl_verify_openssl.c
Go to the documentation of this file.
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-2026 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2010-2026 Sentyron B.V. <openvpn@sentyron.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, see <https://www.gnu.org/licenses/>.
22 */
23
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include "syshead.h"
34
35#if defined(ENABLE_CRYPTO_OPENSSL)
36
37#include "ssl_verify_openssl.h"
38
39#include "error.h"
40#include "ssl_openssl.h"
41#include "ssl_verify.h"
42#include "ssl_verify_backend.h"
43#include "openssl_compat.h"
44
45#include <openssl/bn.h>
46#include <openssl/err.h>
47#include <openssl/x509v3.h>
48
49int
50verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
51{
52 int ret = 0;
53 struct tls_session *session;
54 SSL *ssl;
55 struct gc_arena gc = gc_new();
56
57 /* get the tls_session pointer */
58 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
59 ASSERT(ssl);
60 session = (struct tls_session *)SSL_get_ex_data(ssl, mydata_index);
62
63 X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
66
67 /* did peer present cert which was signed by our root cert? */
68 if (!preverify_ok && !session->opt->verify_hash_no_ca)
69 {
70 /* get the X509 name */
73
74 if (!subject)
75 {
76 subject = "(Failed to retrieve certificate subject)";
77 }
78
79 /* Log and ignore missing CRL errors */
81 {
82 msg(D_TLS_DEBUG_LOW, "VERIFY WARNING: depth=%d, %s: %s",
85 ret = 1;
86 goto cleanup;
87 }
88
89 /* Remote site specified a certificate, but it's not correct */
90 msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, error=%s: %s, serial=%s",
93 serial ? serial : "<not available>");
94
96
97 session->verified = false;
98 goto cleanup;
99 }
100
102 {
103 goto cleanup;
104 }
105
106 ret = 1;
107
108cleanup:
109 gc_free(&gc);
110
111 return ret;
112}
113
114bool
116{
117 int nid = OBJ_txt2nid(fieldname);
118 return nid == NID_subject_alt_name || nid == NID_issuer_alt_name;
119}
120
121static bool
122extract_x509_extension(X509 *cert, char *fieldname, char *out, size_t size)
123{
124 bool retval = false;
125
127 {
128 msg(D_TLS_ERRORS, "ERROR: --x509-username-field 'ext:%s' not supported", fieldname);
129 return false;
130 }
131
132 int nid = OBJ_txt2nid(fieldname);
134 if (extensions)
135 {
136 /* get amount of alternatives,
137 * RFC2459 claims there MUST be at least
138 * one, but we don't depend on it...
139 */
140
142
143 /* loop through all alternatives */
144 for (openssl_stack_size_t i = 0; i < numalts; i++)
145 {
146 /* get a handle to alternative name number i */
148 char *buf = NULL;
149
150 switch (name->type)
151 {
152 case GEN_EMAIL:
153 if (ASN1_STRING_to_UTF8((unsigned char **)&buf, name->d.rfc822Name) < 0)
154 {
155 continue;
156 }
157 if ((ssize_t)strlen(buf) != ASN1_STRING_length(name->d.rfc822Name))
158 {
159 msg(D_TLS_ERRORS, "ASN1 ERROR: string contained terminating zero");
160 OPENSSL_free(buf);
161 }
162 else
163 {
164 strncpynt(out, buf, size);
165 OPENSSL_free(buf);
166 retval = true;
167 }
168 break;
169
170 default:
171 msg(D_TLS_DEBUG, "%s: ignoring general name field type %d", __func__,
172 name->type);
173 break;
174 }
175 }
177 }
178 return retval;
179}
180
181/*
182 * Extract a field from an X509 subject name.
183 *
184 * Example:
185 *
186 * /C=US/ST=CO/L=Denver/O=ORG/CN=First-CN/CN=Test-CA/Email=jim@yonan.net
187 *
188 * The common name is 'Test-CA'
189 *
190 * Return true on success, false on error (insufficient buffer size in 'out'
191 * to contain result is grounds for error).
192 */
193static result_t
194extract_x509_field_ssl(const X509_NAME *x509, const char *field_name, char *out, size_t size)
195{
196 int lastpos = -1;
197 int tmp = -1;
198 unsigned char *buf = NULL;
200
202 if (field_name_obj == NULL)
203 {
204 msg(D_TLS_ERRORS, "Invalid X509 attribute name '%s'", field_name);
205 goto exit;
206 }
207
208 ASSERT(size > 0);
209 *out = '\0';
210 do
211 {
212 lastpos = tmp;
213#if OPENSSL_VERSION_NUMBER >= 0x30000000L
215#else
216 /* OpenSSL 1.1.x has the argument as non-const */
218#endif
219 } while (tmp > -1);
220
222
223 /* Nothing found */
224 if (lastpos == -1)
225 {
226 goto exit;
227 }
228
230 if (!x509ne)
231 {
232 goto exit;
233 }
234
236 if (!asn1)
237 {
238 goto exit;
239 }
240 int length = ASN1_STRING_to_UTF8(&buf, asn1);
241 if (length < 0 || (size_t)length != strlen((char *)buf))
242 {
243 goto exit;
244 }
245
246 strncpynt(out, (char *)buf, size);
247
248 ret = (strlen((char *)buf) < size) ? SUCCESS : FAILURE;
249
250exit:
251 OPENSSL_free(buf);
252 return ret;
253}
254
256backend_x509_get_username(char *common_name, size_t cn_len, char *x509_username_field, X509 *peer_cert)
257{
258 if (strncmp("ext:", x509_username_field, 4) == 0)
259 {
260 if (!extract_x509_extension(peer_cert, x509_username_field + 4, common_name, cn_len))
261 {
262 return FAILURE;
263 }
264 }
265 else if (strcmp(LN_serialNumber, x509_username_field) == 0)
266 {
268
270 char *serial = BN_bn2hex(bn_serial);
272
273 if (!serial || cn_len <= strlen(serial) + 2)
274 {
276 return FAILURE;
277 }
278 snprintf(common_name, cn_len, "0x%s", serial);
280 }
281 else
282 {
284 if (x509_subject_name == NULL)
285 {
286 msg(D_TLS_ERRORS, "X509 subject name is NULL");
287 return FAILURE;
288 }
289
290 if (FAILURE
291 == extract_x509_field_ssl(x509_subject_name, x509_username_field,
292 common_name, cn_len))
293 {
294 return FAILURE;
295 }
296 }
297
298 return SUCCESS;
299}
300
301char *
319
320char *
322{
326 unsigned char *buf = malloc(len_serial);
328
329 char *ret = format_hex_ex(buf, len_serial, 0, 1, ":", gc);
330 free(buf);
332
333 return ret;
334}
335
337backend_x509_write_pem(openvpn_x509_cert_t *cert, const char *filename)
338{
339 BIO *out = BIO_new_file(filename, "w");
340 if (!out)
341 {
342 goto err;
343 }
344
345 if (!PEM_write_bio_X509(out, cert))
346 {
347 goto err;
348 }
349 BIO_free(out);
350
351 return SUCCESS;
352err:
353 BIO_free(out);
354 crypto_msg(D_TLS_DEBUG_LOW, "Error writing X509 certificate to file %s", filename);
355 return FAILURE;
356}
357
358struct buffer
360{
361 const EVP_MD *sha1 = EVP_sha1();
362 struct buffer hash = alloc_buf_gc((size_t)EVP_MD_size(sha1), gc);
363 X509_digest(cert, EVP_sha1(), BPTR(&hash), NULL);
365 return hash;
366}
367
368struct buffer
370{
371 const EVP_MD *sha256 = EVP_sha256();
372 struct buffer hash = alloc_buf_gc((size_t)EVP_MD_size(sha256), gc);
373 X509_digest(cert, EVP_sha256(), BPTR(&hash), NULL);
375 return hash;
376}
377
378char *
380{
383 char *subject = NULL;
384
386 if (subject_bio == NULL)
387 {
388 goto err;
389 }
390
393
394 if (BIO_eof(subject_bio))
395 {
396 goto err;
397 }
398
400
401 /* Check subject for '\0' bytes. */
402 for (size_t i = 0; i < subject_mem->length; i++)
403 {
404 if (subject_mem->data[i] == 0)
405 {
406 msg(M_WARN, "ERROR: Certificate subject contains a '\\0' byte.");
407 goto err;
408 }
409 }
410
411 subject = gc_malloc(subject_mem->length + 1, false, gc);
412
413 memcpy(subject, subject_mem->data, subject_mem->length);
414 subject[subject_mem->length] = '\0';
415
416err:
418 return subject;
419}
420
421
422/*
423 * x509-track implementation -- save X509 fields to environment,
424 * using the naming convention:
425 *
426 * X509_{cert_depth}_{name}={value}
427 *
428 * This function differs from x509_setenv below in the following ways:
429 *
430 * (1) Only explicitly named attributes in xt are saved, per usage
431 * of "x509-track" program options.
432 * (2) Only the level 0 cert info is saved unless the XT_FULL_CHAIN
433 * flag is set in xt->flags (corresponds with prepending a '+'
434 * to the name when specified by "x509-track" program option).
435 * (3) This function supports both X509 subject name fields as
436 * well as X509 V3 extensions.
437 * (4) This function can return the SHA1 fingerprint of a cert, e.g.
438 * x509-track "+SHA1"
439 * will return the SHA1 fingerprint for each certificate in the
440 * peer chain.
441 */
442
443void
444x509_track_add(const struct x509_track **ll_head, const char *name, msglvl_t msglevel,
445 struct gc_arena *gc)
446{
447 struct x509_track *xt;
448 ALLOC_OBJ_CLEAR_GC(xt, struct x509_track, gc);
449 if (*name == '+')
450 {
451 xt->flags |= XT_FULL_CHAIN;
452 ++name;
453 }
454 xt->name = name;
455 xt->nid = OBJ_txt2nid(name);
456 if (xt->nid != NID_undef)
457 {
458 xt->next = *ll_head;
459 *ll_head = xt;
460 }
461 else
462 {
463 msg(msglevel, "x509_track: no such attribute '%s'", name);
464 }
465}
466
467/* worker method for setenv_x509_track */
468static void
469do_setenv_x509(struct env_set *es, const char *name, char *value, int depth)
470{
471 char *name_expand;
472 size_t name_expand_size;
473
474 string_mod(value, CC_ANY, CC_CRLF, '?');
475 msg(D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth);
476 name_expand_size = 64 + strlen(name);
477 name_expand = (char *)malloc(name_expand_size);
478 check_malloc_return(name_expand);
479 snprintf(name_expand, name_expand_size, "X509_%d_%s", depth, name);
480 setenv_str(es, name_expand, value);
481 free(name_expand);
482}
483
484void
485x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, X509 *x509)
486{
487 struct gc_arena gc = gc_new();
488#if OPENSSL_VERSION_NUMBER < 0x30000000L
489 /* OpenSSL 1.1.x APIs all take non-const arguments */
490 X509_NAME *x509_name = X509_get_subject_name(x509);
491#else
492 const X509_NAME *x509_name = X509_get_subject_name(x509);
493#endif
494 const char nullc = '\0';
495
496 while (xt)
497 {
498 if (depth == 0 || (xt->flags & XT_FULL_CHAIN))
499 {
500 switch (xt->nid)
501 {
502 case NID_sha1:
503 case NID_sha256:
504 {
505 struct buffer fp_buf;
506 char *fp_str = NULL;
507
508 if (xt->nid == NID_sha1)
509 {
511 }
512 else
513 {
515 }
516
517 fp_str = format_hex_ex(BPTR(&fp_buf), BLEN(&fp_buf), 0, 1 | FHE_CAPS, ":", &gc);
518 do_setenv_x509(es, xt->name, fp_str, depth);
519 }
520 break;
521
522 default:
523 {
524 int i = X509_NAME_get_index_by_NID(x509_name, xt->nid, -1);
525 if (i >= 0)
526 {
528 if (ent)
529 {
531 unsigned char *buf = NULL;
532 if (ASN1_STRING_to_UTF8(&buf, val) >= 0)
533 {
534 do_setenv_x509(es, xt->name, (char *)buf, depth);
535 OPENSSL_free(buf);
536 }
537 }
538 }
539 else
540 {
541 i = X509_get_ext_by_NID(x509, xt->nid, -1);
542 if (i >= 0)
543 {
544#if OPENSSL_VERSION_NUMBER < 0x40000000L
546#else
548#endif
549 if (ext)
550 {
551 BIO *bio = BIO_new(BIO_s_mem());
552 if (bio)
553 {
554 if (X509V3_EXT_print(bio, ext, 0, 0))
555 {
556 if (BIO_write(bio, &nullc, 1) == 1)
557 {
558 char *str;
560 do_setenv_x509(es, xt->name, str, depth);
561 }
562 }
563 BIO_free(bio);
564 }
565 }
566 }
567 }
568 }
569 }
570 }
571 xt = xt->next;
572 }
573 gc_free(&gc);
574}
575
576/*
577 * Save X509 fields to environment, using the naming convention:
578 *
579 * X509_{cert_depth}_{name}={value}
580 */
581void
583{
585
587 for (int i = 0; i < n; ++i)
588 {
590 if (!ent)
591 {
592 continue;
593 }
595 if (!fn)
596 {
597 continue;
598 }
600 if (!val)
601 {
602 continue;
603 }
604 int fn_nid = OBJ_obj2nid(fn);
605 if (fn_nid == NID_undef)
606 {
607 continue;
608 }
609 const char *objbuf = OBJ_nid2sn(fn_nid);
610 if (!objbuf)
611 {
612 continue;
613 }
614 unsigned char *buf = NULL;
615 if (ASN1_STRING_to_UTF8(&buf, val) < 0)
616 {
617 continue;
618 }
619 size_t name_expand_size = 64 + strlen(objbuf);
624 string_mod((char *)buf, CC_PRINT, CC_CRLF, '_');
625 setenv_str_incr(es, name_expand, (char *)buf);
626 free(name_expand);
627 OPENSSL_free(buf);
628 }
629}
630
633{
635 {
636 return SUCCESS;
637 }
639 {
640 /*
641 * Unfortunately, X509_check_purpose() before OpenSSL 4.0 does some weird thing that
642 * prevent it to take a const argument
643 */
646 /*
647 * Note that we did not check for netscape certificate type here but
648 * instead a general SSL/TLS client purpose. These nscert attributes
649 * might stop being accepted by TLS libraries in the future.
650 * Currently, OpenSSL 4.0 and aws-lc 1.9.0 still consider nscert client
651 * as acceptable.
652 *
653 * So in case that this check failed, we now check if this is caused
654 * by the check above no longer recognising nscert attributes.
655 */
656 if (result == FAILURE)
657 {
660 // bit 0 is to check if certificate is the client certificate
662 if (result == SUCCESS)
663 {
664 msg(M_WARN, "X509: Certificate is a client certificate yet it's purpose "
665 "cannot be verified (check may fail in the future)");
666 }
668 }
669 return result;
670 }
672 {
673 /*
674 * Unfortunately, X509_check_purpose() before OpenSSL 4.0 does some weird thing that
675 * prevent it to take a const argument
676 */
679
680 /*
681 * Note that we did not check for netscape certificate type here but
682 * instead a general SSL/TLS server purpose. These nscert attributes
683 * might stop being accepted by TLS libraries in the future.
684 * Currently, OpenSSL 4.0 and aws-lc 1.9.0 still consider nscert server
685 * as acceptable.
686 *
687 * So in case that this check failed, we now check if this is caused
688 * by the check above no longer recognising nscert attributes.
689 */
690 if (result == FAILURE)
691 {
693 // Server bit is 1 for ASN1_BIT_STRING_get_bit
695 if (result == SUCCESS)
696 {
697 msg(M_WARN, "X509: Certificate is a server certificate yet it's purpose "
698 "cannot be verified (check may fail in the future)");
699 }
701 }
702 return result;
703 }
704
705 return FAILURE;
706}
707
709x509_verify_cert_ku(X509 *x509, const unsigned int *const expected_ku, size_t expected_len)
710{
712
713 if (ku == NULL)
714 {
715 msg(D_TLS_ERRORS, "Certificate does not have key usage extension");
716 return FAILURE;
717 }
718
720 {
721 /* Extension required, value checked by TLS library */
723 return SUCCESS;
724 }
725
726 unsigned int nku = 0;
727 for (int i = 0; i < 8; i++)
728 {
730 {
731 nku |= 1 << (7 - i);
732 }
733 }
734
735 /*
736 * Fixup if no LSB bits
737 */
738 if ((nku & 0xff) == 0)
739 {
740 nku >>= 8;
741 }
742
743 msg(D_HANDSHAKE, "Validating certificate key usage");
745 for (size_t i = 0; fFound != SUCCESS && i < expected_len; i++)
746 {
747 if (expected_ku[i] != 0 && (nku & expected_ku[i]) == expected_ku[i])
748 {
749 fFound = SUCCESS;
750 }
751 }
752
753 if (fFound != SUCCESS)
754 {
755 msg(D_TLS_ERRORS, "ERROR: Certificate has key usage %04x, expected one of:", nku);
756 for (size_t i = 0; i < expected_len && expected_ku[i]; i++)
757 {
758 msg(D_TLS_ERRORS, " * %04x", expected_ku[i]);
759 }
760 }
761
763
764 return fFound;
765}
766
769{
772
774 {
775 msg(D_HANDSHAKE, "Certificate does not have extended key usage extension");
776 }
777 else
778 {
779 msg(D_HANDSHAKE, "Validating certificate extended key usage");
781 {
783 char szOid[1024];
784
785 if (SUCCESS != fFound && OBJ_obj2txt(szOid, sizeof(szOid), oid, 0) != -1)
786 {
787 msg(D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s", szOid,
790 {
791 fFound = SUCCESS;
792 }
793 }
794 if (SUCCESS != fFound && OBJ_obj2txt(szOid, sizeof(szOid), oid, 1) != -1)
795 {
796 msg(D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s", szOid,
799 {
800 fFound = SUCCESS;
801 }
802 }
803 }
804 }
805
806 if (eku != NULL)
807 {
809 }
810
811 return fFound;
812}
813
814bool
816{
817 if (!opt->crl_file || (opt->ssl_flags & SSLF_CRL_VERIFY_DIR))
818 {
819 return false;
820 }
821
822 return opt->ssl_ctx->crls == NULL || sk_X509_CRL_num(opt->ssl_ctx->crls) == 0;
823}
824
825#endif /* defined(ENABLE_CRYPTO_OPENSSL) */
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Allocate memory and, optionally, zero it.
Definition buffer.c:318
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
Definition buffer.c:77
char * format_hex_ex(const uint8_t *data, size_t size, size_t maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Format a binary buffer as a hex string.
Definition buffer.c:452
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Modifies a string in place by replacing certain classes of characters of it with a specified characte...
Definition buffer.c:1005
char * string_alloc(const char *str, struct gc_arena *gc)
Duplicate a string, allocating memory under garbage collection.
Definition buffer.c:616
#define CC_ANY
any character
Definition buffer.h:1698
#define BPTR(buf)
Return a pointer to the start of the buffer content.
Definition buffer.h:139
static bool buf_inc_len(struct buffer *buf, int inc)
Increase or decrease the length of a buffer.
Definition buffer.h:1140
#define CC_CRLF
carriage return or newline
Definition buffer.h:1735
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Allocate and zero-initialise a garbage-collected object of the given type.
Definition buffer.h:2132
#define BLEN(buf)
Return the length of the buffer content in bytes.
Definition buffer.h:151
static void strncpynt(char *dest, const char *src, size_t maxlen)
Like strncpy() but always null-terminates the destination.
Definition buffer.h:708
static void check_malloc_return(void *p)
Abort if a memory allocation returned NULL.
Definition buffer.h:2144
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
Definition buffer.h:1974
#define CC_PRINT
printable (>= 32, != 127)
Definition buffer.h:1706
#define FHE_CAPS
Flag for format_hex_ex(): output hex digits in upper case.
Definition buffer.h:948
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
Definition buffer.h:1958
#define crypto_msg(flags,...)
Retrieve any OpenSSL errors, then print the supplied error message.
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition env_set.c:307
void setenv_str_incr(struct env_set *es, const char *name, const char *value)
Store the supplied name value pair in the env_set.
Definition env_set.c:329
#define D_TLS_DEBUG_LOW
Definition errlevel.h:76
#define D_X509_ATTR
Definition errlevel.h:102
#define D_HANDSHAKE
Definition errlevel.h:71
#define D_TLS_ERRORS
Definition errlevel.h:58
#define D_TLS_DEBUG
Definition errlevel.h:164
int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
Verify that the remote OpenVPN peer's certificate allows setting up a VPN tunnel.
OpenSSL compatibility stub.
int openssl_stack_size_t
#define msg(flags,...)
Definition error.h:152
unsigned int msglvl_t
Definition error.h:77
#define ASSERT(x)
Definition error.h:219
#define M_WARN
Definition error.h:92
#define SSLF_CRL_VERIFY_DIR
Definition ssl_common.h:428
int mydata_index
Allocate space in SSL objects in which to store a struct tls_session pointer back to parent.
Definition ssl_openssl.c:88
Control Channel OpenSSL Backend.
result_t verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth)
Definition ssl_verify.c:588
void cert_hash_remember(struct tls_session *session, const int error_depth, const struct buffer *cert_hash)
Definition ssl_verify.c:194
Control Channel Verification Module.
#define OPENVPN_KU_REQUIRED
Require keyUsage to be present in cert (0xFFFF is an invalid KU value)
Definition ssl_verify.h:257
#define XT_FULL_CHAIN
Definition ssl_verify.h:241
#define NS_CERT_CHECK_CLIENT
Do not perform Netscape certificate type verification.
Definition ssl_verify.h:254
#define NS_CERT_CHECK_NONE
Do not perform Netscape certificate type verification.
Definition ssl_verify.h:250
#define NS_CERT_CHECK_SERVER
Do not perform Netscape certificate type verification.
Definition ssl_verify.h:252
Control Channel Verification Module library-specific backend interface.
result_t
Result of verification function.
@ FAILURE
@ SUCCESS
mbedtls_x509_crt openvpn_x509_cert_t
char * x509_get_subject(X509 *cert, struct gc_arena *gc)
struct buffer x509_get_sha1_fingerprint(X509 *cert, struct gc_arena *gc)
result_t x509_verify_ns_cert_type(openvpn_x509_cert_t *peer_cert, const int cert_type)
result_t x509_verify_cert_ku(X509 *x509, const unsigned int *const expected_ku, size_t expected_len)
bool tls_verify_crl_missing(const struct tls_options *opt)
Return true iff a CRL is configured, but is not loaded.
static result_t extract_x509_field_ssl(const X509_NAME *x509, const char *field_name, char *out, size_t size)
result_t backend_x509_write_pem(openvpn_x509_cert_t *cert, const char *filename)
struct buffer x509_get_sha256_fingerprint(X509 *cert, struct gc_arena *gc)
result_t x509_verify_cert_eku(X509 *x509, const char *const expected_oid)
static void do_setenv_x509(struct env_set *es, const char *name, char *value, int depth)
static bool extract_x509_extension(X509 *cert, char *fieldname, char *out, size_t size)
bool x509_username_field_ext_supported(const char *fieldname)
Return true iff the supplied extension field is supported by the –x509-username-field option.
char * backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc)
void x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, X509 *x509)
char * backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
void x509_track_add(const struct x509_track **ll_head, const char *name, msglvl_t msglevel, struct gc_arena *gc)
void x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert)
result_t backend_x509_get_username(char *common_name, size_t cn_len, char *x509_username_field, X509 *peer_cert)
Control Channel Verification Module OpenSSL backend.
Wrapper structure for dynamically allocated memory.
Definition buffer.h:71
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:76
Structure containing the hash for a single certificate.
Definition ssl_verify.h:58
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:127
Definition list.h:56
unsigned int ssl_flags
Definition ssl_common.h:434
struct tls_root_ctx * ssl_ctx
Definition ssl_common.h:310
const char * crl_file
Definition ssl_common.h:355
Security parameter state of a single session within a VPN tunnel.
Definition ssl_common.h:489
unsigned int flags
Definition ssl_verify.h:242
const struct x509_track * next
Definition ssl_verify.h:239
const char * name
Definition ssl_verify.h:240
static int cleanup(void **state)
struct gc_arena gc
Definition test_ssl.c:122