SSL options fix

Hrvoje Niksic <[email protected]>
Newsgroups gmane.comp.web.wget.patches
Message-ID <[email protected]>
This patch provides several more SSL option fixes, such as the ability
to specify key type in parallel to the certificate type.

Documentation coming in a separate patch.

2005-04-27  Hrvoje Niksic  <[email protected]>

	* openssl.c (ssl_init): Ditto.

	* options.h (struct options): Allow separate specification of key
	type and certificate type.

	* init.c (cmd_spec_cert_type): Provide a "der" synonym for "asn1"
	certificate encoding.

Index: src/http.c
===================================================================
RCS file: /pack/anoncvs/wget/src/http.c,v
retrieving revision 1.167
diff -u -r1.167 http.c
--- src/http.c	2005/04/26 21:41:38	1.167
+++ src/http.c	2005/04/27 17:12:03
@@ -1203,8 +1203,8 @@
 	  break;
 	case SSLERRCERTKEY:
 	  logprintf (LOG_NOTQUIET,
-		     _("Failed to get certificate key from %s\n"),
-		     opt.cert_key);
+		     _("Failed to get private key from %s\n"),
+		     opt.private_key);
 	  logprintf (LOG_NOTQUIET,
 		     _("Trying without the specified certificate\n"));
 	  break;
Index: src/init.c
===================================================================
RCS file: /pack/anoncvs/wget/src/init.c,v
retrieving revision 1.104
diff -u -r1.104 init.c
--- src/init.c	2005/04/26 21:10:24	1.104
+++ src/init.c	2005/04/27 17:12:10
@@ -74,6 +74,9 @@
 CMD_DECLARE (cmd_boolean);
 CMD_DECLARE (cmd_bytes);
 CMD_DECLARE (cmd_bytes_large);
+#ifdef HAVE_SSL
+CMD_DECLARE (cmd_cert_type);
+#endif
 CMD_DECLARE (cmd_directory_vector);
 CMD_DECLARE (cmd_lockable_boolean);
 CMD_DECLARE (cmd_number);
@@ -84,9 +87,6 @@
 CMD_DECLARE (cmd_time);
 CMD_DECLARE (cmd_vector);
 
-#ifdef HAVE_SSL
-CMD_DECLARE (cmd_spec_cert_type);
-#endif
 CMD_DECLARE (cmd_spec_dirstruct);
 CMD_DECLARE (cmd_spec_header);
 CMD_DECLARE (cmd_spec_htmlify);
@@ -128,8 +128,7 @@
 #ifdef HAVE_SSL
   { "cadirectory",	&opt.ca_directory,	cmd_directory },
   { "certificate",	&opt.cert_file,		cmd_file },
-  { "certificatekey",	&opt.cert_key,		cmd_file },
-  { "certificatetype",	&opt.cert_type,		cmd_spec_cert_type },
+  { "certificatetype",	&opt.cert_type,		cmd_cert_type },
   { "checkcertificate", &opt.check_cert,	cmd_boolean },
 #endif
   { "connecttimeout",	&opt.connect_timeout,	cmd_time },
@@ -196,6 +195,8 @@
   { "postfile",		&opt.post_file_name,	cmd_file },
   { "preferfamily",	NULL,			cmd_spec_prefer_family },
   { "preservepermissions", &opt.preserve_perm,	cmd_boolean },
+  { "privatekey",	&opt.private_key,	cmd_file },
+  { "privatekeytype",	&opt.private_key_type,	cmd_cert_type },
   { "progress",		&opt.progress_type,	cmd_spec_progress },
   { "protocoldirectories", &opt.protocol_directories, cmd_boolean },
   { "proxypasswd",	&opt.proxy_passwd,	cmd_string },
@@ -616,6 +617,16 @@
 
 /* Generic helper functions, for use with `commands'. */
 
+/* Forward declarations: */
+struct decode_item {
+  const char *name;
+  int code;
+};
+static int decode_string PARAMS ((const char *, const struct decode_item *,
+				  int, int *));
+static int simple_atoi PARAMS ((const char *, const char *, int *));
+static int simple_atof PARAMS ((const char *, const char *, double *));
+
 #define CMP1(p, c0) (TOLOWER((p)[0]) == (c0) && (p)[1] == '\0')
 
 #define CMP2(p, c0, c1) (TOLOWER((p)[0]) == (c0)	\
@@ -696,8 +707,6 @@
   return 1;
 }
 
-static int simple_atoi PARAMS ((const char *, const char *, int *));
-
 /* Set the non-negative integer value from VAL to PLACE.  With
    incorrect specification, the number remains unchanged.  */
 static int
