diff --git a/src/ChangeLog b/src/ChangeLog
index 7c9eeea9..d505b4c5 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,19 @@
+2001-02-08  Christian Fraenkel <christian.fraenkel@gmx.net>
+
+        * gen_sslfunc.c: verify_callback is now static
+
+        * gen_sslfunc.c (init_ssl): load certificate if specified
+
+        * gen_sslfunc.c (ssl_printerr): new function
+
+        * init.c: added new --sslcertfile and --sslcertkey switches
+
+        * main.c: ditto
+
+        * options.h: ditto
+
+        * http.c (gethttp): abort when init_ssl fails
+
 2001-01-23  Herold Heiko  <Heiko.Herold@previnet.it>
 
 	* mswindows.h: Include <malloc.h>; it's needed for alloca().
diff --git a/src/gen_sslfunc.c b/src/gen_sslfunc.c
index 8b64b581..c19cc66f 100644
--- a/src/gen_sslfunc.c
+++ b/src/gen_sslfunc.c
@@ -32,8 +32,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <openssl/err.h>
 #include <openssl/pem.h>
 
-#define SSL_ERR_CTX_CREATION -2
-
 #include "wget.h"
 #include "connect.h"
 
@@ -41,11 +39,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 extern int errno;
 #endif
 
-/* #### Shouldn't this be static?  --hniksic */
-int verify_callback PARAMS ((int, X509_STORE_CTX *));
+static int verify_callback PARAMS ((int, X509_STORE_CTX *));
 
 /* Creates a SSL Context and sets some defaults for it */
-int
+uerr_t
 init_ssl (SSL_CTX **ctx)
 {
   SSL_METHOD *meth = NULL;
@@ -57,7 +54,18 @@ init_ssl (SSL_CTX **ctx)
   meth = SSLv23_client_method ();
   *ctx = SSL_CTX_new (meth);
   SSL_CTX_set_verify (*ctx, verify, verify_callback);
-  if (*ctx == NULL) return SSL_ERR_CTX_CREATION;
+  if (*ctx == NULL) return SSLERRCTXCREATE;
+  if (opt.sslcertfile)
+    {
+      if (SSL_CTX_use_certificate_file (*ctx, opt.sslcertfile,
+					SSL_FILETYPE_PEM) <= 0)
+	return SSLERRCERTFILE;
+      if (opt.sslcertkey == NULL) 
+	opt.sslcertkey=opt.sslcertfile;
+      if (SSL_CTX_use_PrivateKey_file (*ctx, opt.sslcertkey,
+				       SSL_FILETYPE_PEM) <= 0)
+	return SSLERRCERTKEY;
+  }
   return 0; /* Succeded */
 }
 
@@ -107,6 +115,23 @@ verify_callback (int ok, X509_STORE_CTX *ctx)
   return ok;
 }
 
+/* pass all ssl errors to DEBUGP
+   returns the number of printed errors */
+int
+ssl_printerrors (void) 
+{
+  int ocerr = 0;
+  unsigned long curerr = 0;
+  char errbuff[1024];
+  memset(errbuff, 0, sizeof(errbuff));
+  for (curerr = ERR_get_error (); curerr; curerr = ERR_get_error ())
+    {
+      DEBUGP (("OpenSSL: %s\n", ERR_error_string (curerr, errbuff)));
+      ++ocerr;
+    }
+  return ocerr;
+}
+
 /* SSL version of iread. Only exchanged read for SSL_read 
    Read at most LEN bytes from FD, storing them to BUF.  This is
    virtually the same as read(), but takes care of EINTR braindamage
diff --git a/src/gen_sslfunc.h b/src/gen_sslfunc.h
index 066ebfed..fdd3da1a 100644
--- a/src/gen_sslfunc.h
+++ b/src/gen_sslfunc.h
@@ -28,4 +28,5 @@ void free_ssl_ctx PARAMS ((SSL_CTX *));
 int verify_callback PARAMS ((int, X509_STORE_CTX *));
 int ssl_iread PARAMS ((SSL *, char *, int));
 int ssl_iwrite PARAMS ((SSL *, char *, int));
+int ssl_printerrors PARAMS ((void)); 
 
diff --git a/src/http.c b/src/http.c
index 0d81a30d..b8151ea2 100644
--- a/src/http.c
+++ b/src/http.c
@@ -536,9 +536,41 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt)
   int inhibit_keep_alive;
 
 #ifdef HAVE_SSL
-/* initialize ssl_ctx on first run */
+  /* initialize ssl_ctx on first run */
   if (!ssl_ctx)
-    init_ssl (&ssl_ctx);
+    {
+      err=init_ssl (&ssl_ctx);
+      if (err != 0)
+	{
+	  switch (err)
+	    {
+	    case SSLERRCTXCREATE:
+	      /* this is fatal */
+	      logprintf (LOG_NOTQUIET, _("Failed to set up an SSL context\n"));
+	      ssl_printerrors ();
+	      return err;
+	    case SSLERRCERTFILE:
+	      /* try without certfile */
+	      logprintf (LOG_NOTQUIET,
+			 _("Failed to load certificates from %s\n"),
+			 opt.sslcertfile);
+	      ssl_printerrors ();
+	      logprintf (LOG_NOTQUIET,
+			 _("Trying without the specified certificate\n"));
+	      break;
+	    case SSLERRCERTKEY:
+	      logprintf (LOG_NOTQUIET,
+			 _("Failed to get certificate key from %s\n"),
+			 opt.sslcertkey);
+	      ssl_printerrors ();
+	      logprintf (LOG_NOTQUIET,
+			 _("Trying without the specified certificate\n"));
+	      break;
+	    default:
+	      break;
+	    }
+	}
+    }
 #endif /* HAVE_SSL */
 
   if (!(*dt & HEAD_ONLY))
