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-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
9  * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.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, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #elif defined(_MSC_VER)
32 #include "config-msvc.h"
33 #endif
34 
35 #include "syshead.h"
36 
37 #if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL)
38 
39 #include "ssl_verify_openssl.h"
40 
41 #include "error.h"
42 #include "ssl_openssl.h"
43 #include "ssl_verify.h"
44 #include "ssl_verify_backend.h"
45 #include "openssl_compat.h"
46 
47 #include <openssl/x509v3.h>
48 #include <openssl/err.h>
49 
50 int
51 verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
52 {
53  int ret = 0;
54  struct tls_session *session;
55  SSL *ssl;
56  struct gc_arena gc = gc_new();
57 
58  /* get the tls_session pointer */
59  ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
60  ASSERT(ssl);
61  session = (struct tls_session *) SSL_get_ex_data(ssl, mydata_index);
62  ASSERT(session);
63 
64  X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
65  struct buffer cert_hash = x509_get_sha256_fingerprint(current_cert, &gc);
66  cert_hash_remember(session, X509_STORE_CTX_get_error_depth(ctx), &cert_hash);
67 
68  /* did peer present cert which was signed by our root cert? */
69  if (!preverify_ok)
70  {
71  /* get the X509 name */
72  char *subject = x509_get_subject(current_cert, &gc);
73 
74  if (!subject)
75  {
76  subject = "(Failed to retrieve certificate subject)";
77  }
78 
79  /* Log and ignore missing CRL errors */
80  if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL)
81  {
82  msg(D_TLS_DEBUG_LOW, "VERIFY WARNING: depth=%d, %s: %s",
83  X509_STORE_CTX_get_error_depth(ctx),
84  X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)),
85  subject);
86  ret = 1;
87  goto cleanup;
88  }
89 
90  /* Remote site specified a certificate, but it's not correct */
91  msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, error=%s: %s",
92  X509_STORE_CTX_get_error_depth(ctx),
93  X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)),
94  subject);
95 
96  ERR_clear_error();
97 
98  session->verified = false;
99  goto cleanup;
100  }
101 
102  if (SUCCESS != verify_cert(session, current_cert, X509_STORE_CTX_get_error_depth(ctx)))
103  {
104  goto cleanup;
105  }
106 
107  ret = 1;
108 
109 cleanup:
110  gc_free(&gc);
111 
112  return ret;
113 }
114 
115 #ifdef ENABLE_X509ALTUSERNAME
116 bool x509_username_field_ext_supported(const char *fieldname)
117 {
118  int nid = OBJ_txt2nid(fieldname);
119  return nid == NID_subject_alt_name || nid == NID_issuer_alt_name;
120 }
121 
122 static
123 bool
124 extract_x509_extension(X509 *cert, char *fieldname, char *out, int size)
125 {
126  bool retval = false;
127  char *buf = 0;
128 
129  if (!x509_username_field_ext_supported(fieldname))
130  {
132  "ERROR: --x509-username-field 'ext:%s' not supported", fieldname);
133  return false;
134  }
135 
136  int nid = OBJ_txt2nid(fieldname);
137  GENERAL_NAMES *extensions = X509_get_ext_d2i(cert, nid, NULL, NULL);
138  if (extensions)
139  {
140  int numalts;
141  int i;
142  /* get amount of alternatives,
143  * RFC2459 claims there MUST be at least
144  * one, but we don't depend on it...
145  */
146 
147  numalts = sk_GENERAL_NAME_num(extensions);
148 
149  /* loop through all alternatives */
150  for (i = 0; i<numalts; i++)
151  {
152  /* get a handle to alternative name number i */
153  const GENERAL_NAME *name = sk_GENERAL_NAME_value(extensions, i );
154 
155  switch (name->type)
156  {
157  case GEN_EMAIL:
158  if (ASN1_STRING_to_UTF8((unsigned char **)&buf, name->d.ia5) < 0)
159  {
160  continue;
161  }
162  if (strlen(buf) != name->d.ia5->length)
163  {
164  msg(D_TLS_ERRORS, "ASN1 ERROR: string contained terminating zero");
165  OPENSSL_free(buf);
166  }
167  else
168  {
169  strncpynt(out, buf, size);
170  OPENSSL_free(buf);
171  retval = true;
172  }
173  break;
174 
175  default:
176  msg(D_TLS_DEBUG, "%s: ignoring general name field type %i",
177  __func__, name->type);
178  break;
179  }
180  }
181  GENERAL_NAMES_free(extensions);
182  }
183  return retval;
184 }
185 #endif /* ENABLE_X509ALTUSERNAME */
186 
187 /*
188  * Extract a field from an X509 subject name.
189  *
190  * Example:
191  *
192  * /C=US/ST=CO/L=Denver/O=ORG/CN=First-CN/CN=Test-CA/Email=jim@yonan.net
193  *
194  * The common name is 'Test-CA'
195  *
196  * Return true on success, false on error (insufficient buffer size in 'out'
197  * to contain result is grounds for error).
198  */
199 static result_t
200 extract_x509_field_ssl(X509_NAME *x509, const char *field_name, char *out,
201  int size)
202 {
203  int lastpos = -1;
204  int tmp = -1;
205  X509_NAME_ENTRY *x509ne = NULL;
206  ASN1_STRING *asn1 = NULL;
207  unsigned char *buf = NULL;
208  ASN1_OBJECT *field_name_obj = OBJ_txt2obj(field_name, 0);
209 
210  if (field_name_obj == NULL)
211  {
212  msg(D_TLS_ERRORS, "Invalid X509 attribute name '%s'", field_name);
213  return FAILURE;
214  }
215 
216  ASSERT(size > 0);
217  *out = '\0';
218  do
219  {
220  lastpos = tmp;
221  tmp = X509_NAME_get_index_by_OBJ(x509, field_name_obj, lastpos);
222  } while (tmp > -1);
223 
224  ASN1_OBJECT_free(field_name_obj);
225 
226  /* Nothing found */
227  if (lastpos == -1)
228  {
229  return FAILURE;
230  }
231 
232  x509ne = X509_NAME_get_entry(x509, lastpos);
233  if (!x509ne)
234  {
235  return FAILURE;
236  }
237 
238  asn1 = X509_NAME_ENTRY_get_data(x509ne);
239  if (!asn1)
240  {
241  return FAILURE;
242  }
243  if (ASN1_STRING_to_UTF8(&buf, asn1) < 0)
244  {
245  return FAILURE;
246  }
247 
248  strncpynt(out, (char *)buf, size);
249 
250  {
251  const result_t ret = (strlen((char *)buf) < size) ? SUCCESS : FAILURE;
252  OPENSSL_free(buf);
253  return ret;
254  }
255 }
256 
257 result_t
258 backend_x509_get_username(char *common_name, int cn_len,
259  char *x509_username_field, X509 *peer_cert)
260 {
261 #ifdef ENABLE_X509ALTUSERNAME
262  if (strncmp("ext:",x509_username_field,4) == 0)
263  {
264  if (!extract_x509_extension(peer_cert, x509_username_field+4, common_name, cn_len))
265  {
266  return FAILURE;
267  }
268  }
269  else
270 #endif
271  if (FAILURE == extract_x509_field_ssl(X509_get_subject_name(peer_cert),
272  x509_username_field, common_name, cn_len))
273  {
274  return FAILURE;
275  }
276 
277  return SUCCESS;
278 }
279 
280 char *
282 {
283  ASN1_INTEGER *asn1_i;
284  BIGNUM *bignum;
285  char *openssl_serial, *serial;
286 
287  asn1_i = X509_get_serialNumber(cert);
288  bignum = ASN1_INTEGER_to_BN(asn1_i, NULL);
289  openssl_serial = BN_bn2dec(bignum);
290 
291  serial = string_alloc(openssl_serial, gc);
292 
293  BN_free(bignum);
294  OPENSSL_free(openssl_serial);
295 
296  return serial;
297 }
298 
299 char *
301 {
302  const ASN1_INTEGER *asn1_i = X509_get_serialNumber(cert);
303 
304  return format_hex_ex(asn1_i->data, asn1_i->length, 0, 1, ":", gc);
305 }
306 
307 struct buffer
308 x509_get_sha1_fingerprint(X509 *cert, struct gc_arena *gc)
309 {
310  const EVP_MD *sha1 = EVP_sha1();
311  struct buffer hash = alloc_buf_gc(EVP_MD_size(sha1), gc);
312  X509_digest(cert, EVP_sha1(), BPTR(&hash), NULL);
313  ASSERT(buf_inc_len(&hash, EVP_MD_size(sha1)));
314  return hash;
315 }
316 
317 struct buffer
318 x509_get_sha256_fingerprint(X509 *cert, struct gc_arena *gc)
319 {
320  const EVP_MD *sha256 = EVP_sha256();
321  struct buffer hash = alloc_buf_gc(EVP_MD_size(sha256), gc);
322  X509_digest(cert, EVP_sha256(), BPTR(&hash), NULL);
323  ASSERT(buf_inc_len(&hash, EVP_MD_size(sha256)));
324  return hash;
325 }
326 
327 char *
328 x509_get_subject(X509 *cert, struct gc_arena *gc)
329 {
330  BIO *subject_bio = NULL;
331  BUF_MEM *subject_mem;
332  char *subject = NULL;
333 
334  /*
335  * Generate the subject string in OpenSSL proprietary format,
336  * when in --compat-names mode
337  */
339  {
340  subject = gc_malloc(256, false, gc);
341  X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
342  subject[255] = '\0';
343  return subject;
344  }
345 
346  subject_bio = BIO_new(BIO_s_mem());
347  if (subject_bio == NULL)
348  {
349  goto err;
350  }
351 
352  X509_NAME_print_ex(subject_bio, X509_get_subject_name(cert),
353  0, XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN
354  |ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_ESC_CTRL);
355 
356  if (BIO_eof(subject_bio))
357  {
358  goto err;
359  }
360 
361  BIO_get_mem_ptr(subject_bio, &subject_mem);
362 
363  subject = gc_malloc(subject_mem->length + 1, false, gc);
364 
365  memcpy(subject, subject_mem->data, subject_mem->length);
366  subject[subject_mem->length] = '\0';
367 
368 err:
369  if (subject_bio)
370  {
371  BIO_free(subject_bio);
372  }
373 
374  return subject;
375 }
376 
377 
378 /*
379  * x509-track implementation -- save X509 fields to environment,
380  * using the naming convention:
381  *
382  * X509_{cert_depth}_{name}={value}
383  *
384  * This function differs from x509_setenv below in the following ways:
385  *
386  * (1) Only explicitly named attributes in xt are saved, per usage
387  * of "x509-track" program options.
388  * (2) Only the level 0 cert info is saved unless the XT_FULL_CHAIN
389  * flag is set in xt->flags (corresponds with prepending a '+'
390  * to the name when specified by "x509-track" program option).
391  * (3) This function supports both X509 subject name fields as
392  * well as X509 V3 extensions.
393  * (4) This function can return the SHA1 fingerprint of a cert, e.g.
394  * x509-track "+SHA1"
395  * will return the SHA1 fingerprint for each certificate in the
396  * peer chain.
397  */
398 
399 void
400 x509_track_add(const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc)
401 {
402  struct x509_track *xt;
403  ALLOC_OBJ_CLEAR_GC(xt, struct x509_track, gc);
404  if (*name == '+')
405  {
406  xt->flags |= XT_FULL_CHAIN;
407  ++name;
408  }
409  xt->name = name;
410  xt->nid = OBJ_txt2nid(name);
411  if (xt->nid != NID_undef)
412  {
413  xt->next = *ll_head;
414  *ll_head = xt;
415  }
416  else
417  {
418  msg(msglevel, "x509_track: no such attribute '%s'", name);
419  }
420 }
421 
422 /* worker method for setenv_x509_track */
423 static void
424 do_setenv_x509(struct env_set *es, const char *name, char *value, int depth)
425 {
426  char *name_expand;
427  size_t name_expand_size;
428 
429  string_mod(value, CC_ANY, CC_CRLF, '?');
430  msg(D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth);
431  name_expand_size = 64 + strlen(name);
432  name_expand = (char *) malloc(name_expand_size);
433  check_malloc_return(name_expand);
434  openvpn_snprintf(name_expand, name_expand_size, "X509_%d_%s", depth, name);
435  setenv_str(es, name_expand, value);
436  free(name_expand);
437 }
438 
439 void
440 x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, X509 *x509)
441 {
442  struct gc_arena gc = gc_new();
443  X509_NAME *x509_name = X509_get_subject_name(x509);
444  const char nullc = '\0';
445 
446  while (xt)
447  {
448  if (depth == 0 || (xt->flags & XT_FULL_CHAIN))
449  {
450  switch (xt->nid)
451  {
452  case NID_sha1:
453  case NID_sha256:
454  {
455  struct buffer fp_buf;
456  char *fp_str = NULL;
457 
458  if (xt->nid == NID_sha1)
459  {
460  fp_buf = x509_get_sha1_fingerprint(x509, &gc);
461  }
462  else
463  {
464  fp_buf = x509_get_sha256_fingerprint(x509, &gc);
465  }
466 
467  fp_str = format_hex_ex(BPTR(&fp_buf), BLEN(&fp_buf), 0,
468  1 | FHE_CAPS, ":", &gc);
469  do_setenv_x509(es, xt->name, fp_str, depth);
470  }
471  break;
472 
473  default:
474  {
475  int i = X509_NAME_get_index_by_NID(x509_name, xt->nid, -1);
476  if (i >= 0)
477  {
478  X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i);
479  if (ent)
480  {
481  ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent);
482  unsigned char *buf = NULL;
483  if (ASN1_STRING_to_UTF8(&buf, val) >= 0)
484  {
485  do_setenv_x509(es, xt->name, (char *)buf, depth);
486  OPENSSL_free(buf);
487  }
488  }
489  }
490  else
491  {
492  i = X509_get_ext_by_NID(x509, xt->nid, -1);
493  if (i >= 0)
494  {
495  X509_EXTENSION *ext = X509_get_ext(x509, i);
496  if (ext)
497  {
498  BIO *bio = BIO_new(BIO_s_mem());
499  if (bio)
500  {
501  if (X509V3_EXT_print(bio, ext, 0, 0))
502  {
503  if (BIO_write(bio, &nullc, 1) == 1)
504  {
505  char *str;
506  BIO_get_mem_data(bio, &str);
507  do_setenv_x509(es, xt->name, str, depth);
508  }
509  }
510  BIO_free(bio);
511  }
512  }
513  }
514  }
515  }
516  }
517  }
518  xt = xt->next;
519  }
520  gc_free(&gc);
521 }
522 
523 /*
524  * Save X509 fields to environment, using the naming convention:
525  *
526  * X509_{cert_depth}_{name}={value}
527  */
528 void
529 x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert)
530 {
531  int i, n;
532  int fn_nid;
533  ASN1_OBJECT *fn;
534  ASN1_STRING *val;
535  X509_NAME_ENTRY *ent;
536  const char *objbuf;
537  unsigned char *buf = NULL;
538  char *name_expand;
539  size_t name_expand_size;
540  X509_NAME *x509 = X509_get_subject_name(peer_cert);
541 
542  n = X509_NAME_entry_count(x509);
543  for (i = 0; i < n; ++i)
544  {
545  ent = X509_NAME_get_entry(x509, i);
546  if (!ent)
547  {
548  continue;
549  }
550  fn = X509_NAME_ENTRY_get_object(ent);
551  if (!fn)
552  {
553  continue;
554  }
555  val = X509_NAME_ENTRY_get_data(ent);
556  if (!val)
557  {
558  continue;
559  }
560  fn_nid = OBJ_obj2nid(fn);
561  if (fn_nid == NID_undef)
562  {
563  continue;
564  }
565  objbuf = OBJ_nid2sn(fn_nid);
566  if (!objbuf)
567  {
568  continue;
569  }
570  if (ASN1_STRING_to_UTF8(&buf, val) < 0)
571  {
572  continue;
573  }
574  name_expand_size = 64 + strlen(objbuf);
575  name_expand = (char *) malloc(name_expand_size);
576  check_malloc_return(name_expand);
577  openvpn_snprintf(name_expand, name_expand_size, "X509_%d_%s", cert_depth,
578  objbuf);
579  string_mod(name_expand, CC_PRINT, CC_CRLF, '_');
580  string_mod((char *)buf, CC_PRINT, CC_CRLF, '_');
581  setenv_str_incr(es, name_expand, (char *)buf);
582  free(name_expand);
583  OPENSSL_free(buf);
584  }
585 }
586 
587 result_t
589 {
590  if (usage == NS_CERT_CHECK_NONE)
591  {
592  return SUCCESS;
593  }
594  if (usage == NS_CERT_CHECK_CLIENT)
595  {
596  /*
597  * Unfortunately, X509_check_purpose() does some weird thing that
598  * prevent it to take a const argument
599  */
600  result_t result = X509_check_purpose(peer_cert, X509_PURPOSE_SSL_CLIENT, 0) ?
601  SUCCESS : FAILURE;
602 
603  /*
604  * old versions of OpenSSL allow us to make the less strict check we used to
605  * do. If this less strict check pass, warn user that this might not be the
606  * case when its distribution will update to OpenSSL 1.1
607  */
608  if (result == FAILURE)
609  {
610  ASN1_BIT_STRING *ns;
611  ns = X509_get_ext_d2i(peer_cert, NID_netscape_cert_type, NULL, NULL);
612  result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_CLIENT)) ? SUCCESS : FAILURE;
613  if (result == SUCCESS)
614  {
615  msg(M_WARN, "X509: Certificate is a client certificate yet it's purpose "
616  "cannot be verified (check may fail in the future)");
617  }
618  ASN1_BIT_STRING_free(ns);
619  }
620  return result;
621  }
622  if (usage == NS_CERT_CHECK_SERVER)
623  {
624  /*
625  * Unfortunately, X509_check_purpose() does some weird thing that
626  * prevent it to take a const argument
627  */
628  result_t result = X509_check_purpose(peer_cert, X509_PURPOSE_SSL_SERVER, 0) ?
629  SUCCESS : FAILURE;
630 
631  /*
632  * old versions of OpenSSL allow us to make the less strict check we used to
633  * do. If this less strict check pass, warn user that this might not be the
634  * case when its distribution will update to OpenSSL 1.1
635  */
636  if (result == FAILURE)
637  {
638  ASN1_BIT_STRING *ns;
639  ns = X509_get_ext_d2i(peer_cert, NID_netscape_cert_type, NULL, NULL);
640  result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_SERVER)) ? SUCCESS : FAILURE;
641  if (result == SUCCESS)
642  {
643  msg(M_WARN, "X509: Certificate is a server certificate yet it's purpose "
644  "cannot be verified (check may fail in the future)");
645  }
646  ASN1_BIT_STRING_free(ns);
647  }
648  return result;
649  }
650 
651  return FAILURE;
652 }
653 
654 result_t
655 x509_verify_cert_ku(X509 *x509, const unsigned *const expected_ku,
656  int expected_len)
657 {
658  ASN1_BIT_STRING *ku = X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL);
659 
660  if (ku == NULL)
661  {
662  msg(D_TLS_ERRORS, "Certificate does not have key usage extension");
663  return FAILURE;
664  }
665 
666  if (expected_ku[0] == OPENVPN_KU_REQUIRED)
667  {
668  /* Extension required, value checked by TLS library */
669  ASN1_BIT_STRING_free(ku);
670  return SUCCESS;
671  }
672 
673  unsigned nku = 0;
674  for (size_t i = 0; i < 8; i++)
675  {
676  if (ASN1_BIT_STRING_get_bit(ku, i))
677  {
678  nku |= 1 << (7 - i);
679  }
680  }
681 
682  /*
683  * Fixup if no LSB bits
684  */
685  if ((nku & 0xff) == 0)
686  {
687  nku >>= 8;
688  }
689 
690  msg(D_HANDSHAKE, "Validating certificate key usage");
691  result_t fFound = FAILURE;
692  for (size_t i = 0; fFound != SUCCESS && i < expected_len; i++)
693  {
694  if (expected_ku[i] != 0 && (nku & expected_ku[i]) == expected_ku[i])
695  {
696  fFound = SUCCESS;
697  }
698  }
699 
700  if (fFound != SUCCESS)
701  {
703  "ERROR: Certificate has key usage %04x, expected one of:", nku);
704  for (size_t i = 0; i < expected_len && expected_ku[i]; i++)
705  {
706  msg(D_TLS_ERRORS, " * %04x", expected_ku[i]);
707  }
708  }
709 
710  ASN1_BIT_STRING_free(ku);
711 
712  return fFound;
713 }
714 
715 result_t
716 x509_verify_cert_eku(X509 *x509, const char *const expected_oid)
717 {
718  EXTENDED_KEY_USAGE *eku = NULL;
719  result_t fFound = FAILURE;
720 
721  if ((eku = (EXTENDED_KEY_USAGE *) X509_get_ext_d2i(x509, NID_ext_key_usage,
722  NULL, NULL)) == NULL)
723  {
724  msg(D_HANDSHAKE, "Certificate does not have extended key usage extension");
725  }
726  else
727  {
728  int i;
729 
730  msg(D_HANDSHAKE, "Validating certificate extended key usage");
731  for (i = 0; SUCCESS != fFound && i < sk_ASN1_OBJECT_num(eku); i++)
732  {
733  ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(eku, i);
734  char szOid[1024];
735 
736  if (SUCCESS != fFound && OBJ_obj2txt(szOid, sizeof(szOid), oid, 0) != -1)
737  {
738  msg(D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s",
739  szOid, expected_oid);
740  if (!strcmp(expected_oid, szOid))
741  {
742  fFound = SUCCESS;
743  }
744  }
745  if (SUCCESS != fFound && OBJ_obj2txt(szOid, sizeof(szOid), oid, 1) != -1)
746  {
747  msg(D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s",
748  szOid, expected_oid);
749  if (!strcmp(expected_oid, szOid))
750  {
751  fFound = SUCCESS;
752  }
753  }
754  }
755  }
756 
757  if (eku != NULL)
758  {
759  sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
760  }
761 
762  return fFound;
763 }
764 
765 result_t
766 x509_write_pem(FILE *peercert_file, X509 *peercert)
767 {
768  if (PEM_write_X509(peercert_file, peercert) < 0)
769  {
770  msg(M_ERR, "Failed to write peer certificate in PEM format");
771  return FAILURE;
772  }
773  return SUCCESS;
774 }
775 
776 bool
778 {
779  if (!opt->crl_file || (opt->ssl_flags & SSLF_CRL_VERIFY_DIR))
780  {
781  return false;
782  }
783 
784  X509_STORE *store = SSL_CTX_get_cert_store(opt->ssl_ctx.ctx);
785  if (!store)
786  {
787  crypto_msg(M_FATAL, "Cannot get certificate store");
788  }
789 
790  STACK_OF(X509_OBJECT) *objs = X509_STORE_get0_objects(store);
791  for (int i = 0; i < sk_X509_OBJECT_num(objs); i++)
792  {
793  X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i);
794  ASSERT(obj);
795  if (X509_OBJECT_get_type(obj) == X509_LU_CRL)
796  {
797  return false;
798  }
799  }
800  return true;
801 }
802 
803 #endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL) */
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition: buffer.h:343
const char * crl_file
Definition: ssl_common.h:280
#define SSLF_CRL_VERIFY_DIR
Definition: ssl_common.h:337
#define D_TLS_DEBUG_LOW
Definition: errlevel.h:77
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:626
#define D_TLS_DEBUG
Definition: errlevel.h:160
bool tls_verify_crl_missing(const struct tls_options *opt)
Return true iff a CRL is configured, but is not loaded.
static void gc_free(struct gc_arena *a)
Definition: buffer.h:990
struct tls_root_ctx ssl_ctx
Definition: ssl_common.h:238
bool verified
Definition: ssl_common.h:433
#define NS_CERT_CHECK_CLIENT
Do not perform Netscape certificate type verification.
Definition: ssl_verify.h:218
#define D_TLS_ERRORS
Definition: errlevel.h:59
#define CC_PRINT
Definition: buffer.h:882
#define ASSERT(x)
Definition: error.h:221
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: misc.c:586
#define M_FATAL
Definition: error.h:94
#define crypto_msg(flags,...)
Retrieve any OpenSSL errors, then print the supplied error message.
void cert_hash_remember(struct tls_session *session, const int error_depth, const struct buffer *cert_hash)
Definition: ssl_verify.c:249
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition: misc.c:564
void x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert)
result_t verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth)
Definition: ssl_verify.c:665
result_t x509_verify_cert_ku(X509 *x509, const unsigned *const expected_ku, int expected_len)
char * x509_get_subject(X509 *cert, struct gc_arena *gc)
#define D_X509_ATTR
Definition: errlevel.h:104
#define BPTR(buf)
Definition: buffer.h:124
struct buffer x509_get_sha1_fingerprint(X509 *cert, struct gc_arena *gc)
bool openvpn_snprintf(char *str, size_t size, const char *format,...)
Definition: buffer.c:277
static struct gc_arena gc_new(void)
Definition: buffer.h:982
#define COMPAT_NAMES
Definition: misc.h:299
result_t x509_verify_cert_eku(X509 *x509, const char *const expected_oid)
unsigned int flags
Definition: ssl_verify.h:206
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition: buffer.c:346
#define M_ERR
Definition: error.h:110
#define NS_CERT_CHECK_NONE
Do not perform Netscape certificate type verification.
Definition: ssl_verify.h:214
#define COMPAT_FLAG_QUERY
Definition: misc.h:297
static STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *store)
Fetch the X509 object stack from the X509 store.
void x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, X509 *x509)
const struct x509_track * next
Definition: ssl_verify.h:203
static result_t extract_x509_field_ssl(X509_NAME *x509, const char *field_name, char *out, int size)
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Definition: buffer.c:460
struct buffer x509_get_sha256_fingerprint(X509 *cert, struct gc_arena *gc)
const char * name
Definition: ssl_verify.h:204
char * backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc)
#define BLEN(buf)
Definition: buffer.h:127
int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
Verify that the remote OpenVPN peer&#39;s certificate allows setting up a VPN tunnel. ...
char * backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
#define D_HANDSHAKE
Definition: errlevel.h:72
SSL_CTX * ctx
Definition: ssl_openssl.h:39
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Definition: buffer.c:1019
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Definition: buffer.h:1054
static void do_setenv_x509(struct env_set *es, const char *name, char *value, int depth)
static bool buf_inc_len(struct buffer *buf, int inc)
Definition: buffer.h:585
static void check_malloc_return(const void *p)
Definition: buffer.h:1060
static void usage(void)
Definition: options.c:4066
Security parameter state of a single session within a VPN tunnel.
Definition: ssl_common.h:400
#define msg
Definition: error.h:173
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
int mydata_index
Allocate space in SSL objects in which to store a struct tls_session pointer back to parent...
Definition: ssl_openssl.c:69
#define FHE_CAPS
Definition: buffer.h:493
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
Definition: misc.h:49
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
result_t backend_x509_get_username(char *common_name, int cn_len, char *x509_username_field, X509 *peer_cert)
result_t x509_write_pem(FILE *peercert_file, X509 *peercert)
void x509_track_add(const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc)
#define XT_FULL_CHAIN
Definition: ssl_verify.h:205
mbedtls_x509_crt openvpn_x509_cert_t
#define CC_CRLF
Definition: buffer.h:911
#define CC_ANY
Definition: buffer.h:874
bool compat_flag(unsigned int flag)
Will set or query for a global compat flag.
Definition: misc.c:1536
unsigned int ssl_flags
Definition: ssl_common.h:342
#define M_WARN
Definition: error.h:96
result_t x509_verify_ns_cert_type(openvpn_x509_cert_t *peer_cert, const int usage)
static int X509_OBJECT_get_type(const X509_OBJECT *obj)
Get the type of an X509 object.
result_t
Result of verification function.
#define NS_CERT_CHECK_SERVER
Do not perform Netscape certificate type verification.
Definition: ssl_verify.h:216
#define OPENVPN_KU_REQUIRED
Require keyUsage to be present in cert (0xFFFF is an invalid KU value)
Definition: ssl_verify.h:221