@@ -860,8 +869,6 @@
   return 1;
 }
 
-static int simple_atof PARAMS ((const char *, const char *, double *));
-
 /* Engine for cmd_bytes and cmd_bytes_large: converts a string such as
    "100k" or "2.5G" to a floating point number.  */
 
@@ -1025,26 +1032,15 @@
   *(double *)place = number * mult;
   return 1;
 }
-
-/* Specialized helper functions, used by `commands' to handle some
-   options specially.  */
 
-static int check_user_specified_header PARAMS ((const char *));
-/* Forward decl */
-struct decode_item {
-  const char *name;
-  int code;
-};
-static int decode_string PARAMS ((const char *, const struct decode_item *,
-				  int, int *));
-
 #ifdef HAVE_SSL
 static int
-cmd_spec_cert_type (const char *com, const char *val, void *place)
+cmd_cert_type (const char *com, const char *val, void *place)
 {
   static const struct decode_item choices[] = {
-    { "pem", cert_type_pem },
-    { "asn1", cert_type_asn1 },
+    { "pem", keyfile_pem },
+    { "der", keyfile_asn1 },
+    { "asn1", keyfile_asn1 },
   };
   int ok = decode_string (val, choices, countof (choices), place);
   if (!ok)
@@ -1052,7 +1048,12 @@
   return ok;
 }
 #endif
+
+/* Specialized helper functions, used by `commands' to handle some
+   options specially.  */
 
+static int check_user_specified_header PARAMS ((const char *));
+
 static int
 cmd_spec_dirstruct (const char *com, const char *val, void *place_ignored)
 {
@@ -1455,12 +1456,12 @@
   xfree_null (opt.http_user);
   xfree_null (opt.http_passwd);
   free_vec (opt.user_headers);
-#ifdef HAVE_SSL
-  xfree_null (opt.sslcertkey);
-  xfree_null (opt.sslcertfile);
-#endif /* HAVE_SSL */
+# ifdef HAVE_SSL
+  xfree_null (opt.cert_file);
+  xfree_null (opt.private_key);
+# endif
   xfree_null (opt.bind_address);
   xfree_null (opt.cookies_input);
   xfree_null (opt.cookies_output);
-#endif
+#endif /* DEBUG_MALLOC */
 }
Index: src/main.c
===================================================================
RCS file: /pack/anoncvs/wget/src/main.c,v
retrieving revision 1.129
diff -u -r1.129 main.c
--- src/main.c	2005/04/26 17:24:19	1.129
+++ src/main.c	2005/04/27 17:12:10
@@ -161,7 +161,6 @@
     { IF_SSL ("ca-directory"), 0, OPT_VALUE, "cadirectory", -1 },
     { "cache", 0, OPT_BOOLEAN, "cache", -1 },
     { IF_SSL ("certificate"), 0, OPT_VALUE, "certificate", -1 },
-    { IF_SSL ("certificate-key"), 0, OPT_VALUE, "certificatekey", -1 },
     { IF_SSL ("certificate-type"), 0, OPT_VALUE, "certificatetype", -1 },
     { IF_SSL ("check-certificate"), 0, OPT_BOOLEAN, "checkcertificate", -1 },
     { "clobber", 0, OPT__CLOBBER, NULL, optional_argument },
@@ -222,6 +221,8 @@
     { "post-file", 0, OPT_VALUE, "postfile", -1 },
     { "prefer-family", 0, OPT_VALUE, "preferfamily", -1 },
     { "preserve-permissions", 0, OPT_BOOLEAN, "preservepermissions", -1 },
+    { IF_SSL ("private-key"), 0, OPT_VALUE, "privatekey", -1 },
+    { IF_SSL ("private-key-type"), 0, OPT_VALUE, "privatekeytype", -1 },
     { "progress", 0, OPT_VALUE, "progress", -1 },
     { "protocol-directories", 0, OPT_BOOLEAN, "protocoldirectories", -1 },
     { "proxy", 0, OPT_BOOLEAN, "useproxy", -1 },
@@ -541,9 +542,11 @@
     N_("\
        --certificate=FILE       client certificate file.\n"),
     N_("\
-       --certificate-key=FILE   optional key file for this certificate.\n"),
-    N_("\
        --certificate-type=TYPE  client certificate type, PEM or ASN1.\n"),
