35#if defined(ENABLE_CRYPTO_OPENSSL)
45#include <openssl/bn.h>
46#include <openssl/err.h>
47#include <openssl/x509v3.h>
58 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
63 X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
68 if (!preverify_ok && !
session->opt->verify_hash_no_ca)
76 subject =
"(Failed to retrieve certificate subject)";
80 if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL)
83 X509_STORE_CTX_get_error_depth(ctx),
84 X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)), subject);
91 X509_STORE_CTX_get_error_depth(ctx),
92 X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)), subject,
93 serial ? serial :
"<not available>");
117 int nid = OBJ_txt2nid(fieldname);
118 return nid == NID_subject_alt_name || nid == NID_issuer_alt_name;
128 msg(
D_TLS_ERRORS,
"ERROR: --x509-username-field 'ext:%s' not supported", fieldname);
132 int nid = OBJ_txt2nid(fieldname);
133 GENERAL_NAMES *extensions = X509_get_ext_d2i(cert, nid, NULL, NULL);
147 const GENERAL_NAME *name = sk_GENERAL_NAME_value(extensions, i);
153 if (ASN1_STRING_to_UTF8((
unsigned char **)&buf, name->d.rfc822Name) < 0)
157 if ((ssize_t)strlen(buf) != ASN1_STRING_length(name->d.rfc822Name))
171 msg(
D_TLS_DEBUG,
"%s: ignoring general name field type %d", __func__,
176 GENERAL_NAMES_free(extensions);
198 unsigned char *buf = NULL;
201 ASN1_OBJECT *field_name_obj = OBJ_txt2obj(field_name, 0);
202 if (field_name_obj == NULL)
213#if OPENSSL_VERSION_NUMBER >= 0x30000000L
214 tmp = X509_NAME_get_index_by_OBJ(x509, field_name_obj, lastpos);
217 tmp = X509_NAME_get_index_by_OBJ((X509_NAME *)x509, field_name_obj, lastpos);
221 ASN1_OBJECT_free(field_name_obj);
229 const X509_NAME_ENTRY *x509ne = X509_NAME_get_entry(x509, lastpos);
235 const ASN1_STRING *asn1 = X509_NAME_ENTRY_get_data(x509ne);
240 int length = ASN1_STRING_to_UTF8(&buf, asn1);
241 if (length < 0 || (
size_t)length != strlen((
char *)buf))
258 if (strncmp(
"ext:", x509_username_field, 4) == 0)
265 else if (strcmp(LN_serialNumber, x509_username_field) == 0)
267 const ASN1_INTEGER *asn1_i = X509_get_serialNumber(peer_cert);
269 BIGNUM *bn_serial = ASN1_INTEGER_to_BN(asn1_i, NULL);
270 char *serial = BN_bn2hex(bn_serial);
273 if (!serial || cn_len <= strlen(serial) + 2)
275 OPENSSL_free(serial);
278 snprintf(common_name, cn_len,
"0x%s", serial);
279 OPENSSL_free(serial);
283 const X509_NAME *x509_subject_name = X509_get_subject_name(peer_cert);
284 if (x509_subject_name == NULL)
292 common_name, cn_len))
304 ASN1_INTEGER *asn1_i;
306 char *openssl_serial, *serial;
308 asn1_i = X509_get_serialNumber(cert);
309 bignum = ASN1_INTEGER_to_BN(asn1_i, NULL);
310 openssl_serial = BN_bn2dec(bignum);
315 OPENSSL_free(openssl_serial);
323 const ASN1_INTEGER *asn1_i = X509_get_serialNumber(cert);
324 BIGNUM *bn_serial = ASN1_INTEGER_to_BN(asn1_i, NULL);
325 int len_serial = BN_num_bytes(bn_serial);
326 unsigned char *buf = malloc(len_serial);
327 BN_bn2binpad(bn_serial, buf, len_serial);
339 BIO *out = BIO_new_file(filename,
"w");
345 if (!PEM_write_bio_X509(out, cert))
361 const EVP_MD *sha1 = EVP_sha1();
363 X509_digest(cert, EVP_sha1(),
BPTR(&
hash), NULL);
371 const EVP_MD *sha256 = EVP_sha256();
373 X509_digest(cert, EVP_sha256(),
BPTR(&
hash), NULL);
381 BIO *subject_bio = NULL;
382 BUF_MEM *subject_mem;
383 char *subject = NULL;
385 subject_bio = BIO_new(BIO_s_mem());
386 if (subject_bio == NULL)
391 X509_NAME_print_ex(subject_bio, X509_get_subject_name(cert), 0,
392 XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN | ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_UTF8_CONVERT);
394 if (BIO_eof(subject_bio))
399 BIO_get_mem_ptr(subject_bio, &subject_mem);
402 for (
size_t i = 0; i < subject_mem->length; i++)
404 if (subject_mem->data[i] == 0)
406 msg(
M_WARN,
"ERROR: Certificate subject contains a '\\0' byte.");
411 subject =
gc_malloc(subject_mem->length + 1,
false,
gc);
413 memcpy(subject, subject_mem->data, subject_mem->length);
414 subject[subject_mem->length] =
'\0';
417 BIO_free(subject_bio);
456 if (xt->
nid != NID_undef)
463 msg(msglevel,
"x509_track: no such attribute '%s'",
name);
472 size_t name_expand_size;
476 name_expand_size = 64 + strlen(
name);
477 name_expand = (
char *)malloc(name_expand_size);
479 snprintf(name_expand, name_expand_size,
"X509_%d_%s", depth,
name);
488#if OPENSSL_VERSION_NUMBER < 0x30000000L
490 X509_NAME *x509_name = X509_get_subject_name(x509);
492 const X509_NAME *x509_name = X509_get_subject_name(x509);
494 const char nullc =
'\0';
508 if (xt->
nid == NID_sha1)
524 int i = X509_NAME_get_index_by_NID(x509_name, xt->
nid, -1);
527 const X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i);
530 const ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent);
531 unsigned char *buf = NULL;
532 if (ASN1_STRING_to_UTF8(&buf, val) >= 0)
541 i = X509_get_ext_by_NID(x509, xt->
nid, -1);
544#if OPENSSL_VERSION_NUMBER < 0x40000000L
545 X509_EXTENSION *ext = X509_get_ext(x509, i);
547 const X509_EXTENSION *ext = X509_get_ext(x509, i);
551 BIO *bio = BIO_new(BIO_s_mem());
554 if (X509V3_EXT_print(bio, ext, 0, 0))
556 if (BIO_write(bio, &nullc, 1) == 1)
559 BIO_get_mem_data(bio, &str);
584 const X509_NAME *x509 = X509_get_subject_name(peer_cert);
586 int n = X509_NAME_entry_count(x509);
587 for (
int i = 0; i < n; ++i)
589 const X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509, i);
594 const ASN1_OBJECT *fn = X509_NAME_ENTRY_get_object(ent);
599 const ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent);
604 int fn_nid = OBJ_obj2nid(fn);
605 if (fn_nid == NID_undef)
609 const char *objbuf = OBJ_nid2sn(fn_nid);
614 unsigned char *buf = NULL;
615 if (ASN1_STRING_to_UTF8(&buf, val) < 0)
619 size_t name_expand_size = 64 + strlen(objbuf);
620 char *name_expand = malloc(name_expand_size);
622 snprintf(name_expand, name_expand_size,
"X509_%d_%s", cert_depth, objbuf);
645 X509_check_purpose(peer_cert, X509_PURPOSE_SSL_CLIENT, 0) ?
SUCCESS :
FAILURE;
659 ns = X509_get_ext_d2i(peer_cert, NID_netscape_cert_type, NULL, NULL);
664 msg(
M_WARN,
"X509: Certificate is a client certificate yet it's purpose "
665 "cannot be verified (check may fail in the future)");
667 ASN1_BIT_STRING_free(ns);
678 X509_check_purpose(peer_cert, X509_PURPOSE_SSL_SERVER, 0) ?
SUCCESS :
FAILURE;
692 ASN1_BIT_STRING *ns = X509_get_ext_d2i(peer_cert, NID_netscape_cert_type, NULL, NULL);
697 msg(
M_WARN,
"X509: Certificate is a server certificate yet it's purpose "
698 "cannot be verified (check may fail in the future)");
700 ASN1_BIT_STRING_free(ns);
711 ASN1_BIT_STRING *ku = X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL);
722 ASN1_BIT_STRING_free(ku);
726 unsigned int nku = 0;
727 for (
int i = 0; i < 8; i++)
729 if (ASN1_BIT_STRING_get_bit(ku, i))
738 if ((nku & 0xff) == 0)
745 for (
size_t i = 0; fFound !=
SUCCESS && i < expected_len; i++)
747 if (expected_ku[i] != 0 && (nku & expected_ku[i]) == expected_ku[i])
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++)
762 ASN1_BIT_STRING_free(ku);
770 EXTENDED_KEY_USAGE *eku = NULL;
773 if ((eku = (EXTENDED_KEY_USAGE *)X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL)) == NULL)
775 msg(
D_HANDSHAKE,
"Certificate does not have extended key usage extension");
782 ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(eku, i);
785 if (
SUCCESS != fFound && OBJ_obj2txt(szOid,
sizeof(szOid), oid, 0) != -1)
787 msg(
D_HANDSHAKE,
"++ Certificate has EKU (str) %s, expects %s", szOid,
789 if (!strcmp(expected_oid, szOid))
794 if (
SUCCESS != fFound && OBJ_obj2txt(szOid,
sizeof(szOid), oid, 1) != -1)
796 msg(
D_HANDSHAKE,
"++ Certificate has EKU (oid) %s, expects %s", szOid,
798 if (!strcmp(expected_oid, szOid))
808 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
822 return opt->
ssl_ctx->crls == NULL || sk_X509_CRL_num(opt->
ssl_ctx->crls) == 0;
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Allocate memory and, optionally, zero it.
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
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.
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...
char * string_alloc(const char *str, struct gc_arena *gc)
Duplicate a string, allocating memory under garbage collection.
#define CC_ANY
any character
#define BPTR(buf)
Return a pointer to the start of the buffer content.
static bool buf_inc_len(struct buffer *buf, int inc)
Increase or decrease the length of a buffer.
#define CC_CRLF
carriage return or newline
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Allocate and zero-initialise a garbage-collected object of the given type.
#define BLEN(buf)
Return the length of the buffer content in bytes.
static void strncpynt(char *dest, const char *src, size_t maxlen)
Like strncpy() but always null-terminates the destination.
static void check_malloc_return(void *p)
Abort if a memory allocation returned NULL.
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
#define CC_PRINT
printable (>= 32, != 127)
#define FHE_CAPS
Flag for format_hex_ex(): output hex digits in upper case.
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
#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)
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(int preverify_ok, X509_STORE_CTX *ctx)
Verify that the remote OpenVPN peer's certificate allows setting up a VPN tunnel.
OpenSSL compatibility stub.
#define SSLF_CRL_VERIFY_DIR
int mydata_index
Allocate space in SSL objects in which to store a struct tls_session pointer back to parent.
Control Channel OpenSSL Backend.
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_CLIENT
Do not perform Netscape certificate type verification.
#define NS_CERT_CHECK_NONE
Do not perform Netscape certificate type verification.
#define NS_CERT_CHECK_SERVER
Do not perform Netscape certificate type verification.
Control Channel Verification Module library-specific backend interface.
struct buffer x509_get_sha256_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate's SHA256 fingerprint.
struct buffer x509_get_sha1_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate's SHA1 fingerprint.
result_t
Result of verification function.
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.
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
Security parameter state of a single session within a VPN tunnel.
const struct x509_track * next
static int cleanup(void **state)