]> sjero.net Git - wget/blob - src/openssl.c
0376614d0650aa95a6a65abcb98b9eaa7a18264b
[wget] / src / openssl.c
1 /* SSL support via OpenSSL library.
2    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3    2009, 2010 Free Software Foundation, Inc.
4    Originally contributed by Christian Fraenkel.
5
6 This file is part of GNU Wget.
7
8 GNU Wget is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 GNU Wget is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
20
21 Additional permission under GNU GPL version 3 section 7
22
23 If you modify this program, or any covered work, by linking or
24 combining it with the OpenSSL project's OpenSSL library (or a
25 modified version of that library), containing parts covered by the
26 terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
27 grants you additional permission to convey the resulting work.
28 Corresponding Source for a non-source form of such a combination
29 shall include the source code for the parts of OpenSSL used as well
30 as that of the covered work.  */
31
32 #include "wget.h"
33
34 #include <assert.h>
35 #include <errno.h>
36 #include <unistd.h>
37 #include <string.h>
38
39 #include <openssl/ssl.h>
40 #include <openssl/x509v3.h>
41 #include <openssl/err.h>
42 #include <openssl/rand.h>
43
44 #include "utils.h"
45 #include "connect.h"
46 #include "url.h"
47 #include "ssl.h"
48
49 /* Application-wide SSL context.  This is common to all SSL
50    connections.  */
51 static SSL_CTX *ssl_ctx;
52
53 /* Initialize the SSL's PRNG using various methods. */
54
55 static void
56 init_prng (void)
57 {
58   char namebuf[256];
59   const char *random_file;
60
61   if (RAND_status ())
62     /* The PRNG has been seeded; no further action is necessary. */
63     return;
64
65   /* Seed from a file specified by the user.  This will be the file
66      specified with --random-file, $RANDFILE, if set, or ~/.rnd, if it
67      exists.  */
68   if (opt.random_file)
69     random_file = opt.random_file;
70   else
71     {
72       /* Get the random file name using RAND_file_name. */
73       namebuf[0] = '\0';
74       random_file = RAND_file_name (namebuf, sizeof (namebuf));
75     }
76
77   if (random_file && *random_file)
78     /* Seed at most 16k (apparently arbitrary value borrowed from
79        curl) from random file. */
80     RAND_load_file (random_file, 16384);
81
82   if (RAND_status ())
83     return;
84
85   /* Get random data from EGD if opt.egd_file was used.  */
86   if (opt.egd_file && *opt.egd_file)
87     RAND_egd (opt.egd_file);
88
89   if (RAND_status ())
90     return;
91
92 #ifdef WINDOWS
93   /* Under Windows, we can try to seed the PRNG using screen content.
94      This may or may not work, depending on whether we'll calling Wget
95      interactively.  */
96
97   RAND_screen ();
98   if (RAND_status ())
99     return;
100 #endif
101
102 #if 0 /* don't do this by default */
103   {
104     int maxrand = 500;
105
106     /* Still not random enough, presumably because neither /dev/random
107        nor EGD were available.  Try to seed OpenSSL's PRNG with libc
108        PRNG.  This is cryptographically weak and defeats the purpose
109        of using OpenSSL, which is why it is highly discouraged.  */
110
111     logprintf (LOG_NOTQUIET, _("WARNING: using a weak random seed.\n"));
112
113     while (RAND_status () == 0 && maxrand-- > 0)
114       {
115         unsigned char rnd = random_number (256);
116         RAND_seed (&rnd, sizeof (rnd));
117       }
118   }
119 #endif
120 }
121
122 /* Print errors in the OpenSSL error stack. */
123
124 static void
125 print_errors (void)
126 {
127   unsigned long err;
128   while ((err = ERR_get_error ()) != 0)
129     logprintf (LOG_NOTQUIET, "OpenSSL: %s\n", ERR_error_string (err, NULL));
130 }
131
132 /* Convert keyfile type as used by options.h to a type as accepted by
133    SSL_CTX_use_certificate_file and SSL_CTX_use_PrivateKey_file.
134
135    (options.h intentionally doesn't use values from openssl/ssl.h so
136    it doesn't depend specifically on OpenSSL for SSL functionality.)  */
137
138 static int
139 key_type_to_ssl_type (enum keyfile_type type)
140 {
141   switch (type)
142     {
143     case keyfile_pem:
144       return SSL_FILETYPE_PEM;
145     case keyfile_asn1:
146       return SSL_FILETYPE_ASN1;
147     default:
148       abort ();
149     }
150 }
151
152 /* Create an SSL Context and set default paths etc.  Called the first
153    time an HTTP download is attempted.
154
155    Returns true on success, false otherwise.  */
156
157 bool
158 ssl_init ()
159 {
160   SSL_METHOD *meth;
161
162   if (ssl_ctx)
163     /* The SSL has already been initialized. */
164     return true;
165
166   /* Init the PRNG.  If that fails, bail out.  */
167   init_prng ();
168   if (RAND_status () != 1)
169     {
170       logprintf (LOG_NOTQUIET,
171                  _("Could not seed PRNG; consider using --random-file.\n"));
172       goto error;
173     }
174
175   SSL_library_init ();
176   SSL_load_error_strings ();
177   SSLeay_add_all_algorithms ();
178   SSLeay_add_ssl_algorithms ();
179
180   switch (opt.secure_protocol)
181     {
182     case secure_protocol_auto:
183       meth = SSLv23_client_method ();
184       break;
185     case secure_protocol_sslv2:
186       meth = SSLv2_client_method ();
187       break;
188     case secure_protocol_sslv3:
189       meth = SSLv3_client_method ();
190       break;
191     case secure_protocol_tlsv1:
192       meth = TLSv1_client_method ();
193       break;
194     default:
195       abort ();
196     }
197
198   ssl_ctx = SSL_CTX_new (meth);
199   if (!ssl_ctx)
200     goto error;
201
202   SSL_CTX_set_default_verify_paths (ssl_ctx);
203   SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory);
204
205   /* SSL_VERIFY_NONE instructs OpenSSL not to abort SSL_connect if the
206      certificate is invalid.  We verify the certificate separately in
207      ssl_check_certificate, which provides much better diagnostics
208      than examining the error stack after a failed SSL_connect.  */
209   SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL);
210
211   /* Use the private key from the cert file unless otherwise specified. */
212   if (opt.cert_file && !opt.private_key)
213     {
214       opt.private_key = opt.cert_file;
215       opt.private_key_type = opt.cert_type;
216     }
217
218   if (opt.cert_file)
219     if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
220                                       key_type_to_ssl_type (opt.cert_type))
221         != 1)
222       goto error;
223   if (opt.private_key)
224     if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key,
225                                      key_type_to_ssl_type (opt.private_key_type))
226         != 1)
227       goto error;
228
229   /* Since fd_write unconditionally assumes partial writes (and
230      handles them correctly), allow them in OpenSSL.  */
231   SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
232
233   /* The OpenSSL library can handle renegotiations automatically, so
234      tell it to do so.  */
235   SSL_CTX_set_mode (ssl_ctx, SSL_MODE_AUTO_RETRY);
236
237   return true;
238
239  error:
240   if (ssl_ctx)
241     SSL_CTX_free (ssl_ctx);
242   print_errors ();
243   return false;
244 }
245
246 struct openssl_transport_context {
247   SSL *conn;                    /* SSL connection handle */
248   char *last_error;             /* last error printed with openssl_errstr */
249 };
250
251 static int
252 openssl_read (int fd, char *buf, int bufsize, void *arg)
253 {
254   int ret;
255   struct openssl_transport_context *ctx = arg;
256   SSL *conn = ctx->conn;
257   do
258     ret = SSL_read (conn, buf, bufsize);
259   while (ret == -1
260          && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
261          && errno == EINTR);
262   return ret;
263 }
264
265 static int
266 openssl_write (int fd, char *buf, int bufsize, void *arg)
267 {
268   int ret = 0;
269   struct openssl_transport_context *ctx = arg;
270   SSL *conn = ctx->conn;
271   do
272     ret = SSL_write (conn, buf, bufsize);
273   while (ret == -1
274          && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
275          && errno == EINTR);
276   return ret;
277 }
278
279 static int
280 openssl_poll (int fd, double timeout, int wait_for, void *arg)
281 {
282   struct openssl_transport_context *ctx = arg;
283   SSL *conn = ctx->conn;
284   if (timeout == 0)
285     return 1;
286   if (SSL_pending (conn))
287     return 1;
288   return select_fd (fd, timeout, wait_for);
289 }
290
291 static int
292 openssl_peek (int fd, char *buf, int bufsize, void *arg)
293 {
294   int ret;
295   struct openssl_transport_context *ctx = arg;
296   SSL *conn = ctx->conn;
297   do
298     ret = SSL_peek (conn, buf, bufsize);
299   while (ret == -1
300          && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
301          && errno == EINTR);
302   return ret;
303 }
304
305 static const char *
306 openssl_errstr (int fd, void *arg)
307 {
308   struct openssl_transport_context *ctx = arg;
309   unsigned long errcode;
310   char *errmsg = NULL;
311   int msglen = 0;
312
313   /* If there are no SSL-specific errors, just return NULL. */
314   if ((errcode = ERR_get_error ()) == 0)
315     return NULL;
316
317   /* Get rid of previous contents of ctx->last_error, if any.  */
318   xfree_null (ctx->last_error);
319
320   /* Iterate over OpenSSL's error stack and accumulate errors in the
321      last_error buffer, separated by "; ".  This is better than using
322      a static buffer, which *always* takes up space (and has to be
323      large, to fit more than one error message), whereas these
324      allocations are only performed when there is an actual error.  */
325
326   for (;;)
327     {
328       const char *str = ERR_error_string (errcode, NULL);
329       int len = strlen (str);
330
331       /* Allocate space for the existing message, plus two more chars
332          for the "; " separator and one for the terminating \0.  */
333       errmsg = xrealloc (errmsg, msglen + len + 2 + 1);
334       memcpy (errmsg + msglen, str, len);
335       msglen += len;
336
337       /* Get next error and bail out if there are no more. */
338       errcode = ERR_get_error ();
339       if (errcode == 0)
340         break;
341
342       errmsg[msglen++] = ';';
343       errmsg[msglen++] = ' ';
344     }
345   errmsg[msglen] = '\0';
346
347   /* Store the error in ctx->last_error where openssl_close will
348      eventually find it and free it.  */
349   ctx->last_error = errmsg;
350
351   return errmsg;
352 }
353
354 static void
355 openssl_close (int fd, void *arg)
356 {
357   struct openssl_transport_context *ctx = arg;
358   SSL *conn = ctx->conn;
359
360   SSL_shutdown (conn);
361   SSL_free (conn);
362   xfree_null (ctx->last_error);
363   xfree (ctx);
364
365   close (fd);
366
367   DEBUGP (("Closed %d/SSL 0x%0*lx\n", fd, PTR_FORMAT (conn)));
368 }
369
370 /* openssl_transport is the singleton that describes the SSL transport
371    methods provided by this file.  */
372
373 static struct transport_implementation openssl_transport = {
374   openssl_read, openssl_write, openssl_poll,
375   openssl_peek, openssl_errstr, openssl_close
376 };
377
378 /* Perform the SSL handshake on file descriptor FD, which is assumed
379    to be connected to an SSL server.  The SSL handle provided by
380    OpenSSL is registered with the file descriptor FD using
381    fd_register_transport, so that subsequent calls to fd_read,
382    fd_write, etc., will use the corresponding SSL functions.
383
384    Returns true on success, false on failure.  */
385
386 bool
387 ssl_connect_wget (int fd)
388 {
389   SSL *conn;
390   struct openssl_transport_context *ctx;
391
392   DEBUGP (("Initiating SSL handshake.\n"));
393
394   assert (ssl_ctx != NULL);
395   conn = SSL_new (ssl_ctx);
396   if (!conn)
397     goto error;
398 #ifndef FD_TO_SOCKET
399 # define FD_TO_SOCKET(X) (X)
400 #endif
401   if (!SSL_set_fd (conn, FD_TO_SOCKET (fd)))
402     goto error;
403   SSL_set_connect_state (conn);
404   if (SSL_connect (conn) <= 0 || conn->state != SSL_ST_OK)
405     goto error;
406
407   ctx = xnew0 (struct openssl_transport_context);
408   ctx->conn = conn;
409
410   /* Register FD with Wget's transport layer, i.e. arrange that our
411      functions are used for reading, writing, and polling.  */
412   fd_register_transport (fd, &openssl_transport, ctx);
413   DEBUGP (("Handshake successful; connected socket %d to SSL handle 0x%0*lx\n",
414            fd, PTR_FORMAT (conn)));
415   return true;
416
417  error:
418   DEBUGP (("SSL handshake failed.\n"));
419   print_errors ();
420   if (conn)
421     SSL_free (conn);
422   return false;
423 }
424
425 #define ASTERISK_EXCLUDES_DOT   /* mandated by rfc2818 */
426
427 /* Return true is STRING (case-insensitively) matches PATTERN, false
428    otherwise.  The recognized wildcard character is "*", which matches
429    any character in STRING except ".".  Any number of the "*" wildcard
430    may be present in the pattern.
431
432    This is used to match of hosts as indicated in rfc2818: "Names may
433    contain the wildcard character * which is considered to match any
434    single domain name component or component fragment. E.g., *.a.com
435    matches foo.a.com but not bar.foo.a.com. f*.com matches foo.com but
436    not bar.com [or foo.bar.com]."
437
438    If the pattern contain no wildcards, pattern_match(a, b) is
439    equivalent to !strcasecmp(a, b).  */
440
441 static bool
442 pattern_match (const char *pattern, const char *string)
443 {
444   const char *p = pattern, *n = string;
445   char c;
446   for (; (c = c_tolower (*p++)) != '\0'; n++)
447     if (c == '*')
448       {
449         for (c = c_tolower (*p); c == '*'; c = c_tolower (*++p))
450           ;
451         for (; *n != '\0'; n++)
452           if (c_tolower (*n) == c && pattern_match (p, n))
453             return true;
454 #ifdef ASTERISK_EXCLUDES_DOT
455           else if (*n == '.')
456             return false;
457 #endif
458         return c == '\0';
459       }
460     else
461       {
462         if (c != c_tolower (*n))
463           return false;
464       }
465   return *n == '\0';
466 }
467
468 /* Verify the validity of the certificate presented by the server.
469    Also check that the "common name" of the server, as presented by
470    its certificate, corresponds to HOST.  (HOST typically comes from
471    the URL and is what the user thinks he's connecting to.)
472
473    This assumes that ssl_connect_wget has successfully finished, i.e. that
474    the SSL handshake has been performed and that FD is connected to an
475    SSL handle.
476
477    If opt.check_cert is true (the default), this returns 1 if the
478    certificate is valid, 0 otherwise.  If opt.check_cert is 0, the
479    function always returns 1, but should still be called because it
480    warns the user about any problems with the certificate.  */
481
482 bool
483 ssl_check_certificate (int fd, const char *host)
484 {
485   X509 *cert;
486   GENERAL_NAMES *subjectAltNames;
487   char common_name[256];
488   long vresult;
489   bool success = true;
490   bool alt_name_checked = false;
491
492   /* If the user has specified --no-check-cert, we still want to warn
493      him about problems with the server's certificate.  */
494   const char *severity = opt.check_cert ? _("ERROR") : _("WARNING");
495
496   struct openssl_transport_context *ctx = fd_transport_context (fd);
497   SSL *conn = ctx->conn;
498   assert (conn != NULL);
499
500   cert = SSL_get_peer_certificate (conn);
501   if (!cert)
502     {
503       logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
504                  severity, quotearg_style (escape_quoting_style, host));
505       success = false;
506       goto no_cert;             /* must bail out since CERT is NULL */
507     }
508
509   IF_DEBUG
510     {
511       char *subject = X509_NAME_oneline (X509_get_subject_name (cert), 0, 0);
512       char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
513       DEBUGP (("certificate:\n  subject: %s\n  issuer:  %s\n",
514                quotearg_n_style (0, escape_quoting_style, subject),
515                quotearg_n_style (1, escape_quoting_style, issuer)));
516       OPENSSL_free (subject);
517       OPENSSL_free (issuer);
518     }
519
520   vresult = SSL_get_verify_result (conn);
521   if (vresult != X509_V_OK)
522     {
523       char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
524       logprintf (LOG_NOTQUIET,
525                  _("%s: cannot verify %s's certificate, issued by %s:\n"),
526                  severity, quotearg_n_style (0, escape_quoting_style, host),
527                  quote_n (1, issuer));
528       /* Try to print more user-friendly (and translated) messages for
529          the frequent verification errors.  */
530       switch (vresult)
531         {
532         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
533           logprintf (LOG_NOTQUIET,
534                      _("  Unable to locally verify the issuer's authority.\n"));
535           break;
536         case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
537         case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
538           logprintf (LOG_NOTQUIET,
539                      _("  Self-signed certificate encountered.\n"));
540           break;
541         case X509_V_ERR_CERT_NOT_YET_VALID:
542           logprintf (LOG_NOTQUIET, _("  Issued certificate not yet valid.\n"));
543           break;
544         case X509_V_ERR_CERT_HAS_EXPIRED:
545           logprintf (LOG_NOTQUIET, _("  Issued certificate has expired.\n"));
546           break;
547         default:
548           /* For the less frequent error strings, simply provide the
549              OpenSSL error message.  */
550           logprintf (LOG_NOTQUIET, "  %s\n",
551                      X509_verify_cert_error_string (vresult));
552         }
553       success = false;
554       /* Fall through, so that the user is warned about *all* issues
555          with the cert (important with --no-check-certificate.)  */
556     }
557
558   /* Check that HOST matches the common name in the certificate.
559      #### The following remains to be done:
560
561      - When matching against common names, it should loop over all
562        common names and choose the most specific one, i.e. the last
563        one, not the first one, which the current code picks.
564
565      - Ensure that ASN1 strings from the certificate are encoded as
566        UTF-8 which can be meaningfully compared to HOST.  */
567
568   subjectAltNames = X509_get_ext_d2i (cert, NID_subject_alt_name, NULL, NULL);
569
570   if (subjectAltNames)
571     {
572       /* Test subject alternative names */
573
574       /* Do we want to check for dNSNAmes or ipAddresses (see RFC 2818)?
575        * Signal it by host_in_octet_string. */
576       ASN1_OCTET_STRING *host_in_octet_string = a2i_IPADDRESS (host);
577
578       int numaltnames = sk_GENERAL_NAME_num (subjectAltNames);
579       int i;
580       for (i=0; i < numaltnames; i++)
581         {
582           const GENERAL_NAME *name =
583             sk_GENERAL_NAME_value (subjectAltNames, i);
584           if (name)
585             {
586               if (host_in_octet_string)
587                 {
588                   if (name->type == GEN_IPADD)
589                     {
590                       /* Check for ipAddress */
591                       /* TODO: Should we convert between IPv4-mapped IPv6
592                        * addresses and IPv4 addresses? */
593                       alt_name_checked = true;
594                       if (!ASN1_STRING_cmp (host_in_octet_string,
595                             name->d.iPAddress))
596                         break;
597                     }
598                 }
599               else if (name->type == GEN_DNS)
600                 {
601                   /* dNSName should be IA5String (i.e. ASCII), however who
602                    * does trust CA? Convert it into UTF-8 for sure. */
603                   unsigned char *name_in_utf8 = NULL;
604
605                   /* Check for dNSName */
606                   alt_name_checked = true;
607
608                   if (0 <= ASN1_STRING_to_UTF8 (&name_in_utf8, name->d.dNSName))
609                     {
610                       /* Compare and check for NULL attack in ASN1_STRING */
611                       if (pattern_match ((char *)name_in_utf8, host) &&
612                             (strlen ((char *)name_in_utf8) ==
613                                 ASN1_STRING_length (name->d.dNSName)))
614                         {
615                           OPENSSL_free (name_in_utf8);
616                           break;
617                         }
618                       OPENSSL_free (name_in_utf8);
619                     }
620                 }
621             }
622         }
623       sk_GENERAL_NAME_free (subjectAltNames);
624       if (host_in_octet_string)
625         ASN1_OCTET_STRING_free(host_in_octet_string);
626
627       if (alt_name_checked == true && i >= numaltnames)
628         {
629           logprintf (LOG_NOTQUIET,
630               _("%s: no certificate subject alternative name matches\n"
631                 "\trequested host name %s.\n"),
632                      severity, quote_n (1, host));
633           success = false;
634         }
635     }
636   
637   if (alt_name_checked == false)
638     {
639       /* Test commomName */
640       X509_NAME *xname = X509_get_subject_name(cert);
641       common_name[0] = '\0';
642       X509_NAME_get_text_by_NID (xname, NID_commonName, common_name,
643                                  sizeof (common_name));
644
645       if (!pattern_match (common_name, host))
646         {
647           logprintf (LOG_NOTQUIET, _("\
648     %s: certificate common name %s doesn't match requested host name %s.\n"),
649                      severity, quote_n (0, common_name), quote_n (1, host));
650           success = false;
651         }
652       else
653         {
654           /* We now determine the length of the ASN1 string. If it
655            * differs from common_name's length, then there is a \0
656            * before the string terminates.  This can be an instance of a
657            * null-prefix attack.
658            *
659            * https://www.blackhat.com/html/bh-usa-09/bh-usa-09-archives.html#Marlinspike
660            * */
661
662           int i = -1, j;
663           X509_NAME_ENTRY *xentry;
664           ASN1_STRING *sdata;
665
666           if (xname) {
667             for (;;)
668               {
669                 j = X509_NAME_get_index_by_NID (xname, NID_commonName, i);
670                 if (j == -1) break;
671                 i = j;
672               }
673           }
674
675           xentry = X509_NAME_get_entry(xname,i);
676           sdata = X509_NAME_ENTRY_get_data(xentry);
677           if (strlen (common_name) != ASN1_STRING_length (sdata))
678             {
679               logprintf (LOG_NOTQUIET, _("\
680     %s: certificate common name is invalid (contains a NUL character).\n\
681     This may be an indication that the host is not who it claims to be\n\
682     (that is, it is not the real %s).\n"),
683                          severity, quote (host));
684               success = false;
685             }
686         }
687     }
688
689
690   if (success)
691     DEBUGP (("X509 certificate successfully verified and matches host %s\n",
692              quotearg_style (escape_quoting_style, host)));
693   X509_free (cert);
694
695  no_cert:
696   if (opt.check_cert && !success)
697     logprintf (LOG_NOTQUIET, _("\
698 To connect to %s insecurely, use `--no-check-certificate'.\n"),
699                quotearg_style (escape_quoting_style, host));
700
701   /* Allow --no-check-cert to disable certificate checking. */
702   return opt.check_cert ? success : true;
703 }
704
705 /*
706  * vim: tabstop=2 shiftwidth=2 softtabstop=2
707  */