+    N_("\
+       --private-key=FILE       private key file.\n"),
+    N_("\
+       --private-key-type=TYPE  private key type, PEM or ASN1.\n"),
     N_("\
        --ca-certificate=FILE    file with the bundle of CA's.\n"),
     N_("\
Index: src/openssl.c
===================================================================
RCS file: /pack/anoncvs/wget/src/openssl.c,v
retrieving revision 1.1
diff -u -r1.1 openssl.c
--- src/openssl.c	2005/04/26 21:41:38	1.1
+++ src/openssl.c	2005/04/27 17:12:10
@@ -154,6 +154,26 @@
     logprintf (LOG_NOTQUIET, "OpenSSL: %s\n", ERR_error_string (curerr, NULL));
 }
 
+/* Convert keyfile type as used by options.h to a type as accepted by
+   SSL_CTX_use_certificate_file and SSL_CTX_use_PrivateKey_file.
+
+   (options.h intentionally doesn't use values from openssl/ssl.h so
+   it doesn't depend specifically on OpenSSL for SSL functionality.)  */
+
+static int
+key_type_to_ssl_type (enum keyfile_type type)
+{
+  switch (type)
+    {
+    case keyfile_pem:
+      return SSL_FILETYPE_PEM;
+    case keyfile_asn1:
+      return SSL_FILETYPE_ASN1;
+    default:
+      abort ();
+    }
+}
+
 /* Creates a SSL Context and sets some defaults for it */
 uerr_t
 ssl_init ()
@@ -191,59 +211,33 @@
     case secure_protocol_tlsv1:
       meth = TLSv1_client_method ();
       break;
+    default:
+      abort ();
     }
-  if (meth == NULL)
-    {
-      ssl_print_errors ();
-      return SSLERRCTXCREATE;
-    }
 
   ssl_ctx = SSL_CTX_new (meth);
-  if (meth == NULL)
-    {
-      ssl_print_errors ();
-      return SSLERRCTXCREATE;
-    }
-
   SSL_CTX_set_default_verify_paths (ssl_ctx);
   SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory);
   SSL_CTX_set_verify (ssl_ctx,
 		      opt.check_cert ? SSL_VERIFY_PEER : SSL_VERIFY_NONE,
 		      verify_callback);
 
-  if (opt.cert_file != NULL || opt.cert_key != NULL)
-    {
-      int ssl_cert_type = SSL_FILETYPE_PEM;
-      switch (opt.cert_type)
-	{
-	case cert_type_pem:
-	  ssl_cert_type = SSL_FILETYPE_PEM;
-	  break;
-	case cert_type_asn1:
-	  ssl_cert_type = SSL_FILETYPE_ASN1;
-	  break;
-	}
-
-#if 0 /* what was this supposed to achieve? */
-      if (opt.cert_key == NULL) 
-	opt.cert_key = opt.cert_file;
-      if (opt.cert_file == NULL)
-	opt.cert_file = opt.cert_key;
-#endif
-
-      if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
-					ssl_cert_type) != 1)
-	{
-	  ssl_print_errors ();
-  	  return SSLERRCERTFILE;
-	}
-      if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.cert_key,
-				       ssl_cert_type) != 1)
-	{
-	  ssl_print_errors ();
-	  return SSLERRCERTKEY;
-	}
-    }
+  if (opt.cert_file)
+    if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
+				      key_type_to_ssl_type (opt.cert_type))
+	!= 1)
+      {
+	ssl_print_errors ();
+	return SSLERRCERTFILE;
+      }
+  if (opt.private_key)
+    if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key,
+				     key_type_to_ssl_type (opt.private_key_type))
+	!= 1)
+      {
+	ssl_print_errors ();
+	return SSLERRCERTKEY;
+      }
 
   return 0; /* Succeded */
 }
Index: src/options.h
===================================================================
RCS file: /pack/anoncvs/wget/src/options.h,v
retrieving revision 1.49
diff -u -r1.49 options.h
--- src/options.h	2005/04/26 17:22:56	1.49
+++ src/options.h	2005/04/27 17:12:10
@@ -167,13 +167,13 @@
   } secure_protocol;		/* type of secure protocol to use. */
   int check_cert;		/* whether to validate the server's cert */
   char *cert_file;		/* external client certificate to use. */
-  char *cert_key;		/* the keyfile for this certificate
-				   (if not internal) included in the
-				   certfile. */
-  enum {
-    cert_type_pem,
-    cert_type_asn1
-  } cert_type;			/* type of client certificate */
+  char *private_key;		/* private key file (if not internal). */
+  enum keyfile_type {
+    keyfile_pem,
+    keyfile_asn1
+  } cert_type;			/* type of client certificate file */
+  enum keyfile_type
+    private_key_type;		/* type of private key file */
 
   char *ca_directory;		/* CA directory (hash files) */
   char *ca_cert;		/* CA certificate file to use */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.