1 /* SSL support via OpenSSL library.
2 Copyright (C) 2000-2006 Free Software Foundation, Inc.
3 Originally contributed by Christian Fraenkel.
5 This file is part of GNU Wget.
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.
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.
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/>.
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. */
39 #include <openssl/ssl.h>
40 #include <openssl/x509.h>
41 #include <openssl/err.h>
42 #include <openssl/rand.h>
50 /* Application-wide SSL context. This is common to all SSL
52 static SSL_CTX *ssl_ctx;
54 /* Initialize the SSL's PRNG using various methods. */
60 const char *random_file;
63 /* The PRNG has been seeded; no further action is necessary. */
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
70 random_file = opt.random_file;
73 /* Get the random file name using RAND_file_name. */
75 random_file = RAND_file_name (namebuf, sizeof (namebuf));
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);
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);
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
103 #if 0 /* don't do this by default */
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. */
112 logprintf (LOG_NOTQUIET, _("WARNING: using a weak random seed.\n"));
114 while (RAND_status () == 0 && maxrand-- > 0)
116 unsigned char rnd = random_number (256);
117 RAND_seed (&rnd, sizeof (rnd));
123 /* Print errors in the OpenSSL error stack. */
129 while ((err = ERR_get_error ()) != 0)
130 logprintf (LOG_NOTQUIET, "OpenSSL: %s\n", ERR_error_string (err, NULL));
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.
136 (options.h intentionally doesn't use values from openssl/ssl.h so
137 it doesn't depend specifically on OpenSSL for SSL functionality.) */
140 key_type_to_ssl_type (enum keyfile_type type)
145 return SSL_FILETYPE_PEM;
147 return SSL_FILETYPE_ASN1;
153 /* Create an SSL Context and set default paths etc. Called the first
154 time an HTTP download is attempted.
156 Returns true on success, false otherwise. */
161 const SSL_METHOD *meth;
164 /* The SSL has already been initialized. */
167 /* Init the PRNG. If that fails, bail out. */
169 if (RAND_status () != 1)
171 logprintf (LOG_NOTQUIET,
172 _("Could not seed PRNG; consider using --random-file.\n"));
177 SSL_load_error_strings ();
178 SSLeay_add_all_algorithms ();
179 SSLeay_add_ssl_algorithms ();
181 switch (opt.secure_protocol)
183 case secure_protocol_auto:
184 meth = SSLv23_client_method ();
186 case secure_protocol_sslv2:
187 meth = SSLv2_client_method ();
189 case secure_protocol_sslv3:
190 meth = SSLv3_client_method ();
192 case secure_protocol_tlsv1:
193 meth = TLSv1_client_method ();
199 ssl_ctx = SSL_CTX_new (meth);
203 SSL_CTX_set_default_verify_paths (ssl_ctx);
204 SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory);
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);
213 if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
214 key_type_to_ssl_type (opt.cert_type))
218 if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key,
219 key_type_to_ssl_type (opt.private_key_type))
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);
227 /* The OpenSSL library can handle renegotiations automatically, so
229 SSL_CTX_set_mode (ssl_ctx, SSL_MODE_AUTO_RETRY);
235 SSL_CTX_free (ssl_ctx);
240 struct openssl_transport_context {
241 SSL *conn; /* SSL connection handle */
242 char *last_error; /* last error printed with openssl_errstr */
246 openssl_read (int fd, char *buf, int bufsize, void *arg)
249 struct openssl_transport_context *ctx = arg;
250 SSL *conn = ctx->conn;
252 ret = SSL_read (conn, buf, bufsize);
254 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
260 openssl_write (int fd, char *buf, int bufsize, void *arg)
263 struct openssl_transport_context *ctx = arg;
264 SSL *conn = ctx->conn;
266 ret = SSL_write (conn, buf, bufsize);
268 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
274 openssl_poll (int fd, double timeout, int wait_for, void *arg)
276 struct openssl_transport_context *ctx = arg;
277 SSL *conn = ctx->conn;
280 if (SSL_pending (conn))
282 return select_fd (fd, timeout, wait_for);
286 openssl_peek (int fd, char *buf, int bufsize, void *arg)
289 struct openssl_transport_context *ctx = arg;
290 SSL *conn = ctx->conn;
292 ret = SSL_peek (conn, buf, bufsize);
294 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
300 openssl_errstr (int fd, void *arg)
302 struct openssl_transport_context *ctx = arg;
303 unsigned long errcode;
307 /* If there are no SSL-specific errors, just return NULL. */
308 if ((errcode = ERR_get_error ()) == 0)
311 /* Get rid of previous contents of ctx->last_error, if any. */
312 xfree_null (ctx->last_error);
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. */
322 const char *str = ERR_error_string (errcode, NULL);
323 int len = strlen (str);
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);
331 /* Get next error and bail out if there are no more. */
332 errcode = ERR_get_error ();
336 errmsg[msglen++] = ';';
337 errmsg[msglen++] = ' ';
339 errmsg[msglen] = '\0';
341 /* Store the error in ctx->last_error where openssl_close will
342 eventually find it and free it. */
343 ctx->last_error = errmsg;
349 openssl_close (int fd, void *arg)
351 struct openssl_transport_context *ctx = arg;
352 SSL *conn = ctx->conn;
356 xfree_null (ctx->last_error);
365 DEBUGP (("Closed %d/SSL 0x%0*lx\n", fd, PTR_FORMAT (conn)));
368 /* openssl_transport is the singleton that describes the SSL transport
369 methods provided by this file. */
371 static struct transport_implementation openssl_transport = {
372 openssl_read, openssl_write, openssl_poll,
373 openssl_peek, openssl_errstr, openssl_close
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.
382 Returns true on success, false on failure. */
388 struct openssl_transport_context *ctx;
390 DEBUGP (("Initiating SSL handshake.\n"));
392 assert (ssl_ctx != NULL);
393 conn = SSL_new (ssl_ctx);
396 if (!SSL_set_fd (conn, fd))
398 SSL_set_connect_state (conn);
399 if (SSL_connect (conn) <= 0 || conn->state != SSL_ST_OK)
402 ctx = xnew0 (struct openssl_transport_context);
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)));
413 DEBUGP (("SSL handshake failed.\n"));
420 #define ASTERISK_EXCLUDES_DOT /* mandated by rfc2818 */
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.
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]."
433 If the pattern contain no wildcards, pattern_match(a, b) is
434 equivalent to !strcasecmp(a, b). */
437 pattern_match (const char *pattern, const char *string)
439 const char *p = pattern, *n = string;
441 for (; (c = TOLOWER (*p++)) != '\0'; n++)
444 for (c = TOLOWER (*p); c == '*'; c = TOLOWER (*++p))
446 for (; *n != '\0'; n++)
447 if (TOLOWER (*n) == c && pattern_match (p, n))
449 #ifdef ASTERISK_EXCLUDES_DOT
457 if (c != TOLOWER (*n))
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.)
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
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. */
478 ssl_check_certificate (int fd, const char *host)
481 char common_name[256];
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");
489 struct openssl_transport_context *ctx = fd_transport_context (fd);
490 SSL *conn = ctx->conn;
491 assert (conn != NULL);
493 cert = SSL_get_peer_certificate (conn);
496 logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
497 severity, escnonprint (host));
499 goto no_cert; /* must bail out since CERT is NULL */
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);
512 vresult = SSL_get_verify_result (conn);
513 if (vresult != X509_V_OK)
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. */
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"));
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"));
531 case X509_V_ERR_CERT_NOT_YET_VALID:
532 logprintf (LOG_NOTQUIET, _(" Issued certificate not yet valid.\n"));
534 case X509_V_ERR_CERT_HAS_EXPIRED:
535 logprintf (LOG_NOTQUIET, _(" Issued certificate has expired.\n"));
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));
544 /* Fall through, so that the user is warned about *all* issues
545 with the cert (important with --no-check-certificate.) */
548 /* Check that HOST matches the common name in the certificate.
549 #### The following remains to be done:
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."
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.
559 - Ensure that ASN1 strings from the certificate are encoded as
560 UTF-8 which can be meaningfully compared to HOST. */
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))
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));
574 DEBUGP (("X509 certificate successfully verified and matches host %s\n",
575 escnonprint (host)));
579 if (opt.check_cert && !success)
580 logprintf (LOG_NOTQUIET, _("\
581 To connect to %s insecurely, use `--no-check-certificate'.\n"),
584 /* Allow --no-check-cert to disable certificate checking. */
585 return opt.check_cert ? success : true;