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
141backend_x509_get_username(char *cn, size_t cn_len, char *x509_username_field, mbedtls_x509_crt *cert)
142{
143 mbedtls_x509_name *name;
144
145 ASSERT(cn != NULL);
146
147 name = &cert->subject;
148
149 /* Find common name */
150 while (name != NULL)
151 {
153 {
154 break;
155 }
156
157 name = name->next;
158 }
159
160 /* Not found, return an error if this is the peer's certificate */
161 if (name == NULL)
162 {
163 return FAILURE;
164 }
165
166 /* Found, extract CN */
167 if (cn_len > name->val.len)
168 {
169 memcpy(cn, name->val.p, name->val.len);
170 cn[name->val.len] = '\0';
171 }
172 else
173 {
174 memcpy(cn, name->val.p, cn_len);
175 cn[cn_len - 1] = '\0';
176 }
177
178 return SUCCESS;
179}
180
181#if MBEDTLS_VERSION_NUMBER >= 0x04000000
182/* Mbed TLS 4 has no function to print the certificate serial number and does
183 * not expose the bignum functions anymore. So in order to write the serial
184 * number as a decimal string, we implement bignum % 10 and bignum / 10. */
185static char
187{
188 int result = 0;
189 for (size_t i = 0; i < bignum_length; i++)
190 {
191 result = (result * 256) % 10;
192 result = (result + bignum[i]) % 10;
193 }
194 return (char)result;
195}
196
197/* Divide bignum by 10 rounded down, in place. */
198static void
200{
201 /*
202 * Some intuition for the algorithm below:
203 *
204 * We want to calculate
205 *
206 * (bignum[0] * 256^n + bignum[1] * 256^(n-1) + ... + bignum[n]) / 10.
207 *
208 * Let remainder = bignum[0] % 10 and carry = remainder * 256.
209 * Then we can write the above as
210 *
211 * (bignum[0] / 10) * 256^n
212 * + ((carry + bignum[1]) * 256^(n-1) + ... + bignum[n]) / 10.
213 *
214 * So now we have the first byte of our result. The second byte will be
215 * (carry + bignum[1]) / 10. Note that this fits into one byte because
216 * 0 <= remainder < 10. We calculate the next remainder and carry as
217 * remainder = (carry + bignum[1]) % 10 and carry = remainder * 256 and
218 * move on to the next byte until we are done.
219 */
220 size_t new_length = 0;
221 int carry = 0;
222 for (size_t i = 0; i < *bignum_length; i++)
223 {
224 uint8_t next_byte = (uint8_t)((bignum[i] + carry) / 10);
225 int remainder = (bignum[i] + carry) % 10;
226 carry = remainder * 256;
227
228 /* Write the byte unless it's a leading zero. */
229 if (new_length != 0 || next_byte != 0)
230 {
232 }
233 }
235}
236
237/* Write the decimal representation of bignum to out, if enough space is available.
238 * Returns the number of bytes needed in out, or 0 on error. To calculate the
239 * necessary buffer size, the function can be called with out = NULL. */
240static size_t
241write_bignum(char *out, size_t out_size, const uint8_t *bignum, size_t bignum_length)
242{
243 if (bignum_length == 0)
244 {
245 /* We want out to be "0". */
246 if (out != NULL)
247 {
248 if (out_size >= 2)
249 {
250 out[0] = '0';
251 out[1] = '\0';
252 }
253 else if (out_size > 0)
254 {
255 out[0] = '\0';
256 }
257 }
258 return 2;
259 }
260
262 if (bignum_copy == NULL)
263 {
264 return 0;
265 }
267
268 size_t bytes_needed = 0;
269 size_t bytes_written = 0;
270 while (bignum_length > 0)
271 {
272 /* We're writing the digits in reverse order. We put them in the right order later. */
274 if (out != NULL && bytes_written < out_size - 1)
275 {
276 out[bytes_written++] = '0' + (char)digit;
277 }
278 bytes_needed += 1;
280 }
281
282 if (out != NULL)
283 {
285 {
286 /* We had space for all digits. Now reverse them. */
287 for (size_t i = 0; i < bytes_written / 2; i++)
288 {
289 char tmp = out[i];
290 out[i] = out[bytes_written - 1 - i];
291 out[bytes_written - 1 - i] = tmp;
292 }
293 out[bytes_written] = '\0';
294 }
295 else if (out_size > 0)
296 {
297 out[0] = '\0';
298 }
299 }
300 bytes_needed += 1;
301
302 free(bignum_copy);
303 return bytes_needed;
304}
305#endif /* MBEDTLS_VERSION_NUMBER >= 0x04000000 */
306
307char *
309{
310 char *buf = NULL;
311 size_t buflen = 0;
312
313#if MBEDTLS_VERSION_NUMBER < 0x04000000
314 mbedtls_mpi serial_mpi = { 0 };
315
316 /* Transform asn1 integer serial into mbed TLS MPI */
318 if (!mbed_ok(mbedtls_mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len)))
319 {
320 msg(M_WARN, "Failed to retrieve serial from certificate.");
321 goto end;
322 }
323
324 /* Determine decimal representation length, allocate buffer */
326 buf = gc_malloc(buflen, true, gc);
327
328 /* Write MPI serial as decimal string into buffer */
330 {
331 msg(M_WARN, "Failed to write serial to string.");
332 buf = NULL;
333 goto end;
334 }
335
336end:
338 return buf;
339#else
340 buflen = write_bignum(NULL, 0, cert->serial.p, cert->serial.len);
341 if (buflen == 0)
342 {
343 msg(M_WARN, "Failed to write serial to string.");
344 return NULL;
345 }
346 buf = gc_malloc(buflen, true, gc);
347 if (write_bignum(buf, buflen, cert->serial.p, cert->serial.len) != buflen)
348 {
349 msg(M_WARN, "Failed to write serial to string.");
350 return NULL;
351 }
352 return buf;
353#endif /* MBEDTLS_VERSION_NUMBER < 0x04000000 */
354}
355
356char *
358{
359 char *buf = NULL;
360 size_t len = cert->serial.len * 3 + 1;
361
362 buf = gc_malloc(len, true, gc);
363
364 if (mbedtls_x509_serial_gets(buf, len - 1, &cert->serial) < 0)
365 {
366 buf = NULL;
367 }
368
369 return buf;
370}
371
373backend_x509_write_pem(openvpn_x509_cert_t *cert, const char *filename)
374{
375 /* mbed TLS does not make it easy to write a certificate in PEM format.
376 * The only way is to directly access the DER encoded raw certificate
377 * and PEM encode it ourselves */
378
379 struct gc_arena gc = gc_new();
380 /* just do a very loose upper bound for the base64 based PEM encoding
381 * using 3 times the space for the base64 and 100 bytes for the
382 * headers and footer */
383 struct buffer pem = alloc_buf_gc(cert->raw.len * 3 + 100, &gc);
384
385 struct buffer der = { 0 };
386 buf_set_read(&der, cert->raw.p, cert->raw.len);
387
388 if (!crypto_pem_encode("CERTIFICATE", &pem, &der, &gc))
389 {
390 goto err;
391 }
392
393 if (!buffer_write_file(filename, &pem))
394 {
395 goto err;
396 }
397
398 gc_free(&gc);
399 return SUCCESS;
400err:
401 msg(D_TLS_DEBUG_LOW, "Error writing X509 certificate to file %s", filename);
402 gc_free(&gc);
403 return FAILURE;
404}
405
406#if defined(__GNUC__) || defined(__clang__)
407#pragma GCC diagnostic push
408#pragma GCC diagnostic ignored "-Wconversion"
409#endif
410
411static struct buffer
413{
414 const size_t md_size = mbedtls_md_get_size(md_info);
416 mbedtls_md(md_info, cert->raw.p, cert->raw.len, BPTR(&fingerprint));
418 return fingerprint;
419}
420
421#if defined(__GNUC__) || defined(__clang__)
422#pragma GCC diagnostic pop
423#endif
424
425struct buffer
427{
428 return x509_get_fingerprint(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), cert, gc);
429}
430
431struct buffer
433{
434 return x509_get_fingerprint(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), cert, gc);
435}
436
437char *
438x509_get_subject(mbedtls_x509_crt *cert, struct gc_arena *gc)
439{
440 char tmp_subject[MAX_SUBJECT_LENGTH] = { 0 };
441 char *subject = NULL;
442
443 int ret = 0;
444
445 ret = mbedtls_x509_dn_gets(tmp_subject, MAX_SUBJECT_LENGTH - 1, &cert->subject);
446 if (ret > 0)
447 {
448 /* Allocate the required space for the subject */
449 subject = string_alloc(tmp_subject, gc);
450 }
451
452 return subject;
453}
454
455static void
456do_setenv_x509(struct env_set *es, const char *name, char *value, int depth)
457{
458 char *name_expand;
459 size_t name_expand_size;
460
461 string_mod(value, CC_ANY, CC_CRLF, '?');
462 msg(D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth);
463 name_expand_size = 64 + strlen(name);
464 name_expand = (char *)malloc(name_expand_size);
465 check_malloc_return(name_expand);
466 snprintf(name_expand, name_expand_size, "X509_%d_%s", depth, name);
467 setenv_str(es, name_expand, value);
468 free(name_expand);
469}
470
471static char *
472asn1_buf_to_c_string(const mbedtls_asn1_buf *orig, struct gc_arena *gc)
473{
474 size_t i;
475 char *val;
476
477 if (!(orig->tag == MBEDTLS_ASN1_UTF8_STRING || orig->tag == MBEDTLS_ASN1_PRINTABLE_STRING
478 || orig->tag == MBEDTLS_ASN1_IA5_STRING))
479 {
480 /* Only support C-string compatible types */
481 return string_alloc("ERROR: unsupported ASN.1 string type", gc);
482 }
483
484 for (i = 0; i < orig->len; ++i)
485 {
486 if (orig->p[i] == '\0')
487 {
488 return string_alloc("ERROR: embedded null value", gc);
489 }
490 }
491 val = gc_malloc(orig->len + 1, false, gc);
492 memcpy(val, orig->p, orig->len);
493 val[orig->len] = '\0';
494 return val;
495}
496
497static void
498do_setenv_name(struct env_set *es, const struct x509_track *xt, const mbedtls_x509_crt *cert,
499 int depth, struct gc_arena *gc)
500{
501 const mbedtls_x509_name *xn;
502 for (xn = &cert->subject; xn != NULL; xn = xn->next)
503 {
504 const char *xn_short_name = NULL;
505 if (0 == mbedtls_oid_get_attr_short_name(&xn->oid, &xn_short_name)
506 && 0 == strcmp(xt->name, xn_short_name))
507 {
508 char *val_str = asn1_buf_to_c_string(&xn->val, gc);
509 do_setenv_x509(es, xt->name, val_str, depth);
510 }
511 }
512}
513
514void
515x509_track_add(const struct x509_track **ll_head, const char *name, msglvl_t msglevel,
516 struct gc_arena *gc)
517{
518 struct x509_track *xt;
519 ALLOC_OBJ_CLEAR_GC(xt, struct x509_track, gc);
520 if (*name == '+')
521 {
522 xt->flags |= XT_FULL_CHAIN;
523 ++name;
524 }
525 xt->name = name;
526 xt->next = *ll_head;
527 *ll_head = xt;
528}
529
530void
531x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth,
532 mbedtls_x509_crt *cert)
533{
534 struct gc_arena gc = gc_new();
535 while (xt)
536 {
537 if (depth == 0 || (xt->flags & XT_FULL_CHAIN))
538 {
539 if (0 == strcmp(xt->name, "SHA1") || 0 == strcmp(xt->name, "SHA256"))
540 {
541 /* Fingerprint is not part of X509 structure */
542 struct buffer cert_hash;
543 char *fingerprint;
544
545 if (0 == strcmp(xt->name, "SHA1"))
546 {
548 }
549 else
550 {
552 }
553
555 format_hex_ex(BPTR(&cert_hash), BLEN(&cert_hash), 0, 1 | FHE_CAPS, ":", &gc);
557 }
558 else
559 {
560 do_setenv_name(es, xt, cert, depth, &gc);
561 }
562 }
563 xt = xt->next;
564 }
565 gc_free(&gc);
566}
567
568#if defined(__GNUC__) || defined(__clang__)
569#pragma GCC diagnostic push
570#pragma GCC diagnostic ignored "-Wsign-compare"
571#endif
572
573/*
574 * Save X509 fields to environment, using the naming convention:
575 *
576 * X509_{cert_depth}_{name}={value}
577 */
578void
580{
581 unsigned char c;
582 const mbedtls_x509_name *name;
583 char s[128] = { 0 };
584
585 name = &cert->subject;
586
587 while (name != NULL)
588 {
589 char name_expand[64 + 8];
590 const char *shortname;
591
592 if (0 == mbedtls_oid_get_attr_short_name(&name->oid, &shortname))
593 {
594 snprintf(name_expand, sizeof(name_expand), "X509_%d_%s", cert_depth, shortname);
595 }
596 else
597 {
598 snprintf(name_expand, sizeof(name_expand), "X509_%d_\?\?", cert_depth);
599 }
600
601 size_t i;
602 for (i = 0; i < name->val.len; i++)
603 {
604 if (i >= sizeof(s) - 1)
605 {
606 break;
607 }
608
609 c = name->val.p[i];
610 if (c < 32 || c == 127 || (c > 128 && c < 160))
611 {
612 s[i] = '?';
613 }
614 else
615 {
616 s[i] = c;
617 }
618 }
619 s[i] = '\0';
620
621 /* Check both strings, set environment variable */
623 string_mod((char *)s, CC_PRINT, CC_CRLF, '_');
624 setenv_str_incr(es, name_expand, (char *)s);
625
626 name = name->next;
627 }
628}
629
630/* Dummy function because Netscape certificate types are not supported in OpenVPN with mbedtls.
631 * Returns SUCCESS if usage is NS_CERT_CHECK_NONE, FAILURE otherwise. */
634{
636 {
637 return SUCCESS;
638 }
639
640 return FAILURE;
641}
642
644x509_verify_cert_ku(mbedtls_x509_crt *cert, const unsigned int *const expected_ku, size_t expected_len)
645{
646 msg(D_HANDSHAKE, "Validating certificate key usage");
647
649 {
650 msg(D_TLS_ERRORS, "ERROR: Certificate does not have key usage extension");
651 return FAILURE;
652 }
653
655 {
656 /* Extension required, value checked by TLS library */
657 return SUCCESS;
658 }
659
661 for (size_t i = 0; SUCCESS != fFound && i < expected_len; i++)
662 {
664 {
665 fFound = SUCCESS;
666 }
667 }
668
669 if (fFound != SUCCESS)
670 {
671 msg(D_TLS_ERRORS, "ERROR: Certificate has invalid key usage, expected one of:");
672 for (size_t i = 0; i < expected_len && expected_ku[i]; i++)
673 {
674 msg(D_TLS_ERRORS, " * %04x", expected_ku[i]);
675 }
676 }
677
678 return fFound;
679}
680
681#if defined(__GNUC__) || defined(__clang__)
682#pragma GCC diagnostic pop
683#endif
684
686x509_verify_cert_eku(mbedtls_x509_crt *cert, const char *const expected_oid)
687{
689
691 {
692 msg(D_HANDSHAKE, "Certificate does not have extended key usage extension");
693 }
694 else
695 {
696 mbedtls_x509_sequence *oid_seq = &(cert->ext_key_usage);
697
698 msg(D_HANDSHAKE, "Validating certificate extended key usage");
699 while (oid_seq != NULL)
700 {
702 char oid_num_str[1024];
703 const char *oid_str;
704
706 {
707 msg(D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s", oid_str,
710 {
711 fFound = SUCCESS;
712 break;
713 }
714 }
715
717 {
718 msg(D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s", oid_num_str,
721 {
722 fFound = SUCCESS;
723 break;
724 }
725 }
726 oid_seq = oid_seq->next;
727 }
728 }
729
730 return fFound;
731}
732
733bool
734tls_verify_crl_missing(const struct tls_options *opt)
735{
736 if (opt->crl_file && !(opt->ssl_flags & SSLF_CRL_VERIFY_DIR)
737 && (opt->ssl_ctx->crl == NULL || opt->ssl_ctx->crl->version == 0))
738 {
739 return true;
740 }
741 return false;
742}
743
744#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:89
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:878
#define BPTR(buf)
Definition buffer.h:123
static bool buf_inc_len(struct buffer *buf, int inc)
Definition buffer.h:589
#define CC_CRLF
carriage return or newline
Definition buffer.h:915
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Definition buffer.h:349
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Definition buffer.h:1125
#define BLEN(buf)
Definition buffer.h:126
static void check_malloc_return(void *p)
Definition buffer.h:1131
static void gc_free(struct gc_arena *a)
Definition buffer.h:1049
#define CC_PRINT
printable (>= 32, != 127)
Definition buffer.h:886
#define FHE_CAPS
Definition buffer.h:499
static struct gc_arena gc_new(void)
Definition buffer.h:1041
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.
#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:4820
#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:577
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)
Definition test_pkcs11.c:68
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)
mbedtls_x509_crt openvpn_x509_cert_t
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:60
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
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:116
unsigned int ssl_flags
Definition ssl_common.h:434
struct tls_root_ctx * ssl_ctx
Definition ssl_common.h:311
const char * crl_file
Definition ssl_common.h:356
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:131