]> sjero.net Git - wget/blobdiff - src/gnutls.c
[svn] Merge of fix for bugs 20341 and 20410.
[wget] / src / gnutls.c
index 5cf8bd8d208d379280fe482a1b2a1fc52b018df7..314342b48d01988801b18bf507d945b06d100784 100644 (file)
@@ -1,11 +1,11 @@
 /* SSL support via GnuTLS library.
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005-2006 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,8 +14,7 @@ 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
@@ -38,6 +37,7 @@ 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"
@@ -212,22 +212,20 @@ 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));
       success = false;
-      goto no_cert;
+      goto out;
     }
 
   if (status & GNUTLS_CERT_INVALID)
@@ -249,6 +247,56 @@ ssl_check_certificate (int fd, const char *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"),
+                    host);
+         success = false;
+       }
+      gnutls_x509_crt_deinit (cert);
+   }
+
+ out:
   return opt.check_cert ? success : true;
 }