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-2018 OpenVPN Inc <sales@openvpn.net>
9  * Copyright (C) 2010-2018 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_MBEDTLS)
38 
39 #include "crypto_mbedtls.h"
40 #include "ssl_verify.h"
41 #include <mbedtls/asn1.h>
42 #include <mbedtls/error.h>
43 #include <mbedtls/bignum.h>
44 #include <mbedtls/oid.h>
45 #include <mbedtls/sha1.h>
46 
47 #define MAX_SUBJECT_LENGTH 256
48 
49 int
50 verify_callback(void *session_obj, mbedtls_x509_crt *cert, int cert_depth,
51  uint32_t *flags)
52 {
53  struct tls_session *session = (struct tls_session *) session_obj;
54  struct gc_arena gc = gc_new();
55 
56  ASSERT(cert);
57  ASSERT(session);
58 
59  session->verified = false;
60 
61  /* Remember certificate hash */
62  struct buffer cert_fingerprint = x509_get_sha256_fingerprint(cert, &gc);
63  cert_hash_remember(session, cert_depth, &cert_fingerprint);
64 
65  /* did peer present cert which was signed by our root cert? */
66  if (*flags != 0)
67  {
68  int ret = 0;
69  char errstr[512] = { 0 };
70  char *subject = x509_get_subject(cert, &gc);
71 
72  ret = mbedtls_x509_crt_verify_info(errstr, sizeof(errstr)-1, "", *flags);
73  if (ret <= 0 && !openvpn_snprintf(errstr, sizeof(errstr),
74  "Could not retrieve error string, flags=%" PRIx32, *flags))
75  {
76  errstr[0] = '\0';
77  }
78  else
79  {
80  chomp(errstr);
81  }
82 
83  if (subject)
84  {
85  msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, subject=%s: %s",
86  cert_depth, subject, errstr);
87  }
88  else
89  {
90  msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, (could not extract X509 "
91  "subject string from certificate): %s", cert_depth, errstr);
92  }
93 
94  /* Leave flags set to non-zero to indicate that the cert is not ok */
95  }
96  else if (SUCCESS != verify_cert(session, cert, cert_depth))
97  {
98  *flags |= MBEDTLS_X509_BADCERT_OTHER;
99  }
100 
101  gc_free(&gc);
102 
103  /*
104  * PolarSSL/mbed TLS-1.2.0+ expects 0 on anything except fatal errors.
105  */
106  return 0;
107 }
108 
109 #ifdef ENABLE_X509ALTUSERNAME
110 #warning "X509 alt user name not yet supported for mbed TLS"
111 #endif
112 
113 result_t
114 backend_x509_get_username(char *cn, int cn_len,
115  char *x509_username_field, mbedtls_x509_crt *cert)
116 {
117  mbedtls_x509_name *name;
118 
119  ASSERT( cn != NULL );
120 
121  name = &cert->subject;
122 
123  /* Find common name */
124  while (name != NULL)
125  {
126  if (0 == memcmp(name->oid.p, MBEDTLS_OID_AT_CN,
127  MBEDTLS_OID_SIZE(MBEDTLS_OID_AT_CN)))
128  {
129  break;
130  }
131 
132  name = name->next;
133  }
134 
135  /* Not found, return an error if this is the peer's certificate */
136  if (name == NULL)
137  {
138  return FAILURE;
139  }
140 
141  /* Found, extract CN */
142  if (cn_len > name->val.len)
143  {
144  memcpy( cn, name->val.p, name->val.len );
145  cn[name->val.len] = '\0';
146  }
147  else
148  {
149  memcpy( cn, name->val.p, cn_len);
150  cn[cn_len-1] = '\0';
151  }
152 
153  return SUCCESS;
154 }
155 
156 char *
157 backend_x509_get_serial(mbedtls_x509_crt *cert, struct gc_arena *gc)
158 {
159  char *buf = NULL;
160  size_t buflen = 0;
161  mbedtls_mpi serial_mpi = { 0 };
162 
163  /* Transform asn1 integer serial into mbed TLS MPI */
164  mbedtls_mpi_init(&serial_mpi);
165  if (!mbed_ok(mbedtls_mpi_read_binary(&serial_mpi, cert->serial.p,
166  cert->serial.len)))
167  {
168  msg(M_WARN, "Failed to retrieve serial from certificate.");
169  goto end;
170  }
171 
172  /* Determine decimal representation length, allocate buffer */
173  mbedtls_mpi_write_string(&serial_mpi, 10, NULL, 0, &buflen);
174  buf = gc_malloc(buflen, true, gc);
175 
176  /* Write MPI serial as decimal string into buffer */
177  if (!mbed_ok(mbedtls_mpi_write_string(&serial_mpi, 10, buf, buflen, &buflen)))
178  {
179  msg(M_WARN, "Failed to write serial to string.");
180  buf = NULL;
181  goto end;
182  }
183 
184 end:
185  mbedtls_mpi_free(&serial_mpi);
186  return buf;
187 }
188 
189 char *
190 backend_x509_get_serial_hex(mbedtls_x509_crt *cert, struct gc_arena *gc)
191 {
192  char *buf = NULL;
193  size_t len = cert->serial.len * 3 + 1;
194 
195  buf = gc_malloc(len, true, gc);
196 
197  if (mbedtls_x509_serial_gets(buf, len-1, &cert->serial) < 0)
198  {
199  buf = NULL;
200  }
201 
202  return buf;
203 }
204 
205 static struct buffer
206 x509_get_fingerprint(const mbedtls_md_info_t *md_info, mbedtls_x509_crt *cert,
207  struct gc_arena *gc)
208 {
209  const size_t md_size = mbedtls_md_get_size(md_info);
210  struct buffer fingerprint = alloc_buf_gc(md_size, gc);
211  mbedtls_md(md_info, cert->raw.p, cert->raw.len, BPTR(&fingerprint));
212  ASSERT(buf_inc_len(&fingerprint, md_size));
213  return fingerprint;
214 }
215 
216 struct buffer
217 x509_get_sha1_fingerprint(mbedtls_x509_crt *cert, struct gc_arena *gc)
218 {
219  return x509_get_fingerprint(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1),
220  cert, gc);
221 }
222 
223 struct buffer
224 x509_get_sha256_fingerprint(mbedtls_x509_crt *cert, struct gc_arena *gc)
225 {
226  return x509_get_fingerprint(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
227  cert, gc);
228 }
229 
230 char *
231 x509_get_subject(mbedtls_x509_crt *cert, struct gc_arena *gc)
232 {
233  char tmp_subject[MAX_SUBJECT_LENGTH] = {0};
234  char *subject = NULL;
235 
236  int ret = 0;
237 
238  ret = mbedtls_x509_dn_gets( tmp_subject, MAX_SUBJECT_LENGTH-1, &cert->subject );
239  if (ret > 0)
240  {
241  /* Allocate the required space for the subject */
242  subject = string_alloc(tmp_subject, gc);
243  }
244 
245  return subject;
246 }
247 
248 static void
249 do_setenv_x509(struct env_set *es, const char *name, char *value, int depth)
250 {
251  char *name_expand;
252  size_t name_expand_size;
253 
254  string_mod(value, CC_ANY, CC_CRLF, '?');
255  msg(D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth);
256  name_expand_size = 64 + strlen(name);
257  name_expand = (char *) malloc(name_expand_size);
258  check_malloc_return(name_expand);
259  openvpn_snprintf(name_expand, name_expand_size, "X509_%d_%s", depth, name);
260  setenv_str(es, name_expand, value);
261  free(name_expand);
262 }
263 
264 static char *
265 asn1_buf_to_c_string(const mbedtls_asn1_buf *orig, struct gc_arena *gc)
266 {
267  size_t i;
268  char *val;
269 
270  if (!(orig->tag == MBEDTLS_ASN1_UTF8_STRING
271  || orig->tag == MBEDTLS_ASN1_PRINTABLE_STRING
272  || orig->tag == MBEDTLS_ASN1_IA5_STRING))
273  {
274  /* Only support C-string compatible types */
275  return string_alloc("ERROR: unsupported ASN.1 string type", gc);
276  }
277 
278  for (i = 0; i < orig->len; ++i)
279  {
280  if (orig->p[i] == '\0')
281  {
282  return string_alloc("ERROR: embedded null value", gc);
283  }
284  }
285  val = gc_malloc(orig->len+1, false, gc);
286  memcpy(val, orig->p, orig->len);
287  val[orig->len] = '\0';
288  return val;
289 }
290 
291 static void
292 do_setenv_name(struct env_set *es, const struct x509_track *xt,
293  const mbedtls_x509_crt *cert, int depth, struct gc_arena *gc)
294 {
295  const mbedtls_x509_name *xn;
296  for (xn = &cert->subject; xn != NULL; xn = xn->next)
297  {
298  const char *xn_short_name = NULL;
299  if (0 == mbedtls_oid_get_attr_short_name(&xn->oid, &xn_short_name)
300  && 0 == strcmp(xt->name, xn_short_name))
301  {
302  char *val_str = asn1_buf_to_c_string(&xn->val, gc);
303  do_setenv_x509(es, xt->name, val_str, depth);
304  }
305  }
306 }
307 
308 void
309 x509_track_add(const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc)
310 {
311  struct x509_track *xt;
312  ALLOC_OBJ_CLEAR_GC(xt, struct x509_track, gc);
313  if (*name == '+')
314  {
315  xt->flags |= XT_FULL_CHAIN;
316  ++name;
317  }
318  xt->name = name;
319  xt->next = *ll_head;
320  *ll_head = xt;
321 }
322 
323 void
324 x509_setenv_track(const struct x509_track *xt, struct env_set *es,
325  const int depth, mbedtls_x509_crt *cert)
326 {
327  struct gc_arena gc = gc_new();
328  while (xt)
329  {
330  if (depth == 0 || (xt->flags & XT_FULL_CHAIN))
331  {
332  if (0 == strcmp(xt->name, "SHA1") || 0 == strcmp(xt->name, "SHA256"))
333  {
334  /* Fingerprint is not part of X509 structure */
335  struct buffer cert_hash;
336  char *fingerprint;
337 
338  if (0 == strcmp(xt->name, "SHA1"))
339  {
341  }
342  else
343  {
345  }
346 
347  fingerprint = format_hex_ex(BPTR(&cert_hash),
348  BLEN(&cert_hash), 0, 1 | FHE_CAPS, ":", &gc);
349  do_setenv_x509(es, xt->name, fingerprint, depth);
350  }
351  else
352  {
353  do_setenv_name(es, xt, cert, depth, &gc);
354  }
355  }
356  xt = xt->next;
357  }
358  gc_free(&gc);
359 }
360 
361 /*
362  * Save X509 fields to environment, using the naming convention:
363  *
364  * X509_{cert_depth}_{name}={value}
365  */
366 void
367 x509_setenv(struct env_set *es, int cert_depth, mbedtls_x509_crt *cert)
368 {
369  int i;
370  unsigned char c;
371  const mbedtls_x509_name *name;
372  char s[128] = { 0 };
373 
374  name = &cert->subject;
375 
376  while (name != NULL)
377  {
378  char name_expand[64+8];
379  const char *shortname;
380 
381  if (0 == mbedtls_oid_get_attr_short_name(&name->oid, &shortname) )
382  {
383  openvpn_snprintf(name_expand, sizeof(name_expand), "X509_%d_%s",
384  cert_depth, shortname);
385  }
386  else
387  {
388  openvpn_snprintf(name_expand, sizeof(name_expand), "X509_%d_\?\?",
389  cert_depth);
390  }
391 
392  for (i = 0; i < name->val.len; i++)
393  {
394  if (i >= (int) sizeof( s ) - 1)
395  {
396  break;
397  }
398 
399  c = name->val.p[i];
400  if (c < 32 || c == 127 || ( c > 128 && c < 160 ) )
401  {
402  s[i] = '?';
403  }
404  else
405  {
406  s[i] = c;
407  }
408  }
409  s[i] = '\0';
410 
411  /* Check both strings, set environment variable */
412  string_mod(name_expand, CC_PRINT, CC_CRLF, '_');
413  string_mod((char *)s, CC_PRINT, CC_CRLF, '_');
414  setenv_str_incr(es, name_expand, (char *)s);
415 
416  name = name->next;
417  }
418 }
419 
420 result_t
421 x509_verify_ns_cert_type(mbedtls_x509_crt *cert, const int usage)
422 {
423  if (usage == NS_CERT_CHECK_NONE)
424  {
425  return SUCCESS;
426  }
427  if (usage == NS_CERT_CHECK_CLIENT)
428  {
429  return ((cert->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE)
430  && (cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT)) ?
431  SUCCESS : FAILURE;
432  }
433  if (usage == NS_CERT_CHECK_SERVER)
434  {
435  return ((cert->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE)
436  && (cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER)) ?
437  SUCCESS : FAILURE;
438  }
439 
440  return FAILURE;
441 }
442 
443 result_t
444 x509_verify_cert_ku(mbedtls_x509_crt *cert, const unsigned *const expected_ku,
445  int expected_len)
446 {
447  msg(D_HANDSHAKE, "Validating certificate key usage");
448 
449  if (!(cert->ext_types & MBEDTLS_X509_EXT_KEY_USAGE))
450  {
452  "ERROR: Certificate does not have key usage extension");
453  return FAILURE;
454  }
455 
456  if (expected_ku[0] == OPENVPN_KU_REQUIRED)
457  {
458  /* Extension required, value checked by TLS library */
459  return SUCCESS;
460  }
461 
462  result_t fFound = FAILURE;
463  for (size_t i = 0; SUCCESS != fFound && i<expected_len; i++)
464  {
465  if (expected_ku[i] != 0
466  && 0 == mbedtls_x509_crt_check_key_usage(cert, expected_ku[i]))
467  {
468  fFound = SUCCESS;
469  }
470  }
471 
472  if (fFound != SUCCESS)
473  {
475  "ERROR: Certificate has key usage %04x, expected one of:",
476  cert->key_usage);
477  for (size_t i = 0; i < expected_len && expected_ku[i]; i++)
478  {
479  msg(D_TLS_ERRORS, " * %04x", expected_ku[i]);
480  }
481  }
482 
483  return fFound;
484 }
485 
486 result_t
487 x509_verify_cert_eku(mbedtls_x509_crt *cert, const char *const expected_oid)
488 {
489  result_t fFound = FAILURE;
490 
491  if (!(cert->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE))
492  {
493  msg(D_HANDSHAKE, "Certificate does not have extended key usage extension");
494  }
495  else
496  {
497  mbedtls_x509_sequence *oid_seq = &(cert->ext_key_usage);
498 
499  msg(D_HANDSHAKE, "Validating certificate extended key usage");
500  while (oid_seq != NULL)
501  {
502  mbedtls_x509_buf *oid = &oid_seq->buf;
503  char oid_num_str[1024];
504  const char *oid_str;
505 
506  if (0 == mbedtls_oid_get_extended_key_usage( oid, &oid_str ))
507  {
508  msg(D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s",
509  oid_str, expected_oid);
510  if (!strcmp(expected_oid, oid_str))
511  {
512  fFound = SUCCESS;
513  break;
514  }
515  }
516 
517  if (0 < mbedtls_oid_get_numeric_string( oid_num_str,
518  sizeof(oid_num_str), oid))
519  {
520  msg(D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s",
521  oid_num_str, expected_oid);
522  if (!strcmp(expected_oid, oid_num_str))
523  {
524  fFound = SUCCESS;
525  break;
526  }
527  }
528  oid_seq = oid_seq->next;
529  }
530  }
531 
532  return fFound;
533 }
534 
535 result_t
536 x509_write_pem(FILE *peercert_file, mbedtls_x509_crt *peercert)
537 {
538  msg(M_WARN, "mbed TLS does not support writing peer certificate in PEM format");
539  return FAILURE;
540 }
541 
542 bool
543 tls_verify_crl_missing(const struct tls_options *opt)
544 {
545  if (opt->crl_file && !(opt->ssl_flags & SSLF_CRL_VERIFY_DIR)
546  && (opt->ssl_ctx.crl == NULL || opt->ssl_ctx.crl->version == 0))
547  {
548  return true;
549  }
550  return false;
551 }
552 
553 #endif /* #if defined(ENABLE_CRYPTO_MBEDTLS) */
const char * crl_file
Definition: ssl_common.h:284
#define SSLF_CRL_VERIFY_DIR
Definition: ssl_common.h:344
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:688
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1023
struct tls_root_ctx ssl_ctx
Definition: ssl_common.h:244
bool verified
Definition: ssl_common.h:440
#define NS_CERT_CHECK_CLIENT
Do not perform Netscape certificate type verification.
Definition: ssl_verify.h:216
#define D_TLS_ERRORS
Definition: errlevel.h:59
#define CC_PRINT
Definition: buffer.h:915
result_t x509_verify_cert_ku(openvpn_x509_cert_t *x509, const unsigned *const expected_ku, int expected_len)
void cert_hash_remember(struct tls_session *session, const int error_depth, const struct buffer *cert_hash)
Definition: ssl_verify.c:233
char * backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc)
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition: env_set.c:285
#define ASSERT(x)
Definition: error.h:221
Structure containing the hash for a single certificate.
Definition: ssl_verify.h:54
void x509_track_add(const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc)
result_t verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth)
Definition: ssl_verify.c:656
list flags
int len
Length in bytes of the actual content within the allocated memory.
Definition: buffer.h:66
#define D_X509_ATTR
Definition: errlevel.h:104
#define BPTR(buf)
Definition: buffer.h:124
bool openvpn_snprintf(char *str, size_t size, const char *format,...)
Definition: buffer.c:299
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:307
static struct gc_arena gc_new(void)
Definition: buffer.h:1015
#define mbed_ok(errval)
Check errval and log on error.
#define malloc
Definition: cmocka.c:1795
unsigned int flags
Definition: ssl_verify.h:204
void x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, openvpn_x509_cert_t *x509)
void chomp(char *str)
Definition: buffer.c:653
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition: buffer.c:408
result_t x509_verify_cert_eku(openvpn_x509_cert_t *x509, const char *const expected_oid)
unsigned __int32 uint32_t
Definition: config-msvc.h:121
#define NS_CERT_CHECK_NONE
Do not perform Netscape certificate type verification.
Definition: ssl_verify.h:212
mbedtls_x509_crl * crl
Certificate Revocation List.
Definition: ssl_mbedtls.h:99
int verify_callback(void *session_obj, mbedtls_x509_crt *cert, int cert_depth, uint32_t *flags)
Verify that the remote OpenVPN peer&#39;s certificate allows setting up a VPN tunnel. ...
char * x509_get_subject(openvpn_x509_cert_t *cert, struct gc_arena *gc)
const struct x509_track * next
Definition: ssl_verify.h:201
#define msg
Definition: error.h:173
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:522
char * backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
const char * name
Definition: ssl_verify.h:202
#define BLEN(buf)
Definition: buffer.h:127
#define D_HANDSHAKE
Definition: errlevel.h:72
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Definition: buffer.c:1081
result_t x509_verify_ns_cert_type(openvpn_x509_cert_t *cert, const int usage)
struct buffer x509_get_sha1_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate&#39;s SHA1 fingerprint.
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Definition: buffer.h:1087
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:611
bool tls_verify_crl_missing(const struct tls_options *opt)
Return true iff a CRL is configured, but is not loaded.
static void check_malloc_return(const void *p)
Definition: buffer.h:1093
static void usage(void)
Definition: options.c:4093
Security parameter state of a single session within a VPN tunnel.
Definition: ssl_common.h:407
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
result_t x509_write_pem(FILE *peercert_file, openvpn_x509_cert_t *peercert)
#define FHE_CAPS
Definition: buffer.h:519
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:90
#define M_WARN
Definition: error.h:96
#define free
Definition: cmocka.c:1850
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
#define XT_FULL_CHAIN
Definition: ssl_verify.h:203
struct buffer x509_get_sha256_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate&#39;s SHA256 fingerprint.
#define CC_CRLF
Definition: buffer.h:944
#define CC_ANY
Definition: buffer.h:907
unsigned int ssl_flags
Definition: ssl_common.h:349
void x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert)
result_t
Result of verification function.
result_t backend_x509_get_username(char *common_name, int cn_len, char *x509_username_field, openvpn_x509_cert_t *peer_cert)
#define NS_CERT_CHECK_SERVER
Do not perform Netscape certificate type verification.
Definition: ssl_verify.h:214
#define OPENVPN_KU_REQUIRED
Require keyUsage to be present in cert (0xFFFF is an invalid KU value)
Definition: ssl_verify.h:219