1 /* SSL support via OpenSSL library.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 2009, 2010, 2011 Free Software Foundation, Inc.
4 Originally contributed by Christian Fraenkel.
6 This file is part of GNU Wget.
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.
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.
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/>.
21 Additional permission under GNU GPL version 3 section 7
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. */
39 #include <openssl/ssl.h>
40 #include <openssl/x509v3.h>
41 #include <openssl/err.h>
42 #include <openssl/rand.h>
49 /* Application-wide SSL context. This is common to all SSL
51 static SSL_CTX *ssl_ctx;
53 /* Initialize the SSL's PRNG using various methods. */
59 const char *random_file;
62 /* The PRNG has been seeded; no further action is necessary. */
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
69 random_file = opt.random_file;
72 /* Get the random file name using RAND_file_name. */
74 random_file = RAND_file_name (namebuf, sizeof (namebuf));
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);
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);
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
102 #if 0 /* don't do this by default */
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. */
111 logprintf (LOG_NOTQUIET, _("WARNING: using a weak random seed.\n"));
113 while (RAND_status () == 0 && maxrand-- > 0)
115 unsigned char rnd = random_number (256);
116 RAND_seed (&rnd, sizeof (rnd));
122 /* Print errors in the OpenSSL error stack. */
128 while ((err = ERR_get_error ()) != 0)
129 logprintf (LOG_NOTQUIET, "OpenSSL: %s\n", ERR_error_string (err, NULL));
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.
135 (options.h intentionally doesn't use values from openssl/ssl.h so
136 it doesn't depend specifically on OpenSSL for SSL functionality.) */
139 key_type_to_ssl_type (enum keyfile_type type)
144 return SSL_FILETYPE_PEM;
146 return SSL_FILETYPE_ASN1;
152 /* Create an SSL Context and set default paths etc. Called the first
153 time an HTTP download is attempted.
155 Returns true on success, false otherwise. */
163 /* The SSL has already been initialized. */
166 /* Init the PRNG. If that fails, bail out. */
168 if (RAND_status () != 1)
170 logprintf (LOG_NOTQUIET,
171 _("Could not seed PRNG; consider using --random-file.\n"));
176 SSL_load_error_strings ();
177 SSLeay_add_all_algorithms ();
178 SSLeay_add_ssl_algorithms ();
180 switch (opt.secure_protocol)
182 case secure_protocol_auto:
183 meth = SSLv23_client_method ();
185 case secure_protocol_sslv2:
186 meth = SSLv2_client_method ();
188 case secure_protocol_sslv3:
189 meth = SSLv3_client_method ();
191 case secure_protocol_tlsv1:
192 meth = TLSv1_client_method ();
198 ssl_ctx = SSL_CTX_new (meth);
202 SSL_CTX_set_default_verify_paths (ssl_ctx);
203 SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory);
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);
211 /* Use the private key from the cert file unless otherwise specified. */
212 if (opt.cert_file && !opt.private_key)
214 opt.private_key = opt.cert_file;
215 opt.private_key_type = opt.cert_type;
219 if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
220 key_type_to_ssl_type (opt.cert_type))
224 if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key,
225 key_type_to_ssl_type (opt.private_key_type))
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);
233 /* The OpenSSL library can handle renegotiations automatically, so
235 SSL_CTX_set_mode (ssl_ctx, SSL_MODE_AUTO_RETRY);
241 SSL_CTX_free (ssl_ctx);
246 struct openssl_transport_context {
247 SSL *conn; /* SSL connection handle */
248 char *last_error; /* last error printed with openssl_errstr */
252 openssl_read (int fd, char *buf, int bufsize, void *arg)
255 struct openssl_transport_context *ctx = arg;
256 SSL *conn = ctx->conn;
258 ret = SSL_read (conn, buf, bufsize);
260 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
266 openssl_write (int fd, char *buf, int bufsize, void *arg)
269 struct openssl_transport_context *ctx = arg;
270 SSL *conn = ctx->conn;
272 ret = SSL_write (conn, buf, bufsize);
274 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
280 openssl_poll (int fd, double timeout, int wait_for, void *arg)
282 struct openssl_transport_context *ctx = arg;
283 SSL *conn = ctx->conn;
286 if (SSL_pending (conn))
288 return select_fd (fd, timeout, wait_for);
292 openssl_peek (int fd, char *buf, int bufsize, void *arg)
295 struct openssl_transport_context *ctx = arg;
296 SSL *conn = ctx->conn;
298 ret = SSL_peek (conn, buf, bufsize);
300 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
306 openssl_errstr (int fd, void *arg)
308 struct openssl_transport_context *ctx = arg;
309 unsigned long errcode;
313 /* If there are no SSL-specific errors, just return NULL. */
314 if ((errcode = ERR_get_error ()) == 0)
317 /* Get rid of previous contents of ctx->last_error, if any. */
318 xfree_null (ctx->last_error);
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. */
328 const char *str = ERR_error_string (errcode, NULL);
329 int len = strlen (str);
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);
337 /* Get next error and bail out if there are no more. */
338 errcode = ERR_get_error ();
342 errmsg[msglen++] = ';';
343 errmsg[msglen++] = ' ';
345 errmsg[msglen] = '\0';
347 /* Store the error in ctx->last_error where openssl_close will
348 eventually find it and free it. */
349 ctx->last_error = errmsg;
355 openssl_close (int fd, void *arg)
357 struct openssl_transport_context *ctx = arg;
358 SSL *conn = ctx->conn;
362 xfree_null (ctx->last_error);
367 DEBUGP (("Closed %d/SSL 0x%0*lx\n", fd, PTR_FORMAT (conn)));
370 /* openssl_transport is the singleton that describes the SSL transport
371 methods provided by this file. */
373 static struct transport_implementation openssl_transport = {
374 openssl_read, openssl_write, openssl_poll,
375 openssl_peek, openssl_errstr, openssl_close
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.
384 Returns true on success, false on failure. */
387 ssl_connect_wget (int fd)
390 struct openssl_transport_context *ctx;
392 DEBUGP (("Initiating SSL handshake.\n"));
394 assert (ssl_ctx != NULL);
395 conn = SSL_new (ssl_ctx);
399 # define FD_TO_SOCKET(X) (X)
401 if (!SSL_set_fd (conn, FD_TO_SOCKET (fd)))
403 SSL_set_connect_state (conn);
404 if (SSL_connect (conn) <= 0 || conn->state != SSL_ST_OK)
407 ctx = xnew0 (struct openssl_transport_context);
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)));
418 DEBUGP (("SSL handshake failed.\n"));
425 #define ASTERISK_EXCLUDES_DOT /* mandated by rfc2818 */
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.
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]."
438 If the pattern contain no wildcards, pattern_match(a, b) is
439 equivalent to !strcasecmp(a, b). */
442 pattern_match (const char *pattern, const char *string)
444 const char *p = pattern, *n = string;
446 for (; (c = c_tolower (*p++)) != '\0'; n++)
449 for (c = c_tolower (*p); c == '*'; c = c_tolower (*++p))
451 for (; *n != '\0'; n++)
452 if (c_tolower (*n) == c && pattern_match (p, n))
454 #ifdef ASTERISK_EXCLUDES_DOT
462 if (c != c_tolower (*n))
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.)
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
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. */
483 ssl_check_certificate (int fd, const char *host)
486 GENERAL_NAMES *subjectAltNames;
487 char common_name[256];
490 bool alt_name_checked = false;
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");
496 struct openssl_transport_context *ctx = fd_transport_context (fd);
497 SSL *conn = ctx->conn;
498 assert (conn != NULL);
500 cert = SSL_get_peer_certificate (conn);
503 logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
504 severity, quotearg_style (escape_quoting_style, host));
506 goto no_cert; /* must bail out since CERT is NULL */
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);
520 vresult = SSL_get_verify_result (conn);
521 if (vresult != X509_V_OK)
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. */
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"));
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"));
541 case X509_V_ERR_CERT_NOT_YET_VALID:
542 logprintf (LOG_NOTQUIET, _(" Issued certificate not yet valid.\n"));
544 case X509_V_ERR_CERT_HAS_EXPIRED:
545 logprintf (LOG_NOTQUIET, _(" Issued certificate has expired.\n"));
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));
554 /* Fall through, so that the user is warned about *all* issues
555 with the cert (important with --no-check-certificate.) */
558 /* Check that HOST matches the common name in the certificate.
559 #### The following remains to be done:
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.
565 - Ensure that ASN1 strings from the certificate are encoded as
566 UTF-8 which can be meaningfully compared to HOST. */
568 subjectAltNames = X509_get_ext_d2i (cert, NID_subject_alt_name, NULL, NULL);
572 /* Test subject alternative names */
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);
578 int numaltnames = sk_GENERAL_NAME_num (subjectAltNames);
580 for (i=0; i < numaltnames; i++)
582 const GENERAL_NAME *name =
583 sk_GENERAL_NAME_value (subjectAltNames, i);
586 if (host_in_octet_string)
588 if (name->type == GEN_IPADD)
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,
599 else if (name->type == GEN_DNS)
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;
605 /* Check for dNSName */
606 alt_name_checked = true;
608 if (0 <= ASN1_STRING_to_UTF8 (&name_in_utf8, name->d.dNSName))
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)))
615 OPENSSL_free (name_in_utf8);
618 OPENSSL_free (name_in_utf8);
623 sk_GENERAL_NAME_free (subjectAltNames);
624 if (host_in_octet_string)
625 ASN1_OCTET_STRING_free(host_in_octet_string);
627 if (alt_name_checked == true && i >= numaltnames)
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));
637 if (alt_name_checked == false)
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));
645 if (!pattern_match (common_name, host))
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));
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.
659 * https://www.blackhat.com/html/bh-usa-09/bh-usa-09-archives.html#Marlinspike
663 X509_NAME_ENTRY *xentry;
669 j = X509_NAME_get_index_by_NID (xname, NID_commonName, i);
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))
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));
691 DEBUGP (("X509 certificate successfully verified and matches host %s\n",
692 quotearg_style (escape_quoting_style, host)));
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));
701 /* Allow --no-check-cert to disable certificate checking. */
702 return opt.check_cert ? success : true;
706 * vim: tabstop=2 shiftwidth=2 softtabstop=2