@@ -1417,7 +1449,8 @@ File `%s' already there, will not retrieve.\n"), u->local);
 	  printwhat (count, opt.ntry);
 	  continue;
 	  break;
-	case HOSTERR: case CONREFUSED: case PROXERR: case AUTHFAILED:
+	case HOSTERR: case CONREFUSED: case PROXERR: case AUTHFAILED: 
+	case SSLERRCTXCREATE:
 	  /* Fatal errors just return from the function.  */
 	  FREEHSTAT (hstat);
 	  xfree (filename_plus_orig_suffix); /* must precede every return! */
diff --git a/src/init.c b/src/init.c
index 900f807d..321f50d4 100644
--- a/src/init.c
+++ b/src/init.c
@@ -161,6 +161,10 @@ static struct {
   { "simplehostcheck",	&opt.simple_check,	cmd_boolean },
   { "spanhosts",	&opt.spanhost,		cmd_boolean },
   { "spider",		&opt.spider,		cmd_boolean },
+#ifdef HAVE_SSL
+  { "sslcertfile",	&opt.sslcertfile,	cmd_string },
+  { "sslcertkey",	&opt.sslcertkey,	cmd_string },
+#endif /* HAVE_SSL */
   { "timeout",		&opt.timeout,		cmd_time },
   { "timestamping",	&opt.timestamping,	cmd_boolean },
   { "tries",		&opt.ntry,		cmd_number_inf },
@@ -1014,4 +1018,8 @@ cleanup (void)
   FREE_MAYBE (opt.http_user);
   FREE_MAYBE (opt.http_passwd);
   FREE_MAYBE (opt.user_header);
+#ifdef HAVE_SSL
+  FREE_MAYBE (opt.sslcertkey);
+  FREE_MAYBE (opt.sslcertfile);
+#endif /* HAVE_SSL */
 }
diff --git a/src/main.c b/src/main.c
index d6a19bfd..275605ca 100644
--- a/src/main.c
+++ b/src/main.c
@@ -150,6 +150,8 @@ Logging and input file:\n\
   -i,  --input-file=FILE      download URLs found in FILE.\n\
   -F,  --force-html           treat input file as HTML.\n\
   -B,  --base=URL             prepends URL to relative links in -F -i file.\n\
+       --sslcertfile=FILE     optional client certificate.\n\
+       --sslcertkey=KEYFILE   optional keyfile for this certificate.\n\
 \n"), _("\
 Download:\n\
        --bind-address=ADDRESS   bind to ADDRESS (hostname or IP) on local host.\n\
@@ -303,6 +305,10 @@ main (int argc, char *const *argv)
     { "user-agent", required_argument, NULL, 'U' },
     { "referer", required_argument, NULL, 129 },
     { "use-proxy", required_argument, NULL, 'Y' },
+#ifdef HAVE_SSL
+    { "sslcertfile", required_argument, NULL, 132},
+    { "sslcertkey", required_argument, NULL, 133},
+#endif /* HAVE_SSL */
     { "wait", required_argument, NULL, 'w' },
     { "waitretry", required_argument, NULL, 24 },
     { 0, 0, 0, 0 }
@@ -506,6 +512,14 @@ GNU General Public License for more details.\n"));
 	case 129:
 	  setval ("referer", optarg);
 	  break;
+#ifdef HAVE_SSL
+	case 132:
+	  setval ("sslcertfile", optarg);
+	  break;
+	case 133:
+	  setval ("sslcertkey", optarg);
+	  break;
+#endif /* HAVE_SSL */
 	case 'A':
 	  setval ("accept", optarg);
 	  break;
diff --git a/src/options.h b/src/options.h
index 7c1fac51..13b0bf20 100644
--- a/src/options.h
+++ b/src/options.h
@@ -153,6 +153,13 @@ struct options
 				   necessary to display a page properly. */
 
   struct sockaddr_in *bind_address; /* What local IP address to bind to. */
+
+#ifdef HAVE_SSL
+  char *sslcertfile;		/* external client cert to use. */
+  char *sslcertkey;		/* the keyfile for this certificate
+				   (if not internal) included in the
+				   certfile. */
+#endif /* HAVE_SSL */
 };
 
 #ifndef OPTIONS_DEFINED_HERE
diff --git a/src/wget.h b/src/wget.h
index 42964411..86fa953d 100644
--- a/src/wget.h
+++ b/src/wget.h
@@ -257,7 +257,8 @@ typedef enum
   FTPINVPASV, FTPNOPASV,
   RETRFINISHED, READERR, TRYLIMEXC, URLBADPATTERN,
   FILEBADFILE, RANGEERR, RETRBADPATTERN, RETNOTSUP,
-  ROBOTSOK, NOROBOTS, PROXERR, AUTHFAILED, QUOTEXC, WRITEFAILED
+  ROBOTSOK, NOROBOTS, PROXERR, AUTHFAILED, QUOTEXC, WRITEFAILED,
+  SSLERRCERTFILE,SSLERRCERTKEY,SSLERRCTXCREATE
 } uerr_t;
 
 typedef unsigned char  boolean;