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