OpenVPN
ssl_verify_mbedtls.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_MBEDTLS)
36
37#include <mbedtls/version.h>
38
39#if MBEDTLS_VERSION_NUMBER < 0x04000000
41#include <mbedtls/bignum.h>
42#include <mbedtls/sha1.h>
43#else
44#include "crypto_mbedtls.h"
45#endif
46
47#include "mbedtls_compat.h"
48
49#include "ssl_verify.h"
50#include <mbedtls/asn1.h>
51#include <mbedtls/error.h>
52#include <mbedtls/oid.h>
53
54#define MAX_SUBJECT_LENGTH 256
55
56int
57verify_callback(void *session_obj, mbedtls_x509_crt *cert, int cert_depth, uint32_t *flags)
58{
59 struct tls_session *session = (struct tls_session *)session_obj;
60 struct gc_arena gc = gc_new();
61
62 ASSERT(cert);
64
65 session->verified = false;
66
67 /* Remember certificate hash */
70
71 if (session->opt->verify_hash_no_ca)
72 {
73 /*
74 * If we decide to verify the peer certificate based on the fingerprint
75 * we ignore wrong dates and the certificate not being trusted.
76 * Any other problem with the certificate (wrong key, bad cert,...)
77 * will still trigger an error.
78 * Clearing these flags relies on verify_cert will later rejecting a
79 * certificate that has no matching fingerprint.
80 */
83 *flags = *flags & ~flags_ignore;
84 }
85
86 /* did peer present cert which was signed by our root cert? */
87 if (*flags != 0)
88 {
89 int ret = 0;
90 char errstr[512] = { 0 };
91 char *subject = x509_get_subject(cert, &gc);
92 char *serial = backend_x509_get_serial(cert, &gc);
93
94 ret = mbedtls_x509_crt_verify_info(errstr, sizeof(errstr) - 1, "", *flags);
95 if (ret <= 0
96 && !checked_snprintf(errstr, sizeof(errstr), "Could not retrieve error string, flags=%" PRIx32, *flags))
97 {
98 errstr[0] = '\0';
99 }
100 else
101 {
102 chomp(errstr);
103 }
104
105 if (subject)
106 {
107 msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, subject=%s, serial=%s: %s", cert_depth,
108 subject, serial ? serial : "<not available>", errstr);
109 }
110 else
111 {
113 "VERIFY ERROR: depth=%d, (could not extract X509 "
114 "subject string from certificate): %s",
116 }
117
118 /* Leave flags set to non-zero to indicate that the cert is not ok */
119 }
120 else if (SUCCESS != verify_cert(session, cert, cert_depth))
121 {
123 }
124
125 gc_free(&gc);
126
127 /*
128 * PolarSSL/mbed TLS-1.2.0+ expects 0 on anything except fatal errors.
129 */
130 return 0;
131}
132
133/* not supported for mbedTLS yet */
134bool
136{
137 return false;
138}
139
140static const char *
141fieldname_to_oid(const char *fieldname)
142{
143 if (strcmp(fieldname, "C") == 0)
144 {
146 }
147 else if (strcmp(fieldname, "ST") == 0)
148 {
150 }
151 else if (strcmp(fieldname, "LOCALITY") == 0)
152 {
154 }
155 else if (strcmp(fieldname, "O") == 0)
156 {
158 }
159 else if (strcmp(fieldname, "OU") == 0)
160 {
162 }
163 else if (strcmp(fieldname, "CN") == 0)
164 {
165 return MBEDTLS_OID_AT_CN;
166 }
167 else if (strcmp(fieldname, "GN") == 0)
168 {
170 }
171 else if (strcmp(fieldname, "SN") == 0)
172 {
174 }
175 else if (strcmp(fieldname, "initials") == 0)
176 {
178 }
179 else if (strcmp(fieldname, "pseudonym") == 0)
180 {
182 }
183 else if (strcmp(fieldname, "title") == 0)
184 {
186 }
187 else if (strcmp(fieldname, "generationQualifier") == 0)
188 {
190 }
191 else if (strcmp(fieldname, "postalAddress") == 0)
192 {
194 }
195 else if (strcmp(fieldname, "postalCode") == 0)
196 {
198 }
199 else if (strcmp(fieldname, "emailAddress") == 0)
200 {
202 }
203 else if (strcmp(fieldname, "uid") == 0)
204 {
206 }
207 else if (strcmp(fieldname, "dnQualifier") == 0)
208 {
210 }
211 else
212 {
213 return NULL;
214 }
215}
216
218backend_x509_get_username(char *cn, size_t cn_len, char *x509_username_field, mbedtls_x509_crt *cert)
219{
220 ASSERT(cn != NULL && cn_len > 0 && cert != NULL);
221
222 if (x509_username_field == NULL)
223 {
224 goto fail;
225 }
226
227 if (strcmp(x509_username_field, "serialNumber") == 0)
228 {
229 if (cn_len < 2)
230 {
231 goto fail;
232 }
233 cn[0] = '0';
234 cn[1] = 'x';
235 size_t cn_index = 2;
236 bool leading_zeros = true;
237 for (size_t i = 0; i < cert->serial.len; i++)
238 {
239 uint8_t serial_byte = cert->serial.p[i];
240 if (leading_zeros && serial_byte == 0)
241 {
242 continue;
243 }
244 leading_zeros = false;
245 if (cn_index > cn_len - 3)
246 {
247 goto fail;
248 }
250 cn_index += 2;
251 }
252 return SUCCESS;
253 }
254
255 const char *field_oid = fieldname_to_oid(x509_username_field);
256 if (field_oid == NULL)
257 {
258 goto fail;
259 }
260
261 /* Find field_oid in the subject name. */
262 mbedtls_x509_name *name = &cert->subject;
263 while (name != NULL)
264 {
265 if (strlen(field_oid) == name->oid.len
266 && 0 == memcmp(name->oid.p, field_oid, name->oid.len))
267 {
268 break;
269 }
270
271 name = name->next;
272 }
273
274 /* Not found, return an error if this is the peer's certificate */
275 if (name == NULL)
276 {
277 goto fail;
278 }
279
280 /* Check that we have room in the buffer, including the terminating '/0' byte. */
281 if (cn_len <= name->val.len)
282 {
283 goto fail;
284 }
285
286 memcpy(cn, name->val.p, name->val.len);
287 cn[name->val.len] = '\0';
288
289 return SUCCESS;
290
291fail:
292 cn[0] = '\0';
293 return FAILURE;
294}
295
296#if MBEDTLS_VERSION_NUMBER >= 0x04000000
297/* Mbed TLS 4 has no function to print the certificate serial number and does
298 * not expose the bignum functions anymore. So in order to write the serial
299 * number as a decimal string, we implement bignum % 10 and bignum / 10. */
300static char
302{
303 int result = 0;
304 for (size_t i = 0; i < bignum_length; i++)
305 {
306 result = (result * 256) % 10;
307 result = (result + bignum[i]) % 10;
308 }
309 return (char)result;
310}
311
312/* Divide bignum by 10 rounded down, in place. */
313static void
315{
316 /*
317 * Some intuition for the algorithm below:
318 *
319 * We want to calculate
320 *
321 * (bignum[0] * 256^n + bignum[1] * 256^(n-1) + ... + bignum[n]) / 10.
322 *
323 * Let remainder = bignum[0] % 10 and carry = remainder * 256.
324 * Then we can write the above as
325 *
326 * (bignum[0] / 10) * 256^n
327 * + ((carry + bignum[1]) * 256^(n-1) + ... + bignum[n]) / 10.
328 *
329 * So now we have the first byte of our result. The second byte will be
330 * (carry + bignum[1]) / 10. Note that this fits into one byte because
331 * 0 <= remainder < 10. We calculate the next remainder and carry as
332 * remainder = (carry + bignum[1]) % 10 and carry = remainder * 256 and
333 * move on to the next byte until we are done.
334 */
335 size_t new_length = 0;
336 int carry = 0;
337 for (size_t i = 0; i < *bignum_length; i++)
338 {
339 uint8_t next_byte = (uint8_t)((bignum[i] + carry) / 10);
340 int remainder = (bignum[i] + carry) % 10;
341 carry = remainder * 256;
342
343 /* Write the byte unless it's a leading zero. */
344 if (new_length != 0 || next_byte != 0)
345 {
347 }
348 }
350}
351
352/* Write the decimal representation of bignum to out, if enough space is available.
353 * Returns the number of bytes needed in out, or 0 on error. To calculate the
354 * necessary buffer size, the function can be called with out = NULL. */
355static size_t
356write_bignum(char *out, size_t out_size, const uint8_t *bignum, size_t bignum_length)
357{
358 if (bignum_length == 0)
359 {
360 /* We want out to be "0". */
361 if (out != NULL)
362 {
363 if (out_size >= 2)
364 {
365 out[0] = '0';
366 out[1] = '\0';
367 }
368 else if (out_size > 0)
369 {
370 out[0] = '\0';
371 }
372 }
373 return 2;
374 }
375
377 if (bignum_copy == NULL)
378 {
379 return 0;
380 }
382
383 size_t bytes_needed = 0;
384 size_t bytes_written = 0;
385 while (bignum_length > 0)
386 {
387 /* We're writing the digits in reverse order. We put them in the right order later. */
389 if (out != NULL && bytes_written < out_size - 1)
390 {
391 out[bytes_written++] = '0' + (char)digit;
392 }
393 bytes_needed += 1;
395 }
396
397 if (out != NULL)
398 {
400 {
401 /* We had space for all digits. Now reverse them. */
402 for (size_t i = 0; i < bytes_written / 2; i++)
403 {
404 char tmp = out[i];
405 out[i] = out[bytes_written - 1 - i];
406 out[bytes_written - 1 - i] = tmp;
407 }
408 out[bytes_written] = '\0';
409 }
410 else if (out_size > 0)
411 {
412 out[0] = '\0';
413 }
414 }
415 bytes_needed += 1;
416
417 free(bignum_copy);
418 return bytes_needed;
419}
420#endif /* MBEDTLS_VERSION_NUMBER >= 0x04000000 */
421
422char *
424{
425 char *buf = NULL;
426 size_t buflen = 0;
427
428#if MBEDTLS_VERSION_NUMBER < 0x04000000
429 mbedtls_mpi serial_mpi = { 0 };
430
431 /* Transform asn1 integer serial into mbed TLS MPI */
433 if (!mbed_ok(mbedtls_mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len)))
434 {
435 msg(M_WARN, "Failed to retrieve serial from certificate.");
436 goto end;
437 }
438
439 /* Determine decimal representation length, allocate buffer */
441 buf = gc_malloc(buflen, true, gc);
442
443 /* Write MPI serial as decimal string into buffer */
445 {
446 msg(M_WARN, "Failed to write serial to string.");
447 buf = NULL;
448 goto end;
449 }
450
451end:
453 return buf;
454#else
455 buflen = write_bignum(NULL, 0, cert->serial.p, cert->serial.len);
456 if (buflen == 0)
457 {
458 msg(M_WARN, "Failed to write serial to string.");
459 return NULL;
460 }
461 buf = gc_malloc(buflen, true, gc);
462 if (write_bignum(buf, buflen, cert->serial.p, cert->serial.len) != buflen)
463 {
464 msg(M_WARN, "Failed to write serial to string.");
465 return NULL;
466 }
467 return buf;
468#endif /* MBEDTLS_VERSION_NUMBER < 0x04000000 */
469}
470
471char *
473{
474 char *buf = NULL;
475 size_t len = cert->serial.len * 3 + 1;
476
477 buf = gc_malloc(len, true, gc);
478
479 if (mbedtls_x509_serial_gets(buf, len - 1, &cert->serial) < 0)
480 {
481 buf = NULL;
482 }
483
484 return buf;
485}
486
488backend_x509_write_pem(openvpn_x509_cert_t *cert, const char *filename)
489{
490 /* mbed TLS does not make it easy to write a certificate in PEM format.
491 * The only way is to directly access the DER encoded raw certificate
492 * and PEM encode it ourselves */
493
494 struct gc_arena gc = gc_new();
495 /* just do a very loose upper bound for the base64 based PEM encoding
496 * using 3 times the space for the base64 and 100 bytes for the
497 * headers and footer */
498 struct buffer pem = alloc_buf_gc(cert->raw.len * 3 + 100, &gc);
499
500 struct buffer der = { 0 };
501 buf_set_read(&der, cert->raw.p, cert->raw.len);
502
503 if (!crypto_pem_encode("CERTIFICATE", &pem, &der, &gc))
504 {
505 goto err;
506 }
507
508 if (!buffer_write_file(filename, &pem))
509 {
510 goto err;
511 }
512
513 gc_free(&gc);
514 return SUCCESS;
515err:
516 msg(D_TLS_DEBUG_LOW, "Error writing X509 certificate to file %s", filename);
517 gc_free(&gc);
518 return FAILURE;
519}
520
521#if defined(__GNUC__) || defined(__clang__)
522#pragma GCC diagnostic push
523#pragma GCC diagnostic ignored "-Wconversion"
524#endif
525
526static struct buffer
528{
529 const size_t md_size = mbedtls_md_get_size(md_info);
531 mbedtls_md(md_info, cert->raw.p, cert->raw.len, BPTR(&fingerprint));
533 return fingerprint;
534}
535
536#if defined(__GNUC__) || defined(__clang__)
537#pragma GCC diagnostic pop
538#endif
539
540struct buffer
542{
543 return x509_get_fingerprint(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), cert, gc);
544}
545
546struct buffer
548{
549 return x509_get_fingerprint(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), cert, gc);
550}
551
552char *
553x509_get_subject(mbedtls_x509_crt *cert, struct gc_arena *gc)
554{
555 char tmp_subject[MAX_SUBJECT_LENGTH] = { 0 };
556 char *subject = NULL;
557
558 int ret = 0;
559
560 ret = mbedtls_x509_dn_gets(tmp_subject, MAX_SUBJECT_LENGTH - 1, &cert->subject);
561 if (ret > 0)
562 {
563 /* Allocate the required space for the subject */
564 subject = string_alloc(tmp_subject, gc);
565 }
566
567 return subject;
568}
569
570static void
571do_setenv_x509(struct env_set *es, const char *name, char *value, int depth)
572{
573 char *name_expand;
574 size_t name_expand_size;
575
576 string_mod(value, CC_ANY, CC_CRLF, '?');
577 msg(D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth);
578 name_expand_size = 64 + strlen(name);
579 name_expand = (char *)malloc(name_expand_size);
580 check_malloc_return(name_expand);
581 snprintf(name_expand, name_expand_size, "X509_%d_%s", depth, name);
582 setenv_str(es, name_expand, value);
583 free(name_expand);
584}
585
586static char *
587asn1_buf_to_c_string(const mbedtls_asn1_buf *orig, struct gc_arena *gc)
588{
589 size_t i;
590 char *val;
591
592 if (!(orig->tag == MBEDTLS_ASN1_UTF8_STRING || orig->tag == MBEDTLS_ASN1_PRINTABLE_STRING
593 || orig->tag == MBEDTLS_ASN1_IA5_STRING))
594 {
595 /* Only support C-string compatible types */
596 return string_alloc("ERROR: unsupported ASN.1 string type", gc);
597 }
598
599 for (i = 0; i < orig->len; ++i)
600 {
601 if (orig->p[i] == '\0')
602 {
603 return string_alloc("ERROR: embedded null value", gc);
604 }
605 }
606 val = gc_malloc(orig->len + 1, false, gc);
607 memcpy(val, orig->p, orig->len);
608 val[orig->len] = '\0';
609 return val;
610}
611
612static void
613do_setenv_name(struct env_set *es, const struct x509_track *xt, const mbedtls_x509_crt *cert,
614 int depth, struct gc_arena *gc)
615{
616 const mbedtls_x509_name *xn;
617 for (xn = &cert->subject; xn != NULL; xn = xn->next)
618 {
619 const char *xn_short_name = NULL;
620 if (0 == mbedtls_oid_get_attr_short_name(&xn->oid, &xn_short_name)
621 && 0 == strcmp(xt->name, xn_short_name))
622 {
623 char *val_str = asn1_buf_to_c_string(&xn->val, gc);
624 do_setenv_x509(es, xt->name, val_str, depth);
625 }
626 }
627}
628
629void
630x509_track_add(const struct x509_track **ll_head, const char *name, msglvl_t msglevel,
631 struct gc_arena *gc)
632{
633 struct x509_track *xt;
634 ALLOC_OBJ_CLEAR_GC(xt, struct x509_track, gc);
635 if (*name == '+')
636 {
637 xt->flags |= XT_FULL_CHAIN;
638 ++name;
639 }
640 xt->name = name;
641 xt->next = *ll_head;
642 *ll_head = xt;
643}
644
645void
646x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth,
647 mbedtls_x509_crt *cert)
648{
649 struct gc_arena gc = gc_new();
650 while (xt)
651 {
652 if (depth == 0 || (xt->flags & XT_FULL_CHAIN))
653 {
654 if (0 == strcmp(xt->name, "SHA1") || 0 == strcmp(xt->name, "SHA256"))
655 {
656 /* Fingerprint is not part of X509 structure */
657 struct buffer cert_hash;
658 char *fingerprint;
659
660 if (0 == strcmp(xt->name, "SHA1"))
661 {
663 }
664 else
665 {
667 }
668
670 format_hex_ex(BPTR(&cert_hash), BLEN(&cert_hash), 0, 1 | FHE_CAPS, ":", &gc);
672 }
673 else
674 {
675 do_setenv_name(es, xt, cert, depth, &gc);
676 }
677 }
678 xt = xt->next;
679 }
680 gc_free(&gc);
681}
682
683/*
684 * Save X509 fields to environment, using the naming convention:
685 *
686 * X509_{cert_depth}_{name}={value}
687 */
688void
690{
691 unsigned char c;
692 const mbedtls_x509_name *name;
693 char s[128] = { 0 };
694
695 name = &cert->subject;
696
697 while (name != NULL)
698 {
699 char name_expand[64 + 8];
700 const char *shortname;
701
702 if (0 == mbedtls_oid_get_attr_short_name(&name->oid, &shortname))
703 {
704 snprintf(name_expand, sizeof(name_expand), "X509_%d_%s", cert_depth, shortname);
705 }
706 else
707 {
708 snprintf(name_expand, sizeof(name_expand), "X509_%d_\?\?", cert_depth);
709 }
710
711 size_t i;
712 for (i = 0; i < name->val.len; i++)
713 {
714 if (i >= sizeof(s) - 1)
715 {
716 break;
717 }
718
719 c = name->val.p[i];
720 if (c < 32 || c == 127 || (c > 128 && c < 160))
721 {
722 s[i] = '?';
723 }
724 else
725 {
726 s[i] = c;
727 }
728 }
729 s[i] = '\0';
730
731 /* Check both strings, set environment variable */
733 string_mod((char *)s, CC_PRINT, CC_CRLF, '_');
734 setenv_str_incr(es, name_expand, (char *)s);
735
736 name = name->next;
737 }
738}
739
740/* Dummy function because Netscape certificate types are not supported in OpenVPN with mbedtls.
741 * Returns SUCCESS if usage is NS_CERT_CHECK_NONE, FAILURE otherwise. */
744{
746 {
747 return SUCCESS;
748 }
749
750 return FAILURE;
751}
752
754x509_verify_cert_ku(mbedtls_x509_crt *cert, const unsigned int *const expected_ku, size_t expected_len)
755{
756 msg(D_HANDSHAKE, "Validating certificate key usage");
757
759 {
760 msg(D_TLS_ERRORS, "ERROR: Certificate does not have key usage extension");
761 return FAILURE;
762 }
763
765 {
766 /* Extension required, value checked by TLS library */
767 return SUCCESS;
768 }
769
771 for (size_t i = 0; SUCCESS != fFound && i < expected_len; i++)
772 {
774 {
775 fFound = SUCCESS;
776 }
777 }
778
779 if (fFound != SUCCESS)
780 {
781 msg(D_TLS_ERRORS, "ERROR: Certificate has invalid key usage, expected one of:");
782 for (size_t i = 0; i < expected_len && expected_ku[i]; i++)
783 {
784 msg(D_TLS_ERRORS, " * %04x", expected_ku[i]);
785 }
786 }
787
788 return fFound;
789}
790
792x509_verify_cert_eku(mbedtls_x509_crt *cert, const char *const expected_oid)
793{
795
797 {
798 msg(D_HANDSHAKE, "Certificate does not have extended key usage extension");
799 }
800 else
801 {
802 mbedtls_x509_sequence *oid_seq = &(cert->ext_key_usage);
803
804 msg(D_HANDSHAKE, "Validating certificate extended key usage");
805 while (oid_seq != NULL)
806 {
808 char oid_num_str[1024];
809 const char *oid_str;
810
812 {
813 msg(D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s", oid_str,
816 {
817 fFound = SUCCESS;
818 break;
819 }
820 }
821
823 {
824 msg(D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s", oid_num_str,
827 {
828 fFound = SUCCESS;
829 break;
830 }
831 }
832 oid_seq = oid_seq->next;
833 }
834 }
835
836 return fFound;
837}
838
839bool
840tls_verify_crl_missing(const struct tls_options *opt)
841{
842 if (opt->crl_file && !(opt->ssl_flags & SSLF_CRL_VERIFY_DIR)
843 && (opt->ssl_ctx->crl == NULL || opt->ssl_ctx->crl->version == 0))
844 {
845 return true;
846 }
847 return false;
848}
849
850#endif /* #if defined(ENABLE_CRYPTO_MBEDTLS) */
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
Definition buffer.c:306
void chomp(char *str)
Definition buffer.c:618
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:341
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:88
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)
Definition buffer.c:488
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:1059
bool checked_snprintf(char *str, size_t size, const char *format,...)
Like snprintf() but returns an boolean.
Definition buffer.c:1143
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:653
#define CC_ANY
any character
Definition buffer.h:910
#define BPTR(buf)
Definition buffer.h:124
static bool buf_inc_len(struct buffer *buf, int inc)
Definition buffer.h:590
#define CC_CRLF
carriage return or newline
Definition buffer.h:947
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Definition buffer.h:350
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Definition buffer.h:1157
#define BLEN(buf)
Definition buffer.h:127
static void check_malloc_return(void *p)
Definition buffer.h:1163
static void gc_free(struct gc_arena *a)
Definition buffer.h:1081
#define CC_PRINT
printable (>= 32, != 127)
Definition buffer.h:918
#define FHE_CAPS
Definition buffer.h:500
static struct gc_arena gc_new(void)
Definition buffer.h:1073
bool crypto_pem_encode(const char *name, struct buffer *dst, const struct buffer *src, struct gc_arena *gc)
Encode binary data as PEM.
Data Channel Cryptography backend interface using the TF-PSA-Crypto library part of Mbed TLS 4.
#define mbed_ok(errval)
Check errval and log on error.
Data Channel Cryptography mbed TLS-specific backend interface.
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
int verify_callback(void *session_obj, mbedtls_x509_crt *cert, int cert_depth, uint32_t *flags)
Verify that the remote OpenVPN peer's certificate allows setting up a VPN tunnel.
mbedtls compatibility stub.
X509 openvpn_x509_cert_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
void usage(void)
Definition options.c:4870
#define SSLF_CRL_VERIFY_DIR
Definition ssl_common.h:428
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_NONE
Do not perform Netscape certificate type verification.
Definition ssl_verify.h:250
struct buffer x509_get_sha256_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate's SHA256 fingerprint.
bool x509_username_field_ext_supported(const char *extname)
Return true iff the supplied extension field is supported by the –x509-username-field option.
void x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, openvpn_x509_cert_t *x509)
void x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert)
bool tls_verify_crl_missing(const struct tls_options *opt)
Return true iff a CRL is configured, but is not loaded.
result_t backend_x509_write_pem(openvpn_x509_cert_t *cert, const char *filename)
result_t x509_verify_ns_cert_type(openvpn_x509_cert_t *cert, const int usage)
char * backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc)
struct buffer x509_get_sha1_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate's SHA1 fingerprint.
result_t x509_verify_cert_ku(openvpn_x509_cert_t *x509, const unsigned *const expected_ku, size_t expected_len)
char * x509_get_subject(openvpn_x509_cert_t *cert, struct gc_arena *gc)
char * backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
result_t backend_x509_get_username(char *common_name, size_t cn_len, char *x509_username_field, openvpn_x509_cert_t *peer_cert)
void x509_track_add(const struct x509_track **ll_head, const char *name, msglvl_t msglevel, struct gc_arena *gc)
result_t
Result of verification function.
@ FAILURE
@ SUCCESS
result_t x509_verify_cert_eku(openvpn_x509_cert_t *x509, const char *const expected_oid)
static void do_setenv_x509(struct env_set *es, const char *name, char *value, int depth)
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
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:117
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
mbedtls_x509_crl * crl
Certificate Revocation List.
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
struct env_set * es
struct gc_arena gc
Definition test_ssl.c:133