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 */