35#if defined(ENABLE_CRYPTO_MBEDTLS)
37#include <mbedtls/version.h>
39#if MBEDTLS_VERSION_NUMBER < 0x04000000
41#include <mbedtls/bignum.h>
42#include <mbedtls/sha1.h>
50#include <mbedtls/asn1.h>
51#include <mbedtls/error.h>
52#include <mbedtls/oid.h>
54#define MAX_SUBJECT_LENGTH 256
57verify_callback(
void *session_obj, mbedtls_x509_crt *cert,
int cert_depth, uint32_t *flags)
71 if (
session->opt->verify_hash_no_ca)
113 "VERIFY ERROR: depth=%d, (could not extract X509 "
114 "subject string from certificate): %s",
147 name = &cert->subject;
167 if (
cn_len > name->val.len)
169 memcpy(
cn, name->val.p, name->val.len);
170 cn[name->val.len] =
'\0';
181#if MBEDTLS_VERSION_NUMBER >= 0x04000000
313#if MBEDTLS_VERSION_NUMBER < 0x04000000
320 msg(
M_WARN,
"Failed to retrieve serial from certificate.");
331 msg(
M_WARN,
"Failed to write serial to string.");
343 msg(
M_WARN,
"Failed to write serial to string.");
349 msg(
M_WARN,
"Failed to write serial to string.");
360 size_t len = cert->serial.len * 3 + 1;
406#if defined(__GNUC__) || defined(__clang__)
407#pragma GCC diagnostic push
408#pragma GCC diagnostic ignored "-Wconversion"
414 const size_t md_size = mbedtls_md_get_size(
md_info);
421#if defined(__GNUC__) || defined(__clang__)
422#pragma GCC diagnostic pop
428 return x509_get_fingerprint(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), cert,
gc);
434 return x509_get_fingerprint(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), cert,
gc);
440 char tmp_subject[MAX_SUBJECT_LENGTH] = { 0 };
441 char *subject = NULL;
445 ret = mbedtls_x509_dn_gets(tmp_subject, MAX_SUBJECT_LENGTH - 1, &cert->subject);
459 size_t name_expand_size;
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);
466 snprintf(name_expand, name_expand_size,
"X509_%d_%s", depth, name);
472asn1_buf_to_c_string(
const mbedtls_asn1_buf *orig,
struct gc_arena *
gc)
477 if (!(orig->tag == MBEDTLS_ASN1_UTF8_STRING || orig->tag == MBEDTLS_ASN1_PRINTABLE_STRING
478 || orig->tag == MBEDTLS_ASN1_IA5_STRING))
484 for (i = 0; i < orig->len; ++i)
486 if (orig->p[i] ==
'\0')
492 memcpy(val, orig->p, orig->len);
493 val[orig->len] =
'\0';
498do_setenv_name(
struct env_set *
es,
const struct x509_track *xt,
const mbedtls_x509_crt *cert,
501 const mbedtls_x509_name *xn;
502 for (xn = &cert->subject; xn != NULL; xn = xn->next)
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))
508 char *val_str = asn1_buf_to_c_string(&xn->val,
gc);
532 mbedtls_x509_crt *cert)
539 if (0 == strcmp(xt->
name,
"SHA1") || 0 == strcmp(xt->
name,
"SHA256"))
568#if defined(__GNUC__) || defined(__clang__)
569#pragma GCC diagnostic push
570#pragma GCC diagnostic ignored "-Wsign-compare"
585 name = &cert->subject;
602 for (
i = 0;
i < name->val.len;
i++)
604 if (
i >=
sizeof(s) - 1)
610 if (
c < 32 ||
c == 127 || (
c > 128 &&
c < 160))
650 msg(
D_TLS_ERRORS,
"ERROR: Certificate does not have key usage extension");
671 msg(
D_TLS_ERRORS,
"ERROR: Certificate has invalid key usage, expected one of:");
681#if defined(__GNUC__) || defined(__clang__)
682#pragma GCC diagnostic pop
692 msg(
D_HANDSHAKE,
"Certificate does not have extended key usage extension");
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
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)
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...
bool checked_snprintf(char *str, size_t size, const char *format,...)
Like snprintf() but returns an boolean.
char * string_alloc(const char *str, struct gc_arena *gc)
#define CC_ANY
any character
static bool buf_inc_len(struct buffer *buf, int inc)
#define CC_CRLF
carriage return or newline
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
static void check_malloc_return(void *p)
static void gc_free(struct gc_arena *a)
#define CC_PRINT
printable (>= 32, != 127)
static struct gc_arena gc_new(void)
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)
void setenv_str_incr(struct env_set *es, const char *name, const char *value)
Store the supplied name value pair in the env_set.
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 SSLF_CRL_VERIFY_DIR
result_t verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth)
void cert_hash_remember(struct tls_session *session, const int error_depth, const struct buffer *cert_hash)
Control Channel Verification Module.
#define OPENVPN_KU_REQUIRED
Require keyUsage to be present in cert (0xFFFF is an invalid KU value)
#define NS_CERT_CHECK_NONE
Do not perform Netscape certificate type verification.
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.
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.
int len
Length in bytes of the actual content within the allocated memory.
Structure containing the hash for a single certificate.
Garbage collection arena used to keep track of dynamically allocated memory.
struct tls_root_ctx * ssl_ctx
mbedtls_x509_crl * crl
Certificate Revocation List.
Security parameter state of a single session within a VPN tunnel.
const struct x509_track * next