1 /* SSL support via OpenSSL library.
2 Copyright (C) 2000-2005 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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 In addition, as a special exception, the Free Software Foundation
22 gives permission to link the code of its release of Wget with the
23 OpenSSL project's "OpenSSL" library (or with modified versions of it
24 that use the same license as the "OpenSSL" library), and distribute
25 the linked executables. You must obey the GNU General Public License
26 in all respects for all of the code used other than "OpenSSL". If you
27 modify this file, you may extend this exception to your version of the
28 file, but you are not obligated to do so. If you do not wish to do
29 so, delete this exception statement from your version. */
44 #include <openssl/ssl.h>
45 #include <openssl/x509.h>
46 #include <openssl/err.h>
47 #include <openssl/rand.h>
59 /* Application-wide SSL context. This is common to all SSL
63 /* Initialize the SSL's PRNG using various methods. */
69 const char *random_file;
72 /* The PRNG has been seeded; no further action is necessary. */
75 /* Seed from a file specified by the user. This will be the file
76 specified with --random-file, $RANDFILE, if set, or ~/.rnd, if it
79 random_file = opt.random_file;
82 /* Get the random file name using RAND_file_name. */
84 random_file = RAND_file_name (namebuf, sizeof (namebuf));
87 if (random_file && *random_file)
88 /* Seed at most 16k (apparently arbitrary value borrowed from
89 curl) from random file. */
90 RAND_load_file (random_file, 16384);
95 /* Get random data from EGD if opt.egd_file was used. */
96 if (opt.egd_file && *opt.egd_file)
97 RAND_egd (opt.egd_file);
103 /* Under Windows, we can try to seed the PRNG using screen content.
104 This may or may not work, depending on whether we'll calling Wget
112 #if 0 /* don't do this by default */
116 /* Still not random enough, presumably because neither /dev/random
117 nor EGD were available. Try to seed OpenSSL's PRNG with libc
118 PRNG. This is cryptographically weak and defeats the purpose
119 of using OpenSSL, which is why it is highly discouraged. */
121 logprintf (LOG_NOTQUIET, _("WARNING: using a weak random seed.\n"));
123 while (RAND_status () == 0 && maxrand-- > 0)
125 unsigned char rnd = random_number (256);
126 RAND_seed (&rnd, sizeof (rnd));
132 /* Print errors in the OpenSSL error stack. */
137 unsigned long curerr = 0;
138 while ((curerr = ERR_get_error ()) != 0)
139 logprintf (LOG_NOTQUIET, "OpenSSL: %s\n", ERR_error_string (curerr, NULL));
142 /* Convert keyfile type as used by options.h to a type as accepted by
143 SSL_CTX_use_certificate_file and SSL_CTX_use_PrivateKey_file.
145 (options.h intentionally doesn't use values from openssl/ssl.h so
146 it doesn't depend specifically on OpenSSL for SSL functionality.) */
149 key_type_to_ssl_type (enum keyfile_type type)
154 return SSL_FILETYPE_PEM;
156 return SSL_FILETYPE_ASN1;
162 /* Create an SSL Context and set default paths etc. Called the first
163 time an HTTP download is attempted.
165 Returns 1 on success, 0 otherwise. */
173 /* The SSL has already been initialized. */
176 /* Init the PRNG. If that fails, bail out. */
178 if (RAND_status () != 1)
180 logprintf (LOG_NOTQUIET,
181 _("Could not seed PRNG; consider using --random-file.\n"));
186 SSL_load_error_strings ();
187 SSLeay_add_all_algorithms ();
188 SSLeay_add_ssl_algorithms ();
190 switch (opt.secure_protocol)
192 case secure_protocol_auto:
193 meth = SSLv23_client_method ();
195 case secure_protocol_sslv2:
196 meth = SSLv2_client_method ();
198 case secure_protocol_sslv3:
199 meth = SSLv3_client_method ();
201 case secure_protocol_tlsv1:
202 meth = TLSv1_client_method ();
208 ssl_ctx = SSL_CTX_new (meth);
212 SSL_CTX_set_default_verify_paths (ssl_ctx);
213 SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory);
215 /* SSL_VERIFY_NONE instructs OpenSSL not to abort SSL_connect if the
216 certificate is invalid. We verify the certificate separately in
217 ssl_check_certificate, which provides much better diagnostics
218 than examining the error stack after a failed SSL_connect. */
219 SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL);
222 if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
223 key_type_to_ssl_type (opt.cert_type))
227 if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key,
228 key_type_to_ssl_type (opt.private_key_type))
232 /* Since fd_write unconditionally assumes partial writes (and
233 handles them correctly), allow them in OpenSSL. */
234 SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
240 SSL_CTX_free (ssl_ctx);
246 openssl_read (int fd, char *buf, int bufsize, void *ctx)
249 SSL *ssl = (SSL *) ctx;
251 ret = SSL_read (ssl, buf, bufsize);
253 && SSL_get_error (ssl, ret) == SSL_ERROR_SYSCALL
259 openssl_write (int fd, char *buf, int bufsize, void *ctx)
262 SSL *ssl = (SSL *) ctx;
264 ret = SSL_write (ssl, buf, bufsize);
266 && SSL_get_error (ssl, ret) == SSL_ERROR_SYSCALL
272 openssl_poll (int fd, double timeout, int wait_for, void *ctx)
274 SSL *ssl = (SSL *) ctx;
277 if (SSL_pending (ssl))
279 return select_fd (fd, timeout, wait_for);
283 openssl_peek (int fd, char *buf, int bufsize, void *ctx)
286 SSL *ssl = (SSL *) ctx;
288 ret = SSL_peek (ssl, buf, bufsize);
290 && SSL_get_error (ssl, ret) == SSL_ERROR_SYSCALL
296 openssl_close (int fd, void *ctx)
298 SSL *ssl = (SSL *) ctx;
308 DEBUGP (("Closed %d/SSL 0x%0lx\n", fd, (unsigned long) ssl));
311 /* Perform the SSL handshake on file descriptor FD, which is assumed
312 to be connected to an SSL server. The SSL handle provided by
313 OpenSSL is registered with the file descriptor FD using
314 fd_register_transport, so that subsequent calls to fd_read,
315 fd_write, etc., will use the corresponding SSL functions.
317 Returns 1 on success, 0 on failure. */
324 DEBUGP (("Initiating SSL handshake.\n"));
326 assert (ssl_ctx != NULL);
327 ssl = SSL_new (ssl_ctx);
330 if (!SSL_set_fd (ssl, fd))
332 SSL_set_connect_state (ssl);
333 if (SSL_connect (ssl) <= 0 || ssl->state != SSL_ST_OK)
336 /* Register FD with Wget's transport layer, i.e. arrange that our
337 functions are used for reading, writing, and polling. */
338 fd_register_transport (fd, openssl_read, openssl_write, openssl_poll,
339 openssl_peek, openssl_close, ssl);
340 DEBUGP (("Handshake successful; connected socket %d to SSL handle 0x%0*lx\n",
341 fd, PTR_FORMAT (ssl)));
345 DEBUGP (("SSL handshake failed.\n"));
352 #define ASTERISK_EXCLUDES_DOT /* mandated by rfc2818 */
354 /* Return 1 is STRING (case-insensitively) matches PATTERN, 0
355 otherwise. The recognized wildcard character is "*", which matches
356 any character in STRING except ".". Any number of the "*" wildcard
357 may be present in the pattern.
359 This is used to match of hosts as indicated in rfc2818: "Names may
360 contain the wildcard character * which is considered to match any
361 single domain name component or component fragment. E.g., *.a.com
362 matches foo.a.com but not bar.foo.a.com. f*.com matches foo.com but
363 not bar.com [or foo.bar.com]."
365 If the pattern contain no wildcards, pattern_match(a, b) is
366 equivalent to !strcasecmp(a, b). */
369 pattern_match (const char *pattern, const char *string)
371 const char *p = pattern, *n = string;
373 for (; (c = TOLOWER (*p++)) != '\0'; n++)
376 for (c = TOLOWER (*p); c == '*'; c = TOLOWER (*++p))
378 for (; *n != '\0'; n++)
379 if (TOLOWER (*n) == c && pattern_match (p, n))
381 #ifdef ASTERISK_EXCLUDES_DOT
389 if (c != TOLOWER (*n))
395 /* Verify the validity of the certificate presented by the server.
396 Also check that the "common name" of the server, as presented by
397 its certificate, corresponds to HOST. (HOST typically comes from
398 the URL and is what the user thinks he's connecting to.)
400 This assumes that ssl_connect has successfully finished, i.e. that
401 the SSL handshake has been performed and that FD is connected to an
404 If opt.check_cert is non-zero (the default), this returns 1 if the
405 certificate is valid, 0 otherwise. If opt.check_cert is 0, the
406 function always returns 1, but should still be called because it
407 warns the user about any problems with the certificate. */
410 ssl_check_certificate (int fd, const char *host)
413 char common_name[256];
417 /* If the user has specified --no-check-cert, we still want to warn
418 him about problems with the server's certificate. */
419 const char *severity = opt.check_cert ? _("ERROR") : _("WARNING");
421 SSL *ssl = (SSL *) fd_transport_context (fd);
422 assert (ssl != NULL);
424 cert = SSL_get_peer_certificate (ssl);
427 logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
428 severity, escnonprint (host));
430 goto out; /* must bail out since CERT is NULL */
436 char *subject = X509_NAME_oneline (X509_get_subject_name (cert), 0, 0);
437 char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
438 DEBUGP (("certificate:\n subject: %s\n issuer: %s\n",
439 escnonprint (subject), escnonprint (issuer)));
440 OPENSSL_free (subject);
441 OPENSSL_free (issuer);
445 vresult = SSL_get_verify_result (ssl);
446 if (vresult != X509_V_OK)
448 /* #### We might want to print saner (and translatable) error
449 messages for several frequently encountered errors. The
450 candidates would include
451 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
452 X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN,
453 X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT,
454 X509_V_ERR_CERT_NOT_YET_VALID, X509_V_ERR_CERT_HAS_EXPIRED,
455 and possibly others. The current approach would still be
456 used for the less frequent failure cases. */
457 logprintf (LOG_NOTQUIET,
458 _("%s: Certificate verification error for %s: %s\n"),
459 severity, escnonprint (host),
460 X509_verify_cert_error_string (vresult));
462 /* Fall through, so that the user is warned about *all* issues
463 with the cert (important with --no-check-certificate.) */
466 /* Check that HOST matches the common name in the certificate.
467 #### The following remains to be done:
469 - It should use dNSName/ipAddress subjectAltName extensions if
470 available; according to rfc2818: "If a subjectAltName extension
471 of type dNSName is present, that MUST be used as the identity."
473 - When matching against common names, it should loop over all
474 common names and choose the most specific one, i.e. the last
475 one, not the first one, which the current code picks.
477 - Make sure that the names are encoded as UTF-8 which, being
478 ASCII-compatible, can be easily compared against HOST. */
480 common_name[0] = '\0';
481 X509_NAME_get_text_by_NID (X509_get_subject_name (cert),
482 NID_commonName, common_name, sizeof (common_name));
483 if (!pattern_match (common_name, host))
485 logprintf (LOG_NOTQUIET, _("\
486 %s: certificate common name `%s' doesn't match requested host name `%s'.\n"),
487 severity, escnonprint (common_name), escnonprint (host));
492 DEBUGP (("X509 certificate successfully verified and matches host %s\n",
493 escnonprint (host)));
497 if (opt.check_cert && !success)
498 logprintf (LOG_NOTQUIET, _("\
499 To connect to %s insecurely, use `--no-check-certificate'.\n"),
502 /* Allow --no-check-cert to disable certificate checking. */
503 return opt.check_cert ? success : 1;