1 /*
2  * mtls-openssl.c
3  *
4  * This file is part of msmtp, an SMTP client, and of mpop, a POP3 client.
5  *
6  * Copyright (C) 2000, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
7  * 2012, 2014, 2016, 2018, 2019, 2020
8  * Martin Lambers <marlam@marlam.de>
9  *
10  *   This program is free software; you can redistribute it and/or modify
11  *   it under the terms of the GNU General Public License as published by
12  *   the Free Software Foundation; either version 3 of the License, or
13  *   (at your option) any later version.
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
21  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27 
28 #include <stdio.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <ctype.h>
32 #include <stdlib.h>
33 #include <limits.h>
34 #include <time.h>
35 #include <errno.h>
36 
37 #include <openssl/ssl.h>
38 #include <openssl/x509.h>
39 #include <openssl/x509v3.h>
40 #include <openssl/err.h>
41 #include <openssl/rand.h>
42 #include <openssl/evp.h>
43 #if OPENSSL_VERSION_NUMBER < 0x10100000L
44 #define X509_get0_notBefore X509_get_notBefore
45 #define X509_get0_notAfter X509_get_notAfter
46 #endif
47 
48 #ifdef HAVE_LIBIDN
49 # include <idn2.h>
50 #endif
51 
52 #include "gettext.h"
53 #define _(string) gettext(string)
54 #define N_(string) gettext_noop(string)
55 
56 #include "xalloc.h"
57 #include "readbuf.h"
58 #include "tools.h"
59 #include "mtls.h"
60 
61 
62 struct mtls_internals_t
63 {
64     SSL_CTX *ssl_ctx;
65     SSL *ssl;
66 };
67 
68 
69 
70 /*
71  * seed_prng()
72  *
73  * Seeds the OpenSSL random number generator.
74  * Used error codes: TLS_ESEED
75  */
76 
seed_prng(char ** errstr)77 static int seed_prng(char **errstr)
78 {
79     char randfile[512];
80     time_t t;
81     int prn;
82     int system_prn_max = 1024;
83 
84     /* Most systems have /dev/random or other sources of random numbers that
85      * OpenSSL can use to seed itself.
86      * The only system I know of where we must seed the PRNG is DOS.
87      */
88     if (!RAND_status())
89     {
90         if (!RAND_file_name(randfile, 512))
91         {
92             *errstr = xasprintf(_("no environment variables RANDFILE or HOME, "
93                         "or filename of rand file too long"));
94             return TLS_ESEED;
95         }
96         if (RAND_load_file(randfile, -1) < 1)
97         {
98             *errstr = xasprintf(_("%s: input error"), randfile);
99             return TLS_ESEED;
100         }
101         /* Seed in time. I can't think of other "random" things on DOS
102          * systems. */
103         t = time(NULL);
104         RAND_seed((unsigned char *)&t, sizeof(time_t));
105         /* If the RANDFILE + time is not enough, we fall back to the insecure
106          * and stupid method of seeding OpenSSLs PRNG with the systems PRNG. */
107         if (!RAND_status())
108         {
109             srand((unsigned int)(t % UINT_MAX));
110             while (!RAND_status() && system_prn_max > 0)
111             {
112                 prn = rand();
113                 RAND_seed(&prn, sizeof(int));
114                 system_prn_max--;
115             }
116         }
117         /* Are we happy now? */
118         if (!RAND_status())
119         {
120             *errstr = xasprintf(_("random file + time + pseudo randomness is "
121                         "not enough, giving up"));
122             return TLS_ESEED;
123         }
124         /* Save a rand file for later usage. We ignore errors here as we can't
125          * do anything about them. */
126         (void)RAND_write_file(randfile);
127     }
128     return TLS_EOK;
129 }
130 
131 
132 /*
133  * mtls_lib_init()
134  *
135  * see mtls.h
136  */
137 
mtls_lib_init(char ** errstr)138 int mtls_lib_init(char **errstr)
139 {
140     int e;
141 
142 #if OPENSSL_VERSION_NUMBER < 0x10100000L
143     SSL_load_error_strings();
144     SSL_library_init();
145 #endif
146     if ((e = seed_prng(errstr)) != TLS_EOK)
147     {
148         return e;
149     }
150 
151     return TLS_EOK;
152 }
153 
154 
155 /*
156  * asn1time_to_time_t() [OpenSSL only]
157  *
158  * Convert a ASN1 time string ([YY]YYMMDDhhmm[ss](Z)) into a time_t.
159  * The flag 'is_utc' indicates whether the string is in UTC or GENERALIZED
160  * format. GENERALIZED means a 4 digit year.
161  * In case of invalid strings or over-/underflows, 1 is returned, and the value
162  * of 't' is undefined. On success, 0 is returned.
163  *
164  * This code uses many ideas from GnuTLS code (lib/x509/common.c).
165  * The transformation of struct tm to time_t is based on code from Russ Allbery
166  * (rra@stanford.edu), who wrote a mktime_utc function and placed it under
167  * public domain.
168  */
169 
is_leap(int year)170 static int is_leap(int year)
171 {
172     return (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0));
173 }
174 
asn1time_to_time_t(const char * asn1time,int is_utc,time_t * t)175 static int asn1time_to_time_t(const char *asn1time, int is_utc, time_t *t)
176 {
177     size_t len;
178     int i;
179     size_t j;
180     const char *p;
181     char xx[3];
182     char xxxx[5];
183     const int monthdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
184     struct tm tm;
185 
186     len = strlen(asn1time);
187     if ((is_utc && len < 10) || (!is_utc && len < 12))
188     {
189         goto error_exit;
190     }
191     for (j = 0; j < len - 1; j++)
192     {
193         if (!isdigit((unsigned char)asn1time[j]))
194         {
195             goto error_exit;
196         }
197     }
198 
199     xx[2] = '\0';
200     xxxx[4] = '\0';
201     p = asn1time;
202     if (is_utc)
203     {
204         strncpy(xx, p, 2);
205         tm.tm_year = atoi(xx);
206         tm.tm_year += (tm.tm_year > 49) ? 1900 : 2000;
207         p += 2;
208     }
209     else
210     {
211         strncpy(xxxx, p, 4);
212         tm.tm_year = atoi(xxxx);
213         p += 4;
214     }
215     strncpy(xx, p, 2);
216     tm.tm_mon = atoi(xx) - 1;
217     p += 2;
218     strncpy(xx, p, 2);
219     tm.tm_mday = atoi(xx);
220     p += 2;
221     strncpy(xx, p, 2);
222     tm.tm_hour = atoi(xx);
223     p += 2;
224     strncpy(xx, p, 2);
225     tm.tm_min = atoi(xx);
226     p += 2;
227     if (isdigit((unsigned char)(*p)))
228     {
229         strncpy(xx, p, 2);
230         tm.tm_sec = atoi(xx);
231     }
232     else
233     {
234         tm.tm_sec = 0;
235     }
236 
237     /* basic check for 32 bit time_t overflows. */
238     if (sizeof(time_t) <= 4 && tm.tm_year >= 2038)
239     {
240         goto error_exit;
241     }
242     if (tm.tm_year < 1970 || tm.tm_mon < 0 || tm.tm_mon > 11)
243     {
244         goto error_exit;
245     }
246     *t = 0;
247     for (i = 1970; i < tm.tm_year; i++)
248     {
249         *t += 365 + (is_leap(i) ? 1 : 0);
250     }
251     for (i = 0; i < tm.tm_mon; i++)
252     {
253         *t += monthdays[i];
254     }
255     if (tm.tm_mon > 1 && is_leap(tm.tm_year))
256     {
257         *t += 1;
258     }
259     *t = 24 * (*t + tm.tm_mday - 1) + tm.tm_hour;
260     *t = 60 * (*t) + tm.tm_min;
261     *t = 60 * (*t) + tm.tm_sec;
262 
263     return 0;
264 
265 error_exit:
266     return 1;
267 }
268 
269 
270 /*
271  * mtls_cert_info_get()
272  *
273  * see mtls.h
274  */
275 
mtls_cert_info_get(mtls_t * mtls,mtls_cert_info_t * mtci,char ** errstr)276 int mtls_cert_info_get(mtls_t *mtls, mtls_cert_info_t *mtci, char **errstr)
277 {
278     X509 *x509cert;
279     X509_NAME *x509_subject;
280     X509_NAME *x509_issuer;
281     const ASN1_TIME *asn1time;
282     unsigned int usize;
283     const char *errmsg;
284 
285     errmsg = _("cannot get TLS certificate info");
286     if (!(x509cert = SSL_get_peer_certificate(mtls->internals->ssl)))
287     {
288         *errstr = xasprintf(_("%s: no certificate was found"), errmsg);
289         return TLS_ECERT;
290     }
291     if (!(x509_subject = X509_get_subject_name(x509cert)))
292     {
293         *errstr = xasprintf(_("%s: cannot get certificate subject"), errmsg);
294         X509_free(x509cert);
295         return TLS_ECERT;
296     }
297     if (!(x509_issuer = X509_get_issuer_name(x509cert)))
298     {
299         *errstr = xasprintf(_("%s: cannot get certificate issuer"), errmsg);
300         X509_free(x509cert);
301         return TLS_ECERT;
302     }
303 
304     /* certificate information */
305     usize = 32;
306     if (!X509_digest(x509cert, EVP_sha256(), mtci->sha256_fingerprint, &usize))
307     {
308         *errstr = xasprintf(_("%s: error getting SHA256 fingerprint"), errmsg);
309         return TLS_ECERT;
310     }
311     usize = 20;
312     if (!X509_digest(x509cert, EVP_sha1(), mtci->sha1_fingerprint, &usize))
313     {
314         *errstr = xasprintf(_("%s: error getting SHA1 fingerprint"), errmsg);
315         return TLS_ECERT;
316     }
317     asn1time = X509_get0_notBefore(x509cert);
318     if (asn1time_to_time_t((const char *)asn1time->data,
319                 (asn1time->type != V_ASN1_GENERALIZEDTIME),
320                 &(mtci->activation_time)) != 0)
321     {
322         *errstr = xasprintf(_("%s: cannot get activation time"), errmsg);
323         X509_free(x509cert);
324         mtls_cert_info_free(mtci);
325         return TLS_ECERT;
326     }
327     asn1time = X509_get0_notAfter(x509cert);
328     if (asn1time_to_time_t((const char *)asn1time->data,
329                 (asn1time->type != V_ASN1_GENERALIZEDTIME),
330                 &(mtci->expiration_time)) != 0)
331     {
332         *errstr = xasprintf(_("%s: cannot get expiration time"), errmsg);
333         X509_free(x509cert);
334         mtls_cert_info_free(mtci);
335         return TLS_ECERT;
336     }
337 
338     /* subject information */
339     mtci->subject_info = X509_NAME_oneline(x509_subject, NULL, 0);
340 
341     /* issuer information */
342     mtci->issuer_info = X509_NAME_oneline(x509_issuer, NULL, 0);
343 
344     X509_free(x509cert);
345     return TLS_EOK;
346 }
347 
348 
349 /*
350  * [OpenSSL only] hostname_match()
351  *
352  * Compares the hostname with the name in the certificate. The certificate name
353  * may include a wildcard as the leftmost domain component (its first two
354  * characters are "*." in this case).
355  *
356  * Returns 1 if the names match, 0 otherwise.
357  *
358  * This is the same form of matching that gnutls_x509_crt_check_hostname() from
359  * GnuTLS 1.2.0 uses.
360  * It conforms to RFC2595 (Using TLS with IMAP, POP3 and ACAP), section 2.4.
361  * RFC2818 (HTTP over TLS), section 3.1 says that `f*.com matches foo.com'. This
362  * function does not allow that.
363  * RFC3207 (SMTP Service Extension for Secure SMTP over Transport Layer
364  * Security), section 4.1 says nothing more than `A SMTP client would probably
365  * only want to authenticate an SMTP server whose server certificate has a
366  * domain name that is the domain name that the client thought it was connecting
367  * to'.
368  */
369 
hostname_match(const char * hostname,const char * certname)370 static int hostname_match(const char *hostname, const char *certname)
371 {
372     const char *cmp1, *cmp2;
373 
374     if (strncmp(certname, "*.", 2) == 0)
375     {
376         cmp1 = certname + 2;
377         cmp2 = strchr(hostname, '.');
378         if (!cmp2)
379         {
380             return 0;
381         }
382         else
383         {
384             cmp2++;
385         }
386     }
387     else
388     {
389         cmp1 = certname;
390         cmp2 = hostname;
391     }
392 
393     if (*cmp1 == '\0' || *cmp2 == '\0')
394     {
395         return 0;
396     }
397 
398     if (strcasecmp(cmp1, cmp2) != 0)
399     {
400         return 0;
401     }
402 
403     return 1;
404 }
405 
406 
407 /*
408  * mtls_check_cert()
409  *
410  * If the 'mtls->have_trust_file' flag is set, perform a real verification of
411  * the peer's certificate. If this succeeds, the connection can be considered
412  * secure.
413  * If one of the 'mtls->have_*_fingerprint' flags is
414  * set, compare the 'mtls->fingerprint' data with the peer certificate's
415  * fingerprint. If this succeeds, the connection can be considered secure.
416  * If none of these flags is set, perform only a few sanity checks of the
417  * peer's certificate. You cannot trust the connection when this succeeds.
418  * Used error codes: TLS_ECERT
419  */
420 
mtls_check_cert(mtls_t * mtls,char ** errstr)421 static int mtls_check_cert(mtls_t *mtls, char **errstr)
422 {
423     X509 *x509cert;
424     long status;
425     const char *error_msg;
426     int i;
427     /* hostname in ASCII format: */
428     char *idn_hostname = NULL;
429     /* needed to get the common name: */
430     X509_NAME *x509_subject;
431     char *buf;
432     int length;
433     /* needed to get the DNS subjectAltNames: */
434     void *subj_alt_names;
435     int subj_alt_names_count;
436     GENERAL_NAME *subj_alt_name;
437     /* did we find a name matching hostname? */
438     int match_found;
439     /* needed for fingerprint checking */
440     unsigned int usize;
441     unsigned char fingerprint[32];
442 
443 
444     if (mtls->have_trust_file)
445     {
446         error_msg = _("TLS certificate verification failed");
447     }
448     else
449     {
450         error_msg = _("TLS certificate check failed");
451     }
452 
453     /* Get certificate */
454     if (!(x509cert = SSL_get_peer_certificate(mtls->internals->ssl)))
455     {
456         *errstr = xasprintf(_("%s: no certificate was sent"), error_msg);
457         return TLS_ECERT;
458     }
459 
460     if (mtls->have_sha256_fingerprint
461             || mtls->have_sha1_fingerprint || mtls->have_md5_fingerprint)
462     {
463         /* If one of these matches, we trust the peer and do not perform any
464          * other checks. */
465         if (mtls->have_sha256_fingerprint)
466         {
467             usize = 32;
468             if (!X509_digest(x509cert, EVP_sha256(), fingerprint, &usize))
469             {
470                 *errstr = xasprintf(_("%s: error getting SHA256 fingerprint"),
471                         error_msg);
472                 X509_free(x509cert);
473                 return TLS_ECERT;
474             }
475             if (memcmp(fingerprint, mtls->fingerprint, 32) != 0)
476             {
477                 *errstr = xasprintf(_("%s: the certificate fingerprint "
478                             "does not match"), error_msg);
479                 X509_free(x509cert);
480                 return TLS_ECERT;
481             }
482         }
483         else if (mtls->have_sha1_fingerprint)
484         {
485             usize = 20;
486             if (!X509_digest(x509cert, EVP_sha1(), fingerprint, &usize))
487             {
488                 *errstr = xasprintf(_("%s: error getting SHA1 fingerprint"),
489                         error_msg);
490                 X509_free(x509cert);
491                 return TLS_ECERT;
492             }
493             if (memcmp(fingerprint, mtls->fingerprint, 20) != 0)
494             {
495                 *errstr = xasprintf(_("%s: the certificate fingerprint "
496                             "does not match"), error_msg);
497                 X509_free(x509cert);
498                 return TLS_ECERT;
499             }
500         }
501         else
502         {
503             usize = 16;
504             if (!X509_digest(x509cert, EVP_md5(), fingerprint, &usize))
505             {
506                 *errstr = xasprintf(_("%s: error getting MD5 fingerprint"),
507                         error_msg);
508                 X509_free(x509cert);
509                 return TLS_ECERT;
510             }
511             if (memcmp(fingerprint, mtls->fingerprint, 16) != 0)
512             {
513                 *errstr = xasprintf(_("%s: the certificate fingerprint "
514                             "does not match"), error_msg);
515                 X509_free(x509cert);
516                 return TLS_ECERT;
517             }
518         }
519         X509_free(x509cert);
520         return TLS_EOK;
521     }
522 
523     /* Get result of OpenSSL's default verify function */
524     if ((status = SSL_get_verify_result(mtls->internals->ssl)) != X509_V_OK)
525     {
526         if (mtls->have_trust_file
527                 || (status != X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
528                     && status != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
529                     && status != X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN))
530         {
531             *errstr = xasprintf("%s: %s", error_msg,
532                     X509_verify_cert_error_string(status));
533             X509_free(x509cert);
534             return TLS_ECERT;
535         }
536     }
537 
538     /* Check if 'hostname' matches the one of the subjectAltName extensions of
539      * type DNS or the Common Name (CN). */
540 
541 #ifdef HAVE_LIBIDN
542     idn2_to_ascii_lz(mtls->hostname, &idn_hostname, IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL);
543 #endif
544 
545     /* Try the DNS subjectAltNames. */
546     match_found = 0;
547     if ((subj_alt_names =
548                 X509_get_ext_d2i(x509cert, NID_subject_alt_name, NULL, NULL)))
549     {
550         subj_alt_names_count = sk_GENERAL_NAME_num(subj_alt_names);
551         for (i = 0; i < subj_alt_names_count; i++)
552         {
553             subj_alt_name = sk_GENERAL_NAME_value(subj_alt_names, i);
554             if (subj_alt_name->type == GEN_DNS)
555             {
556                 if ((size_t)(subj_alt_name->d.ia5->length)
557                         != strlen((char *)(subj_alt_name->d.ia5->data)))
558                 {
559                     *errstr = xasprintf(_("%s: certificate subject "
560                                 "alternative name contains NUL"), error_msg);
561                     X509_free(x509cert);
562                     free(idn_hostname);
563                     return TLS_ECERT;
564                 }
565                 if ((match_found = hostname_match(
566                                 idn_hostname ? idn_hostname : mtls->hostname,
567                                 (char *)(subj_alt_name->d.ia5->data))))
568                 {
569                     break;
570                 }
571             }
572         }
573     }
574     if (!match_found)
575     {
576         /* Try the common name */
577         if (!(x509_subject = X509_get_subject_name(x509cert)))
578         {
579             *errstr = xasprintf(_("%s: cannot get certificate subject"),
580                     error_msg);
581             X509_free(x509cert);
582             free(idn_hostname);
583             return TLS_ECERT;
584         }
585         length = X509_NAME_get_text_by_NID(x509_subject, NID_commonName,
586                 NULL, 0);
587         buf = xmalloc((size_t)length + 1);
588         if (X509_NAME_get_text_by_NID(x509_subject, NID_commonName,
589                     buf, length + 1) == -1)
590         {
591             *errstr = xasprintf(_("%s: cannot get certificate common name"),
592                     error_msg);
593             X509_free(x509cert);
594             free(idn_hostname);
595             free(buf);
596             return TLS_ECERT;
597         }
598         if ((size_t)length != strlen(buf))
599         {
600             *errstr = xasprintf(_("%s: certificate common name contains NUL"),
601                     error_msg);
602             X509_free(x509cert);
603             free(idn_hostname);
604             free(buf);
605             return TLS_ECERT;
606         }
607         match_found = hostname_match(idn_hostname ? idn_hostname : mtls->hostname,
608                 buf);
609         free(buf);
610     }
611     X509_free(x509cert);
612     free(idn_hostname);
613 
614     if (!match_found)
615     {
616         *errstr = xasprintf(
617                 _("%s: the certificate owner does not match hostname %s"),
618                 error_msg, mtls->hostname);
619         return TLS_ECERT;
620     }
621 
622     return TLS_EOK;
623 }
624 
625 
626 /*
627  * mtls_init()
628  *
629  * see mtls.h
630  */
631 
mtls_init(mtls_t * mtls,const char * key_file,const char * cert_file,const char * pin,const char * trust_file,const char * crl_file,const unsigned char * sha256_fingerprint,const unsigned char * sha1_fingerprint,const unsigned char * md5_fingerprint,int min_dh_prime_bits,const char * priorities,const char * hostname,int no_certcheck,char ** errstr)632 int mtls_init(mtls_t *mtls,
633         const char *key_file, const char *cert_file, const char *pin,
634         const char *trust_file, const char *crl_file,
635         const unsigned char *sha256_fingerprint,
636         const unsigned char *sha1_fingerprint,
637         const unsigned char *md5_fingerprint,
638         int min_dh_prime_bits, const char *priorities,
639         const char *hostname,
640         int no_certcheck,
641         char **errstr)
642 {
643     const SSL_METHOD *ssl_method = SSLv23_client_method();
644 
645     /* FIXME: Implement support for 'min_dh_prime_bits' */
646     if (min_dh_prime_bits >= 0)
647     {
648         *errstr = xasprintf(
649                 _("cannot set minimum number of DH prime bits for TLS: %s"),
650                 _("feature not yet implemented for OpenSSL"));
651         return TLS_ELIBFAILED;
652     }
653     /* FIXME: Implement support for 'priorities' */
654     if (priorities)
655     {
656         *errstr = xasprintf(
657                 _("cannot set priorities for TLS session: %s"),
658                 _("feature not yet implemented for OpenSSL"));
659         return TLS_ELIBFAILED;
660     }
661     /* FIXME: Implement support for 'crl_file' */
662     if (trust_file && crl_file)
663     {
664         *errstr = xasprintf(
665                 _("cannot load CRL file: %s"),
666                 _("feature not yet implemented for OpenSSL"));
667         return TLS_ELIBFAILED;
668     }
669 
670     if (!ssl_method)
671     {
672         *errstr = xasprintf(_("cannot set TLS method"));
673         return TLS_ELIBFAILED;
674     }
675 
676     mtls->internals = xmalloc(sizeof(struct mtls_internals_t));
677 
678     if (!(mtls->internals->ssl_ctx = SSL_CTX_new(ssl_method)))
679     {
680         *errstr = xasprintf(_("cannot create TLS context: %s"),
681                 ERR_error_string(ERR_get_error(), NULL));
682         free(mtls->internals);
683         mtls->internals = NULL;
684         return TLS_ELIBFAILED;
685     }
686     /* SSLv2 and SSLv3 have known flaws. Disable them. */
687     (void)SSL_CTX_set_options(mtls->internals->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
688     if (key_file && cert_file)
689     {
690         if (SSL_CTX_use_PrivateKey_file(
691                     mtls->internals->ssl_ctx, key_file, SSL_FILETYPE_PEM) != 1)
692         {
693             *errstr = xasprintf(_("cannot load key file %s: %s"),
694                     key_file, ERR_error_string(ERR_get_error(), NULL));
695             SSL_CTX_free(mtls->internals->ssl_ctx);
696             free(mtls->internals);
697             mtls->internals = NULL;
698             return TLS_EFILE;
699         }
700         if (SSL_CTX_use_certificate_chain_file(mtls->internals->ssl_ctx, cert_file) != 1)
701         {
702             *errstr = xasprintf(_("cannot load certificate file %s: %s"),
703                     cert_file, ERR_error_string(ERR_get_error(), NULL));
704             SSL_CTX_free(mtls->internals->ssl_ctx);
705             free(mtls->internals);
706             mtls->internals = NULL;
707             return TLS_EFILE;
708         }
709     }
710     if (trust_file
711             && !no_certcheck
712             && !sha256_fingerprint
713             && !sha1_fingerprint
714             && !md5_fingerprint)
715     {
716         if (strcmp(trust_file, "system") == 0)
717         {
718             if (SSL_CTX_set_default_verify_paths(mtls->internals->ssl_ctx) != 1)
719             {
720                 *errstr = xasprintf(_("cannot set X509 system trust for TLS session: %s"),
721                         ERR_error_string(ERR_get_error(), NULL));
722                 SSL_CTX_free(mtls->internals->ssl_ctx);
723                 free(mtls->internals);
724                 mtls->internals = NULL;
725                 return TLS_EFILE;
726             }
727         }
728         else
729         {
730             if (SSL_CTX_load_verify_locations(mtls->internals->ssl_ctx, trust_file, NULL) != 1)
731             {
732                 *errstr = xasprintf(_("cannot load trust file %s: %s"),
733                         trust_file, ERR_error_string(ERR_get_error(), NULL));
734                 SSL_CTX_free(mtls->internals->ssl_ctx);
735                 free(mtls->internals);
736                 mtls->internals = NULL;
737                 return TLS_EFILE;
738             }
739         }
740         mtls->have_trust_file = 1;
741     }
742     if (sha256_fingerprint && !no_certcheck)
743     {
744         memcpy(mtls->fingerprint, sha256_fingerprint, 32);
745         mtls->have_sha256_fingerprint = 1;
746     }
747     else if (sha1_fingerprint && !no_certcheck)
748     {
749         memcpy(mtls->fingerprint, sha1_fingerprint, 20);
750         mtls->have_sha1_fingerprint = 1;
751     }
752     else if (md5_fingerprint && !no_certcheck)
753     {
754         memcpy(mtls->fingerprint, md5_fingerprint, 16);
755         mtls->have_md5_fingerprint = 1;
756     }
757     if (!(mtls->internals->ssl = SSL_new(mtls->internals->ssl_ctx)))
758     {
759         *errstr = xasprintf(_("cannot create a TLS structure: %s"),
760                 ERR_error_string(ERR_get_error(), NULL));
761         SSL_CTX_free(mtls->internals->ssl_ctx);
762         free(mtls->internals);
763         mtls->internals = NULL;
764         return TLS_ELIBFAILED;
765     }
766     mtls->no_certcheck = no_certcheck;
767     mtls->hostname = xstrdup(hostname);
768     return TLS_EOK;
769 }
770 
771 
772 /*
773  * openssl_io_error()
774  *
775  * Used only internally by the OpenSSL code.
776  *
777  * Construct an error line according to 'error_code' (which originates from an
778  * SSL_read(), SSL_write() or SSL_connect() operation) and 'error_code2' (which
779  * originates from an SSL_get_error() call with 'error_code' as its argument).
780  * The line will read: "error_string: error_reason". 'error_string' is given by
781  * the calling function, this function finds out 'error_reason'.
782  * The resulting string will be returned in an allocated string.
783  * OpenSSL error strings are max 120 characters long according to
784  * ERR_error_string(3).
785  */
786 
openssl_io_error(int error_code,int error_code2,const char * error_string)787 static char *openssl_io_error(int error_code, int error_code2,
788         const char *error_string)
789 {
790     unsigned long error_code3;
791     const char *error_reason;
792 
793     switch (error_code2)
794     {
795         case SSL_ERROR_SYSCALL:
796             error_code3 = ERR_get_error();
797             if (error_code3 == 0)
798             {
799                 if (error_code == 0)
800                 {
801                     error_reason = _("a protocol violating EOF occurred");
802                 }
803                 else if (error_code == -1)
804                 {
805                     error_reason = strerror(errno);
806                 }
807                 else
808                 {
809                     error_reason = _("unknown error");
810                 }
811             }
812             else
813             {
814                 error_reason = ERR_error_string(error_code3, NULL);
815             }
816             break;
817 
818         case SSL_ERROR_ZERO_RETURN:
819             error_reason = _("the connection was closed unexpectedly");
820             break;
821 
822         case SSL_ERROR_SSL:
823             error_reason = ERR_error_string(ERR_get_error(), NULL);
824             break;
825 
826         case SSL_ERROR_WANT_READ:
827         case SSL_ERROR_WANT_WRITE:
828             error_reason = _("the operation timed out");
829             break;
830 
831         default:
832             /* probably SSL_ERROR_NONE */
833             error_reason = _("unknown error");
834             break;
835     }
836     return xasprintf("%s: %s", error_string, error_reason);
837 }
838 
839 
840 /*
841  * mtls_start()
842  *
843  * see mtls.h
844  */
845 
mtls_start(mtls_t * mtls,int fd,mtls_cert_info_t * tci,char ** mtls_parameter_description,char ** errstr)846 int mtls_start(mtls_t *mtls, int fd,
847         mtls_cert_info_t *tci, char **mtls_parameter_description, char **errstr)
848 {
849     int error_code;
850 
851     if (!SSL_set_fd(mtls->internals->ssl, fd))
852     {
853         *errstr = xasprintf(_("cannot set the file descriptor for TLS: %s"),
854                 ERR_error_string(ERR_get_error(), NULL));
855         SSL_free(mtls->internals->ssl);
856         SSL_CTX_free(mtls->internals->ssl_ctx);
857         return TLS_ELIBFAILED;
858     }
859     if ((error_code = SSL_connect(mtls->internals->ssl)) < 1)
860     {
861         if (errno == EINTR
862                 && (SSL_get_error(mtls->internals->ssl, error_code) == SSL_ERROR_WANT_READ
863                     || SSL_get_error(mtls->internals->ssl, error_code)
864                     == SSL_ERROR_WANT_WRITE))
865         {
866             *errstr = xasprintf(_("operation aborted"));
867         }
868         else
869         {
870             *errstr = openssl_io_error(error_code,
871                     SSL_get_error(mtls->internals->ssl, error_code),
872                     _("TLS handshake failed"));
873         }
874         SSL_free(mtls->internals->ssl);
875         SSL_CTX_free(mtls->internals->ssl_ctx);
876         return TLS_EIO;
877     }
878     if (tci)
879     {
880         if ((error_code = mtls_cert_info_get(mtls, tci, errstr)) != TLS_EOK)
881         {
882             SSL_free(mtls->internals->ssl);
883             SSL_CTX_free(mtls->internals->ssl_ctx);
884             return error_code;
885         }
886     }
887     if (mtls_parameter_description)
888     {
889         *mtls_parameter_description = NULL; /* TODO */
890     }
891     if (!mtls->no_certcheck)
892     {
893         if ((error_code = mtls_check_cert(mtls, errstr)) != TLS_EOK)
894         {
895             SSL_free(mtls->internals->ssl);
896             SSL_CTX_free(mtls->internals->ssl_ctx);
897             return error_code;
898         }
899     }
900     mtls->is_active = 1;
901     return TLS_EOK;
902 }
903 
904 
905 /*
906  * mtls_readbuf_read()
907  *
908  * Wraps TLS read function to provide buffering for mtls_gets().
909  */
910 
mtls_readbuf_read(mtls_t * mtls,readbuf_t * readbuf,char * ptr,char ** errstr)911 int mtls_readbuf_read(mtls_t *mtls, readbuf_t *readbuf, char *ptr,
912         char **errstr)
913 {
914     int ret;
915     int error_code;
916 
917     if (readbuf->count <= 0)
918     {
919         ret = SSL_read(mtls->internals->ssl, readbuf->buf, sizeof(readbuf->buf));
920         if (ret < 1)
921         {
922             if ((error_code = SSL_get_error(mtls->internals->ssl, ret)) == SSL_ERROR_NONE)
923             {
924                 return 0;
925             }
926             else
927             {
928                 if (errno == EINTR
929                         && (SSL_get_error(mtls->internals->ssl, ret) == SSL_ERROR_WANT_READ
930                             || SSL_get_error(mtls->internals->ssl, ret)
931                             == SSL_ERROR_WANT_WRITE))
932                 {
933                     *errstr = xasprintf(_("operation aborted"));
934                 }
935                 else
936                 {
937                     *errstr = openssl_io_error(ret, error_code,
938                             _("cannot read from TLS connection"));
939                 }
940                 return TLS_EIO;
941             }
942         }
943         readbuf->count = ret;
944         readbuf->ptr = readbuf->buf;
945     }
946     readbuf->count--;
947     *ptr = *((readbuf->ptr)++);
948     return 1;
949 }
950 
951 
952 /*
953  * mtls_puts()
954  *
955  * see mtls.h
956  */
957 
mtls_puts(mtls_t * mtls,const char * s,size_t len,char ** errstr)958 int mtls_puts(mtls_t *mtls, const char *s, size_t len, char **errstr)
959 {
960     int error_code;
961 
962     if (len < 1)
963     {
964         /* nothing to be done */
965         return TLS_EOK;
966     }
967 
968     if ((error_code = SSL_write(mtls->internals->ssl, s, (int)len)) != (int)len)
969     {
970         if (errno == EINTR
971                 && ((SSL_get_error(mtls->internals->ssl, error_code) == SSL_ERROR_WANT_READ
972                         || SSL_get_error(mtls->internals->ssl, error_code)
973                         == SSL_ERROR_WANT_WRITE)))
974         {
975             *errstr = xasprintf(_("operation aborted"));
976         }
977         else
978         {
979             *errstr = openssl_io_error(error_code,
980                     SSL_get_error(mtls->internals->ssl, error_code),
981                     _("cannot write to TLS connection"));
982         }
983         return TLS_EIO;
984     }
985 
986     return TLS_EOK;
987 }
988 
989 
990 /*
991  * mtls_close()
992  *
993  * see mtls.h
994  */
995 
mtls_close(mtls_t * mtls)996 void mtls_close(mtls_t *mtls)
997 {
998     if (mtls->is_active)
999     {
1000         SSL_shutdown(mtls->internals->ssl);
1001         SSL_free(mtls->internals->ssl);
1002         SSL_CTX_free(mtls->internals->ssl_ctx);
1003     }
1004     free(mtls->internals);
1005     mtls->internals = NULL;
1006     if (mtls->hostname)
1007     {
1008         free(mtls->hostname);
1009     }
1010     mtls_clear(mtls);
1011 }
1012 
1013 
1014 /*
1015  * mtls_lib_deinit()
1016  *
1017  * see mtls.h
1018  */
1019 
mtls_lib_deinit(void)1020 void mtls_lib_deinit(void)
1021 {
1022 }
1023