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