]> sjero.net Git - wget/blobdiff - src/gnutls.c
Translation fixes.
[wget] / src / gnutls.c
index 5cf8bd8d208d379280fe482a1b2a1fc52b018df7..dfbe8bf525fea25d84c14ad6b6aa9e15a72e05ef 100644 (file)
@@ -1,11 +1,11 @@
 /* SSL support via GnuTLS library.
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
 GNU Wget is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
+the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version.
 
 GNU Wget is distributed in the hope that it will be useful,
@@ -14,20 +14,20 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with Wget; if not, write to the Free Software Foundation, Inc.,
-51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+along with Wget.  If not, see <http://www.gnu.org/licenses/>.
 
-In addition, as a special exception, the Free Software Foundation
-gives permission to link the code of its release of Wget with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables.  You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL".  If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so.  If you do not wish to do
-so, delete this exception statement from your version.  */
+Additional permission under GNU GPL version 3 section 7
 
-#include <config.h>
+If you modify this program, or any covered work, by linking or
+combining it with the OpenSSL project's OpenSSL library (or a
+modified version of that library), containing parts covered by the
+terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
+grants you additional permission to convey the resulting work.
+Corresponding Source for a non-source form of such a combination
+shall include the source code for the parts of OpenSSL used as well
+as that of the covered work.  */
+
+#include "wget.h"
 
 #include <assert.h>
 #include <errno.h>
@@ -38,8 +38,8 @@ so, delete this exception statement from your version.  */
 #include <stdio.h>
 
 #include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
 
-#include "wget.h"
 #include "utils.h"
 #include "connect.h"
 #include "url.h"
@@ -59,13 +59,13 @@ ssl_init ()
   gnutls_certificate_allocate_credentials (&credentials);
   if (opt.ca_cert)
     gnutls_certificate_set_x509_trust_file (credentials, opt.ca_cert,
-                                           GNUTLS_X509_FMT_PEM);
+                                            GNUTLS_X509_FMT_PEM);
   return true;
 }
 
 struct wgnutls_transport_context {
-  gnutls_session session;      /* GnuTLS session handle */
-  int last_error;              /* last error returned by read/write/... */
+  gnutls_session session;       /* GnuTLS session handle */
+  int last_error;               /* last error returned by read/write/... */
 
   /* Since GnuTLS doesn't support the equivalent to recv(...,
      MSG_PEEK) or SSL_peek(), we have to do it ourselves.  Peeked data
@@ -92,9 +92,9 @@ wgnutls_read (int fd, char *buf, int bufsize, void *arg)
       memcpy (buf, ctx->peekbuf + ctx->peekstart, copysize);
       ctx->peeklen -= copysize;
       if (ctx->peeklen != 0)
-       ctx->peekstart += copysize;
+        ctx->peekstart += copysize;
       else
-       ctx->peekstart = 0;
+        ctx->peekstart = 0;
       return copysize;
     }
 
@@ -212,43 +212,91 @@ ssl_check_certificate (int fd, const char *host)
   struct wgnutls_transport_context *ctx = fd_transport_context (fd);
 
   unsigned int status;
-  const gnutls_datum *cert_list;
-  int cert_list_size, ret;
-  gnutls_x509_crt cert;
+  int err;
 
   /* If the user has specified --no-check-cert, we still want to warn
      him about problems with the server's certificate.  */
   const char *severity = opt.check_cert ? _("ERROR") : _("WARNING");
   bool success = true;
 
-  ret = gnutls_certificate_verify_peers2 (ctx->session, &status);
-  if (ret < 0)
+  err = gnutls_certificate_verify_peers2 (ctx->session, &status);
+  if (err < 0)
     {
       logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
-                severity, escnonprint (host));
+                 severity, quotearg_style (escape_quoting_style, host));
       success = false;
-      goto no_cert;
+      goto out;
     }
 
   if (status & GNUTLS_CERT_INVALID)
     {
-      logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' is not trusted.\n"),
-                severity, escnonprint (host));
+      logprintf (LOG_NOTQUIET, _("%s: The certificate of %s is not trusted.\n"),
+                 severity, quote (host));
       success = false;
     }
   if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
     {
-      logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' hasn't got a known issuer.\n"),
-                severity, escnonprint (host));
+      logprintf (LOG_NOTQUIET, _("%s: The certificate of %s hasn't got a known issuer.\n"),
+                 severity, quote (host));
       success = false;
     }
   if (status & GNUTLS_CERT_REVOKED)
     {
-      logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' has been revoked.\n"),
-                severity, escnonprint (host));
+      logprintf (LOG_NOTQUIET, _("%s: The certificate of %s has been revoked.\n"),
+                 severity, quote (host));
       success = false;
     }
 
- no_cert:
+  if (gnutls_certificate_type_get (ctx->session) == GNUTLS_CRT_X509)
+    {
+      time_t now = time (NULL);
+      gnutls_x509_crt cert;
+      const gnutls_datum *cert_list;
+      unsigned int cert_list_size;
+
+      if ((err = gnutls_x509_crt_init (&cert)) < 0)
+        {
+          logprintf (LOG_NOTQUIET, _("Error initializing X509 certificate: %s\n"),
+                     gnutls_strerror (err));
+          success = false;
+          goto out;
+        }
+
+      cert_list = gnutls_certificate_get_peers (ctx->session, &cert_list_size);
+      if (!cert_list)
+        {
+          logprintf (LOG_NOTQUIET, _("No certificate found\n"));
+          success = false;
+          goto out;
+        }
+      err = gnutls_x509_crt_import (cert, cert_list, GNUTLS_X509_FMT_DER);
+      if (err < 0)
+        {
+          logprintf (LOG_NOTQUIET, _("Error parsing certificate: %s\n"),
+                     gnutls_strerror (err));
+          success = false;
+          goto out;
+        }
+      if (now < gnutls_x509_crt_get_activation_time (cert))
+        {
+          logprintf (LOG_NOTQUIET, _("The certificate has not yet been activated\n"));
+          success = false;
+        }
+      if (now >= gnutls_x509_crt_get_expiration_time (cert))
+        {
+          logprintf (LOG_NOTQUIET, _("The certificate has expired\n"));
+          success = false;
+        }
+      if (!gnutls_x509_crt_check_hostname (cert, host))
+        {
+          logprintf (LOG_NOTQUIET,
+                     _("The certificate's owner does not match hostname %s\n"),
+                     quote (host));
+          success = false;
+        }
+      gnutls_x509_crt_deinit (cert);
+   }
+
+ out:
   return opt.check_cert ? success : true;
 }