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