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