From d6f18b52e535c69df5255408015a88b2ff1b7ed7 Mon Sep 17 00:00:00 2001 From: "Steffen (Daode) Nurpmeso" Date: Wed, 30 Aug 2017 22:04:59 +0200 Subject: [PATCH] Add more support surrounding OpenSSL config stuff++.. Some tweaks for OpenSSL: . Instead of adding more and more specific variable( chain)(s) introduce a new *ssl-config-pairs* chain that offers direct interaction with SSL_CONF_cmd(3) if that is available, therefore offering access to _all_ possible commands of said command, but otherwise the well-known directives are supported via a builtin parser. Obsolete all variables superseded by this new mechanism: ssl-cert, ssl-cipher-list, ssl-curves, ssl-key, ssl-protocol, as well as ssl-method which was superseded by ssl-protocol already. . Support SSL_CTX_config(3). The new *ssl-config-module* can now be used to outsource the entire SSL/TLS configuration to a central configuration file. *ssl-config-file* is now filename transformed if it is set to anything but an empty string. . Support more variable chains: *ssl-ca-dir*, *ssl-ca-file*, *ssl-ca-flags*, *ssl-ca-no-defaults* are now all chains. . Add a new read-only *ssl-features* variable which announces availability of several options to the user. --- make-config.sh | 115 ++++++--- nail.1 | 494 +++++++++++++++++++++++++-------------- nail.h | 21 +- xssl.c | 720 +++++++++++++++++++++++++++++++++++++-------------------- 4 files changed, 882 insertions(+), 468 deletions(-) diff --git a/make-config.sh b/make-config.sh index 6276fdc7..f5ee32a4 100644 --- a/make-config.sh +++ b/make-config.sh @@ -2144,6 +2144,7 @@ int main(void){ } ! +VAL_SSL_FEATURES= if feat_yes SSL; then # {{{ # {{{ LibreSSL decided to define OPENSSL_VERSION_NUMBER with a useless value # instead of keeping it at the one that corresponds to the OpenSSL at fork @@ -2161,6 +2162,7 @@ if feat_yes SSL; then # {{{ ! then ossl_v1_1= + VAL_SSL_FEATURES=libressl # TODO OPENSSL_IS_BORINGSSL, but never tried that one! elif compile_check _xssl 'TLS/SSL (OpenSSL >= v1.1.0)' \ '#define HAVE_SSL @@ -2174,6 +2176,7 @@ if feat_yes SSL; then # {{{ ! then ossl_v1_1=1 + VAL_SSL_FEATURES=libssl-0x10100 elif compile_check _xssl 'TLS/SSL (OpenSSL)' \ '#define HAVE_SSL #define HAVE_XSSL @@ -2186,16 +2189,17 @@ if feat_yes SSL; then # {{{ ! then ossl_v1_1= + VAL_SSL_FEATURES=libssl-0x10000 else feat_bail_required SSL fi # }}} if feat_yes SSL; then # {{{ if [ -n "${ossl_v1_1}" ]; then - without_check yes xssl 'TLS/SSL (new style *_client_method(3ssl))' \ + without_check yes xssl 'TLS/SSL new style TLS_client_method(3ssl)' \ '#define n_XSSL_CLIENT_METHOD TLS_client_method' \ '-lssl -lcrypto' - elif link_check xssl 'TLS/SSL (new style *_client_method(3ssl))' \ + elif link_check xssl 'TLS/SSL new style TLS_client_method(3ssl)' \ '#define n_XSSL_CLIENT_METHOD TLS_client_method' \ '-lssl -lcrypto' << \! #include @@ -2216,7 +2220,7 @@ int main(void){ ! then : - elif link_check xssl 'TLS/SSL (old style *_client_method(3ssl))' \ + elif link_check xssl 'TLS/SSL old style SSLv23_client_method(3ssl)' \ '#define n_XSSL_CLIENT_METHOD SSLv23_client_method' \ '-lssl -lcrypto' << \! #include @@ -2244,6 +2248,31 @@ int main(void){ fi # }}} if feat_yes SSL; then # {{{ + if feat_yes SSL_ALL_ALGORITHMS; then + if [ -n "${ossl_v1_1}" ]; then + without_check yes ssl_all_algo 'TLS/SSL all-algorithms support' \ + '#define HAVE_SSL_ALL_ALGORITHMS' + elif link_check ssl_all_algo 'TLS/SSL all-algorithms support' \ + '#define HAVE_SSL_ALL_ALGORITHMS' << \! +#include +int main(void){ + OpenSSL_add_all_algorithms(); + EVP_get_cipherbyname("two cents i never exist"); + EVP_cleanup(); + return 0; +} +! + then + : + else + feat_bail_required SSL_ALL_ALGORITHMS + fi + elif [ -n "${ossl_v1_1}" ]; then + without_check yes ssl_all_algo \ + 'TLS/SSL all-algorithms (always available in v1.1.0+)' \ + '#define HAVE_SSL_ALL_ALGORITHMS' + fi + if [ -n "${ossl_v1_1}" ]; then without_check yes xssl_stack_of 'TLS/SSL STACK_OF()' \ '#define HAVE_XSSL_STACK_OF' @@ -2267,9 +2296,11 @@ int main(void){ fi if [ -n "${ossl_v1_1}" ]; then - without_check yes xssl_conf 'TLS/SSL OpenSSL_modules_load_file()' \ + without_check yes xssl_conf 'TLS/SSL OpenSSL_modules_load_file(3ssl)' \ '#define HAVE_XSSL_CONFIG' - elif link_check xssl_conf 'TLS/SSL OpenSSL_modules_load_file() support' \ + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},+modules-load-file" + elif link_check xssl_conf \ + 'TLS/SSL OpenSSL_modules_load_file(3ssl) support' \ '#define HAVE_XSSL_CONFIG' << \! #include /* For C89 NULL */ #include @@ -2280,12 +2311,15 @@ int main(void){ } ! then - : + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},+modules-load-file" + else + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},-modules-load-file" fi if [ -n "${ossl_v1_1}" ]; then without_check yes xssl_conf_ctx 'TLS/SSL SSL_CONF_CTX support' \ '#define HAVE_XSSL_CONF_CTX' + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},+conf-ctx" elif link_check xssl_conf_ctx 'TLS/SSL SSL_CONF_CTX support' \ '#define HAVE_XSSL_CONF_CTX' << \! #include @@ -2306,42 +2340,64 @@ int main(void){ } ! then - : + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},+conf-ctx" + else + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},-conf-ctx" fi if [ -n "${ossl_v1_1}" ]; then - without_check no xssl_rand_egd 'TLS/SSL RAND_egd(3ssl)' \ - '#define HAVE_XSSL_RAND_EGD' - elif link_check xssl_rand_egd 'TLS/SSL RAND_egd(3ssl)' \ - '#define HAVE_XSSL_RAND_EGD' << \! -#include + without_check yes xssl_ctx_config 'TLS/SSL SSL_CTX_config(3ssl)' \ + '#define HAVE_XSSL_CTX_CONFIG' + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},+ctx-config" + elif [ -n "${have_xssl_conf}" ] && [ -n "${have_xssl_conf_ctx}" ] && + link_check xssl_ctx_config 'TLS/SSL SSL_CTX_config(3ssl)' \ + '#define HAVE_XSSL_CTX_CONFIG' << \! +#include /* For C89 NULL */ +#include int main(void){ - return RAND_egd("some.where") > 0; + SSL_CTX_config(NULL, "SOMEVAL"); + return 0; } ! then - : + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},+ctx-config" + else + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},-ctx-config" fi - if feat_yes SSL_ALL_ALGORITHMS; then - if [ -n "${ossl_v1_1}" ]; then - without_check yes ssl_all_algo 'TLS/SSL all-algorithms support' \ - '#define HAVE_SSL_ALL_ALGORITHMS' - elif link_check ssl_all_algo 'TLS/SSL all-algorithms support' \ - '#define HAVE_SSL_ALL_ALGORITHMS' << \! -#include + if [ -n "${ossl_v1_1}" ] && [ -n "${have_xssl_conf_ctx}" ]; then + without_check yes xssl_set_maxmin_proto \ + 'TLS/SSL SSL_CTX_set_min_proto_version(3ssl)' \ + '#define HAVE_XSSL_SET_MIN_PROTO_VERSION' + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},+ctx-set-maxmin-proto" + elif link_check xssl_set_maxmin_proto \ + 'TLS/SSL SSL_CTX_set_min_proto_version(3ssl)' \ + '#define HAVE_XSSL_SET_MIN_PROTO_VERSION' << \! +#include /* For C89 NULL */ +#include int main(void){ - OpenSSL_add_all_algorithms(); - EVP_get_cipherbyname("two cents i never exist"); - EVP_cleanup(); + SSL_CTX_set_min_proto_version(NULL, 0); + SSL_CTX_set_max_proto_version(NULL, 10); return 0; } ! - then - : - else - feat_bail_required SSL_ALL_ALGORITHMS - fi + then + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},+ctx-set-maxmin-proto" + else + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},-ctx-set-maxmin-proto" + fi + + if link_check xssl_rand_egd 'TLS/SSL RAND_egd(3ssl)' \ + '#define HAVE_XSSL_RAND_EGD' << \! +#include +int main(void){ + return RAND_egd("some.where") > 0; +} +! + then + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},+rand-egd" + else + VAL_SSL_FEATURES="${VAL_SSL_FEATURES},-rand-egd" fi fi # feat_yes SSL }}} @@ -2376,6 +2432,7 @@ int main(void){ else echo '/* OPT_SSL=0 */' >> ${h} fi # }}} feat_yes SSL +printf '#define VAL_SSL_FEATURES "#'"${VAL_SSL_FEATURES}"'"\n' >> ${h} if [ "${have_xssl}" = yes ]; then OPT_SMIME=1 diff --git a/nail.1 b/nail.1 index 7619bcf4..f194a4c3 100644 --- a/nail.1 +++ b/nail.1 @@ -1816,7 +1816,7 @@ contains complete example configurations. SSL (Secure Sockets Layer) a.k.a. its successor TLS (Transport Layer Security) are protocols which aid in securing communication by providing a safely initiated and encrypted network connection. -A central concept to SSL/TLS is that of certificates: as part of each +A central concept of SSL/TLS is that of certificates: as part of each network connection setup a (set of) certificates will be exchanged, and by using those the identity of the network peer can be cryptographically verified. @@ -1827,9 +1827,9 @@ the trusted local pool. . .Pp The local pool of trusted so-called CA (Certification Authority) -certificates is usually delivered with the used SSL/TLS library (e.g., -OpenSSL), and will be selected automatically. -It is also possible to create and use an own pool of trusted certificates. +certificates is usually delivered with the used SSL/TLS library, and +will be selected automatically, but it is also possible to create and +use an own pool of trusted certificates. If this is desired, set .Va ssl-ca-no-defaults to avoid using the default certificate pool, and point @@ -1846,10 +1846,8 @@ possible, and which configuration steps have to be taken to enable it. Some protocols, e.g., POP3S, are implicitly encrypted, others, like POP3, can upgrade a plain text connection if so requested: POP3 offers .Ql STLS , -which will be used if the variable +which will be used if the variable (chain) .Va pop3-use-starttls -(which is a variable chain, as documented in -.Sx "On URL syntax and credential lookup") is set: . .Bd -literal -offset indent @@ -1863,28 +1861,28 @@ set mta=smtp://smtp.exam.ple smtp-use-starttls .Ed . .Pp -Normally that is all there is to do, however plenty of knobs exist to -adjust settings shall the necessity or desire arise. -E.g., it is possible to fine-tune certificate verification via -.Va ssl-ca-flags . -Also interesting may be the possibility to configure the allowed -.Va ssl-protocol Ns -s that a communication channel may use: whereas in the past hints of -how to restrict the set of protocols to highly secure ones were -indicated, as of the time of this writing the allowed protocols, or at -least the allowed -.Va ssl-cipher-list , -may need to become relaxed in order to be able to connect to some -servers. -E.g., the following example settings allows connection of a +Normally that is all there is to do, given that SSL/TLS libraries try to +provide safe defaults, plenty of knobs however exist to adjust settings. +For example certificate verification settings can be fine-tuned via +.Va ssl-ca-flags , +and the SSL/TLS configuration basics are accessible via +.Va ssl-config-pairs , +e.g., to specify the allowed protocols or cipher lists that +a communication channel may use. +In the past hints of how to restrict the set of protocols to highly +secure ones were indicated, as of the time of this writing the allowed +protocols or cipher list may need to become relaxed in order to be able +to connect to some servers; the following example allows connecting to a .Dq Lion -which uses OpenSSL 0.9.8za from June 2014: +that uses OpenSSL 0.9.8za from June 2014 (refer to +.Sx "INTERNAL VARIABLES" +for more on variable chains): . .Bd -literal -offset indent -set ssl-protocol-LION=ALL,-SSLv3,-TLSv1 -set ssl-cipher-list-LION=TLSv1.2:!aNULL:!eNULL:\e - ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:\e - DHE-RSA-AES256-SHA:@STRENGTH +wysh set ssl-config-pairs-lion@exam.ple='MinProtocol=TLSv1.1,\e + CipherList=TLSv1.2:!aNULL:!eNULL:\e + ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:\e + DHE-RSA-AES256-SHA:@STRENGTH' .Ed . .Pp @@ -1896,14 +1894,11 @@ Variables of interest for SSL/TLS in general are .Va ssl-ca-file , .Va ssl-ca-flags , .Va ssl-ca-no-defaults , -.Va ssl-cert , -.Va ssl-cipher-list , .Va ssl-config-file , -.Va ssl-curves , +.Va ssl-config-module , +.Va ssl-config-pairs .Va ssl-crl-dir , .Va ssl-crl-file , -.Va ssl-key , -.Va ssl-protocol , .Va ssl-rand-file as well as .Va ssl-verify . @@ -8654,9 +8649,9 @@ or . .Mx .It Va features -\*(RO String giving a list of features \*(UA, preceded with a plus sign +\*(RO String giving a list of optional features, preceded with a plus sign .Ql + -if the feature is available, and a hyphen-minus +if it is available, and a hyphen-minus .Ql - otherwise. The output of the command @@ -11116,9 +11111,10 @@ Then the latter is used to parse the first output line of the hook, and, in case the evaluation is successful, the group that has been specified via the number is interpreted as a floating point scan score. . -.Mx -.Mx -.It Va ssl-ca-dir , ssl-ca-file +.Mx Va ssl-ca-dir +.Mx Va ssl-ca-file +.It Va ssl-ca-dir-USER@HOST , ssl-ca-dir-HOST , ssl-ca-dir ,\ + ssl-ca-file-USER@HOST , ssl-ca-file-HOST , ssl-ca-file \*(OP Specify the location of trusted CA certificates in PEM (Privacy Enhanced Mail) format as a directory and a file, respectively, for the purpose of verification of SSL/TLS server certificates. @@ -11136,8 +11132,8 @@ for more information. establishing TLS connections to servers identified with hostnames. . . -.Mx -.It Va ssl-ca-flags +.Mx Va ssl-ca-flags +.It Va ssl-ca-flags-USER@HOST , ssl-ca-flags-HOST , ssl-ca-flags \*(OP Can be used to fine-tune behaviour of the X509 CA certificate storage, and the certificate verification that is used (also see .Va ssl-verify ) . @@ -11183,64 +11179,222 @@ it by default, resulting in the same behaviour; also see .El . . -.Mx -.It Va ssl-ca-no-defaults +.Mx Va ssl-ca-no-defaults +.It Va ssl-ca-no-defaults-USER@HOST , ssl-ca-no-defaults-HOST ,\ + ssl-ca-no-defaults \*(BO\*(OP Do not load the default CA locations that are built into the used to SSL/TLS library to verify SSL/TLS server certificates. . .Mx Va ssl-cert .It Va ssl-cert-USER@HOST , ssl-cert-HOST , ssl-cert -\*(OP Variable chain that sets the filename for a SSL/TLS client -certificate required by some servers. -This is a direct interface to the -.Ql Certificate -slot of the -.Xr SSL_CONF_cmd 3 -function of the OpenSSL library, if available. +\*(OB\*(OP Please use the +.Cd Certificate +slot of +.Va ssl-config-pairs . . .Mx Va ssl-cipher-list .It Va ssl-cipher-list-USER@HOST , ssl-cipher-list-HOST , ssl-cipher-list -\*(OP Specifies a list of ciphers for SSL/TLS connections. -This is a direct interface to the -.Ql CipherString -slot of the -.Xr SSL_CONF_cmd 3 -function of the OpenSSL library, if available; see -.Xr ciphers 1 -and -.Xr SSL_CTX_set_cipher_list 3 -for more information. -By default \*(UA does not set a list of ciphers, in effect using a -.Va ssl-protocol -specific cipher (protocol standards ship with a list of acceptable -ciphers), possibly cramped to what the actually used SSL/TLS library -supports \(en the manual section -.Sx "An example configuration" -also contains a SSL/TLS use case. +\*(OB\*(OP Please use the +.Cd CipherList +slot of +.Va ssl-config-pairs . . .Mx .It Va ssl-config-file -\*(OP If this variable is set \*(UA will call +\*(OP If this variable is set .Xr CONF_modules_load_file 3 -to allow OpenSSL to be configured according to the host system wide -security settings. -If a non-empty value is given then this will be used to specify the -configuration file to be used instead of the global OpenSSL default; -note that in this case it is an error if the file cannot be loaded. +(if announced via +.Ql +modules-load-file +in +.Va ssl-features ) +is used to allow resource file based configuration of the SSL/TLS library. +This happens once the library is used first, which may also be early +during startup (logged with +.Va verbose ) ! +If a non-empty value is given then the given file, after performing +.Sx "Filename transformations" , +will be used instead of the global OpenSSL default, and it is an error +if the file cannot be loaded. The application name will always be passed as -.Dq \*(uA . +.Ql \*(uA . +Some SSL/TLS libraries support application-specific configuration via +resource files loaded like this, please see +.Va ssl-config-module . +. +.Mx Va ssl-config-module +.It Va ssl-config-module-USER@HOST , ssl-config-module-HOST ,\ + ssl-config-module +\*(OP If file based application-specific configuration via +.Va ssl-config-file +is available, announced as +.Ql +ctx-config +by +.Va ssl-features , +indicating availability of +.Xr SSL_CTX_config 3 , +then, it becomes possible to use a central SSL/TLS configuration file +for all programs, including \*(uA, e.g.: +.Bd -literal -offset indent +# Register a configuration section for \*(uA +\*(uA = mailx_master +# The top configuration section creates a relation +# in between dynamic SSL configuration and an actual +# program specific configuration section +[mailx_master] +ssl_conf = mailx_ssl_config +# Well that actual program specific configuration section +# now can map individual ssl-config-module names to sections, +# e.g., ssl-config-module=account_xy +[mailx_ssl_config] +account_xy = mailx_account_xy +account_yz = mailx_account_yz +[mailx_account_xy] +MinProtocol = TLSv1.2 +Curves=P-521 +[mailx_account_yz] +CipherString = TLSv1.2:!aNULL:!eNULL: +MinProtocol = TLSv1.1 +Options = Bugs +.Ed +. +. +.Mx Va ssl-config-pairs +.It Va ssl-config-pairs-USER@HOST , ssl-config-pairs-HOST , ssl-config-pairs +\*(OP The value of this variable chain will be interpreted as +a comma-separated list of directive/value pairs. +Different to when placing these pairs in a +.Va ssl-config-module +section of a +.Va ssl-config-file +commas +.Ql \&, +need to be escaped with a reverse solidus +.Ql \e +when included in pairs. +Just likewise directives and values need to be separated by equals signs +.Ql = , +any whitespace surrounding pair members is removed. +Keys are (usually) case-insensitive. +Unless proper support is announced by +.Va ssl-features +.Pf ( Ql +conf-ctx ) +only the keys below are supported, otherwise the pairs will be used +directly as arguments to the function +.Xr SSL_CONF_cmd 3 . +Said equals sign +.Ql = +may be preceded with an asterisk +.Ql * +to indicate that +.Sx "Filename transformations" +shall be performed on the value; it is an error if these fail. +. +.Pp +.Bl -tag -compact -width ".It Cd C_rtificate" +.It Cd Certificate +Filename of a SSL/TLS client certificate (chain) required by some servers. +Fallback support via +.Xr SSL_CTX_use_certificate_chain_file 3 . +.Sx "Filename transformations" +are performed. +.\" v15compat: remove the next sentence +.Sy Note: +if you use this you need to specify the private key via +.Cd PrivateKey , +.Va ssl-key +will not be used! +. +.It Cd CipherList +A list of ciphers for SSL/TLS connections, see +.Xr ciphers 1 . +By default no list of ciphers is set, resulting in a +.Cd Protocol Ns - Ns +specific list of ciphers (the protocol standards define lists of +acceptable ciphers; possibly cramped by the used SSL/TLS library). +Fallback support via +.Xr SSL_CTX_set_cipher_list 3 . +. +.It Cd Curves +A list of supported elliptic curves, if applicable. +By default no curves are set. +Fallback support via +.Xr SSL_CTX_set1_curves_list 3 , +if available. +. +.It Cd MaxProtocol , MinProtocol +The maximum and minimum supported SSL/TLS versions, respectively. +Optional fallback support via +.Xr SSL_CTX_set_max_proto_version 3 +and +.Xr SSL_CTX_set_min_proto_version 3 +if +.Va ssl-features +announces +.Ql +ctx-set-maxmin-proto , +otherwise this directive results in an error. +The fallback uses an internal parser which understands the strings +.Ql SSLv3 , +.Ql TLSv1 , +.Ql TLSv1.1 , +.Ql TLSv1.2 , +and the special value +.Ql None , +which disables the given limit. +. +.It Cd Options +Various flags to set. +Fallback via +.Xr SSL_CTX_set_options 3 , +in which case any other value but (exactly) +.Ql Bugs +results in an error. +. +.It Cd PrivateKey +Filename of the private key in PEM format of a SSL/TLS client certificate. +If unset, the name of the certificate file is used. +.Sx "Filename transformations" +are performed. +Fallback via +.Xr SSL_CTX_use_PrivateKey_file 3 . +.\" v15compat: remove the next sentence +.Sy Note: +if you use this you need to specify the certificate (chain) via +.Cd Certificate , +.Va ssl-cert +will not be used! +. +.It Cd Protocol +The used SSL/TLS protocol. +If +.Va ssl-features +announces +.Ql +conf-ctx +or +.Ql ctx-set-maxmin-proto +then using +.Cd MaxProtocol +and +.Cd MinProtocol +is preferable. +Fallback is +.Xr SSL_CTX_set_options 3 , +driven via an internal parser which understands the strings +.Ql SSLv3 , +.Ql TLSv1 , +.Ql TLSv1.1 , +.Ql TLSv1.2 , +and the special value +.Ql ALL . +Multiple protocols may be given as a comma-separated list, any +whitespace is ignored, an optional plus sign +.Ql + +prefix enables, a hyphen-minus +.Ql - +prefix disables a protocol, so that +.Ql -ALL, TLSv1.2 +enables only the TLSv1.2 protocol. +.El . -.Mx Va ssl-curves -.It Va ssl-curves-USER@HOST , ssl-curves-HOST , ssl-curves -\*(OP Specifies a list of supported curves for SSL/TLS connections. -This is a direct interface to the -.Ql Curves -slot of the -.Xr SSL_CONF_cmd 3 -function of the OpenSSL library, if available; see -.Xr SSL_CTX_set1_curves_list 3 -for more information. -By default \*(UA does not set a list of curves. . .Mx .Mx @@ -11248,85 +11402,70 @@ By default \*(UA does not set a list of curves. \*(OP Specify a directory / a file, respectively that contains a CRL in PEM format to use when verifying SSL/TLS server certificates. . +.Mx Va ssl-curves +.It Va ssl-curves-USER@HOST , ssl-curves-HOST , ssl-curves +\*(OB\*(OP Please use the +.Cd Curves +slot of +.Va ssl-config-pairs . +. +.Mx +.It Va ssl-features +\*(OP\*(RO This expands to a comma separated list of the TLS/SSL library +identity and optional TLS/SSL library features. +Currently supported identities are +.Ql libressl +(LibreSSL) , +.Ql libssl-0x10100 +(OpenSSL v1.1.x series) +and +.Ql libssl-0x10000 +(elder OpenSSL series, other clones). +Optional features are preceded with a plus sign +.Ql + +when available, and with a hyphen-minus +.Ql - +otherwise: +.Ql modules-load-file +.Pf ( Va ssl-config-file ) , +.Ql conf-ctx +.Pf ( Va ssl-config-pairs ) , +.Ql ctx-config +.Pf ( Va ssl-config-module ) , +.Ql ctx-set-maxmin-proto +.Pf ( Va ssl-config-pairs ) +and +.Ql rand-egd +.Pf ( Va ssl-rand-egd ) . +. .Mx Va ssl-key .It Va ssl-key-USER@HOST , ssl-key-HOST , ssl-key -\*(OP Variable chain that sets the filename for the private key of -a SSL/TLS client certificate. -If unset, the name of the certificate file is used. -The file is expected to be in PEM format. -This is a direct interface to the -.Ql PrivateKey -slot of the -.Xr SSL_CONF_cmd 3 -function of the OpenSSL library, if available. +\*(OB\*(OP Please use the +.Cd PrivateKey +slot of +.Va ssl-config-pairs . . .It Va ssl-method-USER@HOST , ssl-method-HOST , ssl-method -\*(OB\*(OP Please use the newer and more flexible -.Va ssl-protocol -instead: if both values are set, -.Va ssl-protocol -will take precedence! -Can be set to the following values, the actually used -.Va ssl-protocol -specification to which it is mapped is shown in parenthesis: -.Ql tls1.2 -.Pf ( Ql -ALL, TLSv1.2 ) , -.Ql tls1.1 -.Pf ( Ql -ALL, TLSv1.1 ) , -.Ql tls1 -.Pf ( Ql -ALL, TLSv1 ) -and -.Ql ssl3 -.Pf ( Ql -ALL, SSLv3 ) ; -the special value -.Ql auto -is mapped to -.Ql ALL, -SSLv2 -and thus includes the SSLv3 protocol. -Note that SSLv2 is no longer supported at all. +\*(OB\*(OP Please use the +.Cd Protocol +slot of +.Va ssl-config-pairs . . .Mx Va ssl-protocol .It Va ssl-protocol-USER@HOST , ssl-protocol-HOST , ssl-protocol -\*(OP Specify the used SSL/TLS protocol. -This is a direct interface to the -.Ql Protocol -slot of the -.Xr SSL_CONF_cmd 3 -function of the OpenSSL library, if available; -otherwise an \*(UA internal parser is used which understands the -following subset of (case-insensitive) command strings: -.Ql SSLv3 , -.Ql TLSv1 , -.Ql TLSv1.1 -and -.Ql TLSv1.2 , -as well as the special value -.Ql ALL . -Multiple specifications may be given via a comma-separated list which -ignores any whitespace. -An optional -.Ql + -plus sign prefix will enable a protocol, a -.Ql - -hyphen-minus prefix will disable it, so that -.Ql -ALL, TLSv1.2 -will enable only the TLSv1.2 protocol. -.Pp -It depends upon the used TLS/SSL library which protocols are actually -supported and which protocols are used if -.Va ssl-protocol -is not set, but note that SSLv2 is no longer supported at all and -actively disabled. -Especially for older protocols explicitly securing -.Va ssl-cipher-list -may be worthwile, see -.Sx "An example configuration" . +\*(OB\*(OP Please use the +.Cd Protocol +slot of +.Va ssl-config-pairs . . .Mx .It Va ssl-rand-egd \*(OP Gives the pathname to an entropy daemon socket, see .Xr RAND_egd 3 . -Not all SSL/TLS libraries support this. +Not all SSL/TLS libraries support this, +.Va ssl-features +announces availability with +.Ql +rand-egd . . .Mx .It Va ssl-rand-file @@ -11336,11 +11475,11 @@ If this variable is not set, or set to the empty string, or if the .Sx "Filename transformations" fail, then .Xr RAND_file_name 3 -will be used to create the filename if, and only if, -.Xr RAND_status 3 -documents that the SSL PRNG is not yet sufficiently seeded. -If \*(UA successfully seeded the SSL PRNG then it will update the file -.Pf ( Xr RAND_write_file 3 ) . +will be used to create the filename. +If the SSL PRNG was seeded successfully +The file will be updated +.Pf ( Xr RAND_write_file 3 ) +if and only if seeding and buffer stirring succeeds. This variable is only used if .Va ssl-rand-egd is not set (or not supported by the SSL/TLS library). @@ -12724,10 +12863,10 @@ This is merely for FTP purposes. # This example assumes v15.0 compatibility mode set v15-compat -# Request strict transport security checks! +# Request strict SSL/TLS transport security checks set ssl-verify=strict -# Where are the up-to-date SSL certificates? +# Where are the up-to-date SSL/TLS certificates? # (Since we manage up-to-date ones explicitly, do not use any, # possibly outdated, default certificates shipped with OpenSSL) #set ssl-ca-dir=/etc/ssl/certs @@ -12737,26 +12876,29 @@ set ssl-ca-no-defaults wysh set smime-ca-file="${ssl-ca-file}" \e smime-ca-no-defaults #smime-ca-flags="${ssl-ca-flags}" -# Do not use protocols older than TLS v1.2. -# Change this only when the remote server does not support it: -# maybe use ssl-protocol-HOST (or -USER@HOST) syntax to define -# such explicit exceptions, then, e.g. -# set ssl-protocol-exam.ple='-ALL,+TLSv1.1' -set ssl-protocol='-ALL,+TLSv1.2' - -# Explicitly define the list of ciphers, which may improve security, -# especially with protocols older than TLS v1.2. See ciphers(1). -# Including "@STRENGTH" will sort the final list by algorithm strength. -# In reality it is possibly best to only use ssl-cipher-list-HOST -# (or -USER@HOST), as necessary, again.. -set ssl-cipher-list=TLSv1.2:!aNULL:!eNULL:@STRENGTH - -# - TLSv1.2:!aNULL:!eNULL:\e -# ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:\e -# DHE-RSA-AES256-SHA:@STRENGTH -# -ALL:!aNULL:!eNULL:!MEDIUM:!LOW:!MD5:!RC4:!EXPORT:@STRENGTH -# Especially with TLSv1.3 curves selection may be desired: -#set ssl-curves=P-521:P-384:P-256 +# This could be outsourced to a central configuration file via +# ssl-config-file plus ssl-config-module if the used library allows. +# CipherList: explicitly define the list of ciphers, which may +# improve security, especially with protocols older than TLS v1.2. +# See ciphers(1). Possibly best to only use ssl-cipher-list-HOST +# (or -USER@HOST), as necessary, again.. +# Curves: especially with TLSv1.3 curves selection may be desired. +# MinProtocol,MaxProtocol: do not use protocols older than TLS v1.2. +# Change this only when the remote server does not support it: +# maybe use chain support via ssl-config-pairs-HOST / -USER@HOST +# to define such explicit exceptions, then, e.g. +# MinProtocol=TLSv1.1 +if [ "$ssl-features" =% +ctx-set-maxmin-proto ] + wysh set ssl-config-pairs='\e + CipherList=TLSv1.2:!aNULL:!eNULL:@STRENGTH,\e + Curves=P-521:P-384:P-256,\e + MinProtocol=TLSv1.1' +else + wysh set ssl-config-pairs='\e + CipherList=TLSv1.2:!aNULL:!eNULL:@STRENGTH,\e + Curves=P-521:P-384:P-256,\e + Protocol=-ALL\e,+TLSv1.1 \e, +TLSv1.2' +endif # Essential setting: select allowed character sets set sendcharsets=utf-8,iso-8859-1 diff --git a/nail.h b/nail.h index c9aacf75..f5a2801b 100644 --- a/nail.h +++ b/nail.h @@ -1764,20 +1764,23 @@ ok_v_spamd_user, ok_v_spamfilter_rate, ok_v_spamfilter_rate_scanscore, ok_v_spamfilter_spam, - ok_v_ssl_ca_dir, - ok_v_ssl_ca_file, - ok_v_ssl_ca_flags, - ok_b_ssl_ca_no_defaults, - ok_v_ssl_cert, /* {chain=1} */ - ok_v_ssl_cipher_list, /* {chain=1} */ + ok_v_ssl_ca_dir, /* {chain=1} */ + ok_v_ssl_ca_file, /* {chain=1} */ + ok_v_ssl_ca_flags, /* {chain=1} */ + ok_b_ssl_ca_no_defaults, /* {chain=1} */ +ok_v_ssl_cert, /* {chain=1} */ +ok_v_ssl_cipher_list, /* {chain=1} */ ok_v_ssl_config_file, - ok_v_ssl_curves, /* {chain=1} */ + ok_v_ssl_config_module, /* {chain=1} */ + ok_v_ssl_config_pairs, /* {chain=1} */ +ok_v_ssl_curves, /* {chain=1} */ ok_v_ssl_crl_dir, ok_v_ssl_crl_file, - ok_v_ssl_key, /* {chain=1} */ + ok_v_ssl_features, /* {virt=VAL_SSL_FEATURES} */ +ok_v_ssl_key, /* {chain=1} */ ok_v_ssl_method, /* {chain=1} */ ok_b_ssl_no_default_ca, - ok_v_ssl_protocol, /* {chain=1} */ +ok_v_ssl_protocol, /* {chain=1} */ ok_v_ssl_rand_egd, ok_v_ssl_rand_file, ok_v_ssl_verify, /* {chain=1} */ diff --git a/xssl.c b/xssl.c index dca48546..1f93dcc3 100644 --- a/xssl.c +++ b/xssl.c @@ -1,5 +1,7 @@ /*@ S-nail - a mail user agent derived from Berkeley Mail. - *@ TLS/SSL functions. TODO this needs an overhaul -- there _are_ stack leaks!? + *@ OpenSSL client implementation according to: John Viega, Matt Messier, + *@ Pravir Chandra: Network Security with OpenSSL. Sebastopol, CA 2002. + *@ TODO This needs an overhaul -- there _are_ stack leaks!? * * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany. * Copyright (c) 2012 - 2017 Steffen (Daode) Nurpmeso . @@ -65,14 +67,7 @@ EMPTY_FILE() # include #endif -/* - * OpenSSL client implementation according to: John Viega, Matt Messier, - * Pravir Chandra: Network Security with OpenSSL. Sebastopol, CA 2002. - */ - -/* Update manual on changes (for all those)! */ -#define n_XSSL_DISABLED_PROTOCOLS "-SSLv2" - +/* Compatibility shims which assume 0/-1 cannot really happen */ #ifndef HAVE_XSSL_CONF_CTX # ifndef SSL_OP_NO_SSLv2 # define SSL_OP_NO_SSLv2 0 @@ -89,13 +84,28 @@ EMPTY_FILE() # ifndef SSL_OP_NO_TLSv1_2 # define SSL_OP_NO_TLSv1_2 0 # endif - /* SSL_CONF_CTX and _OP_NO_SSL_MASK were both introduced with 1.0.2!?! */ # ifndef SSL_OP_NO_SSL_MASK # define SSL_OP_NO_SSL_MASK \ (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |\ SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2) # endif + +# ifndef SSL2_VERSION +# define SSL2_VERSION 0 +# endif +# ifndef SSL3_VERSION +# define SSL3_VERSION 0 +# endif +# ifndef TLS1_VERSION +# define TLS1_VERSION 0 +# endif +# ifndef TLS1_1_VERSION +# define TLS1_1_VERSION 0 +# endif +# ifndef TLS1_2_VERSION +# define TLS1_2_VERSION 0 +# endif #endif #ifdef HAVE_XSSL_STACK_OF @@ -165,18 +175,6 @@ enum a_xssl_state{ a_XSSL_S_VERIFY_ERROR = 1u<<16 }; -/* We go for the OpenSSL v1.0.2+ SSL_CONF_CTX if available even if - * the library does internally what we'd otherwise do ourselfs. - * But eventually we can drop the direct use cases */ -enum a_xssl_conf_type{ - a_XSSL_CT_CERTIFICATE, - a_XSSL_CT_CIPHER_STRING, - a_XSSL_CT_CURVES, - a_XSSL_CT_PRIVATE_KEY, - a_XSSL_CT_OPTIONS, - a_XSSL_CT_PROTOCOL -}; - struct ssl_method { /* TODO v15 obsolete */ char const sm_name[8]; char const sm_map[16]; @@ -184,8 +182,12 @@ struct ssl_method { /* TODO v15 obsolete */ #ifndef HAVE_XSSL_CONF_CTX struct a_xssl_protocol{ - char const *sp_name; - sl_i sp_flag; + char const sp_name[8]; + sl_i sp_op_no; /* SSL_OP_NO_* bit */ + ui16_t sp_version; /* *_VERSION number */ + bool_t sp_ok_minmaxproto; /* Valid for {Min,Max}Protocol= */ + bool_t sp_ok_proto; /* Valid for Protocol= */ + ui8_t sp__dummy[4]; }; #endif @@ -205,7 +207,6 @@ struct a_xssl_x509_v_flags{ }; /* Supported SSL/TLS methods: update manual on change! */ - static struct ssl_method const _ssl_methods[] = { /* TODO obsolete */ {"auto", "ALL,-SSLv2"}, {"ssl3", "-ALL,SSLv3"}, @@ -214,17 +215,20 @@ static struct ssl_method const _ssl_methods[] = { /* TODO obsolete */ {"tls1.2", "-ALL,TLSv1.2"} }; -/* Update manual on change! */ +/* Update manual on change! + * Ensure array size by adding \0 to longest entry. + * Strictly to be sorted new/up to old/down, [0]=ALL, [x-1]=None! */ #ifndef HAVE_XSSL_CONF_CTX static struct a_xssl_protocol const a_xssl_protocols[] = { - {"ALL", SSL_OP_NO_SSL_MASK}, - {"TLSv1.2", SSL_OP_NO_TLSv1_2}, - {"TLSv1.1", SSL_OP_NO_TLSv1_1}, - {"TLSv1", SSL_OP_NO_TLSv1}, - {"SSLv3", SSL_OP_NO_SSLv3}, - {"SSLv2", 0} + {"ALL", SSL_OP_NO_SSL_MASK, 0, FAL0, TRU1, {0}}, + {"TLSv1.2\0", SSL_OP_NO_TLSv1_2, TLS1_2_VERSION, TRU1, TRU1, {0}}, + {"TLSv1.1", SSL_OP_NO_TLSv1_1, TLS1_1_VERSION, TRU1, TRU1, {0}}, + {"TLSv1", SSL_OP_NO_TLSv1, TLS1_VERSION, TRU1, TRU1, {0}}, + {"SSLv3", SSL_OP_NO_SSLv3, SSL3_VERSION, TRU1, TRU1, {0}}, + {"SSLv2", SSL_OP_NO_SSLv2, SSL2_VERSION, TRU1, TRU1, {0}}, + {"None", SSL_OP_NO_SSL_MASK, 0, TRU1, FAL0, {0}} }; -#endif +#endif /* HAVE_XSSL_CONF_CTX */ /* Supported S/MIME cipher algorithms */ static struct a_xssl_smime_cipher const a_xssl_smime_ciphers[] = { /* Manual! */ @@ -282,7 +286,9 @@ static struct a_xssl_x509_v_flags const a_xssl_x509_v_flags[] = { /* Manual! */ static enum a_xssl_state a_xssl_state; static size_t a_xssl_msgno; -static bool_t a_xssl_rand_init(void); +static void a_xssl_rand_init(void); +static void a_xssl_init(void); + #if HAVE_XSSL_OPENSSL < 0x10100 # ifdef HAVE_SSL_ALL_ALGORITHMS static void a_xssl__load_algos(void); @@ -304,12 +310,13 @@ static int _ssl_verify_cb(int success, X509_STORE_CTX *store); static void a_xssl_ca_flags(X509_STORE *store, char const *flags); /* SSL_CTX configuration */ -static void * _ssl_conf_setup(SSL_CTX *ctxp); -static bool_t _ssl_conf(void *confp, enum a_xssl_conf_type ct, - char const *value); -static bool_t _ssl_conf_finish(void **confp, bool_t error); +static void * a_xssl_conf_setup(SSL_CTX *ctxp, struct url const *urlp); +static bool_t a_xssl_conf(void *confp, char const *cmd, char const *value); +static bool_t a_xssl_conf_finish(void **confp, bool_t error); -static bool_t _ssl_load_verifications(SSL_CTX *ctxp); +static bool_t a_xssl_obsolete_conf_vars(void *confp, struct url const *urlp); +static bool_t a_xssl_config_pairs(void *confp, struct url const *urlp); +static bool_t a_xssl_load_verifications(SSL_CTX *ctxp, struct url const *urlp); static enum okay ssl_check_host(struct sock *sp, struct url const *urlp); @@ -330,7 +337,7 @@ static enum okay load_crl1(X509_STORE *store, char const *name); #endif static enum okay load_crls(X509_STORE *store, enum okeys fok, enum okeys dok); -static bool_t +static void a_xssl_rand_init(void){ #define a_XSSL_RAND_ENTROPY 32 char b64buf[a_XSSL_RAND_ENTROPY * 5 +1], *randfile; @@ -338,12 +345,18 @@ a_xssl_rand_init(void){ bool_t err; NYD2_ENTER; + a_xssl_state |= a_XSSL_S_RAND_INIT; + err = TRU1; randfile = NULL; - /* Shall use some external daemon? */ /* TODO obsolete *ssl_rand_egd* */ - if((cp = ok_vlook(ssl_rand_egd)) != NULL){ /* TODO no one supports it now! */ - n_OBSOLETE(_("all *SSL libraries removed *ssl-rand-egd* support")); +#ifdef HAVE_XSSL_CONFIG + if(!(a_xssl_state & a_XSSL_S_INIT)) + a_xssl_init(); +#endif + + /* Shall use some external daemon? */ + if((cp = ok_vlook(ssl_rand_egd)) != NULL){ #ifdef HAVE_XSSL_RAND_EGD if((x = fexpand(cp, FEXP_LOCAL | FEXP_NOPROTO)) != NULL && RAND_egd(cp = x) != -1){ @@ -413,44 +426,51 @@ jleave: " On a machine with entropy: " "\"$ dd if=/dev/urandom of=FILE bs=1024 count=1\"\n")); NYD2_LEAVE; - return err; } static void -a_xssl_init(void) -{ +a_xssl_init(void){ #ifdef HAVE_XSSL_CONFIG char const *cp; #endif - NYD_ENTER; + NYD2_ENTER; + + if(a_xssl_state & a_XSSL_S_INIT) + goto jleave; - if(!(a_xssl_state & a_XSSL_S_INIT)){ #if HAVE_XSSL_OPENSSL >= 0x10100 - OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS | - OPENSSL_INIT_LOAD_CRYPTO_STRINGS + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS | + OPENSSL_INIT_LOAD_CRYPTO_STRINGS # ifdef HAVE_SSL_ALL_ALGORITHMS - | OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS + | OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS # endif - , NULL); - -#else /* OPENSSL >= 0x10100 */ - SSL_load_error_strings(); - SSL_library_init(); - a_xssl_load_algos(); + , NULL); +#else + SSL_load_error_strings(); + SSL_library_init(); + a_xssl_load_algos(); #endif - a_xssl_state |= a_XSSL_S_INIT; - } + a_xssl_state |= a_XSSL_S_INIT; + /* Load openssl.cnf or whatever was given in *ssl-config-file* */ #ifdef HAVE_XSSL_CONFIG - if(!(a_xssl_state & a_XSSL_S_CONF_LOAD) && - (cp = ok_vlook(ssl_config_file)) != NULL){ - ul_i flags = CONF_MFLAGS_IGNORE_MISSING_FILE; + if((cp = ok_vlook(ssl_config_file)) != NULL){ + char const *msg; + ul_i flags; if(*cp == '\0'){ + msg = "[default]"; cp = NULL; + flags = CONF_MFLAGS_IGNORE_MISSING_FILE; + }else if((msg = cp, cp = fexpand(cp, FEXP_LOCAL | FEXP_NOPROTO)) != NULL) flags = 0; + else{ + n_err(_("*ssl-config-file*: file expansion failed: %s\n"), + n_shexp_quote_cp(msg, FAL0)); + goto jefile; } + if(CONF_modules_load_file(cp, n_uagent, flags) == 1){ a_xssl_state |= a_XSSL_S_CONF_LOAD; # if HAVE_XSSL_OPENSSL < 0x10100 @@ -459,14 +479,19 @@ a_xssl_init(void) atexit(&a_xssl_atexit); /* TODO generic program-wide event mech. */ } # endif + if(n_poption & n_PO_D_V) + n_err(_("Loaded SSL/TLS configuration for %s from %s\n"), n_uagent, + n_shexp_quote_cp(msg, FAL0)); +jefile:; }else - ssl_gen_err(_("Ignoring CONF_modules_load_file() load error")); + ssl_gen_err(_("SSL/TLS CONF_modules_load_file() load error")); } -#endif +#endif /* HAVE_XSSL_CONFIG */ - if(!(a_xssl_state & a_XSSL_S_RAND_INIT) && a_xssl_rand_init()) - a_xssl_state |= a_XSSL_S_RAND_INIT; - NYD_LEAVE; + if(!(a_xssl_state & a_XSSL_S_RAND_INIT)) + a_xssl_rand_init(); +jleave: + NYD2_LEAVE; } #if HAVE_XSSL_OPENSSL < 0x10100 @@ -606,153 +631,193 @@ jouter: #ifdef HAVE_XSSL_CONF_CTX static void * -_ssl_conf_setup(SSL_CTX *ctxp) -{ +a_xssl_conf_setup(SSL_CTX *ctxp, struct url const *urlp){ + char const *cp; SSL_CONF_CTX *sccp; - NYD_ENTER; + NYD2_ENTER; + + sccp = NULL; - if ((sccp = SSL_CONF_CTX_new()) != NULL) { + if((cp = xok_vlook(ssl_config_module, urlp, OXM_ALL)) != NULL){ +# ifdef HAVE_XSSL_CTX_CONFIG + if(!(a_xssl_state & a_XSSL_S_CONF_LOAD)){ + n_err(_("*ssl-config-module*: no *ssl-config-file* loaded: %s\n"), + n_shexp_quote_cp(cp, FAL0)); + goto jleave; + }else if(!SSL_CTX_config(ctxp, cp)){ + ssl_gen_err(_("*ssl-config-module*: load error for %s, section [%s]"), + n_uagent, n_shexp_quote_cp(cp, FAL0)); + goto jleave; + } +# else + n_err(_("*ssl-config-module*: set but not supported: %s\n"), + n_shexp_quote_cp(cp, FAL0)); + goto jleave; +# endif + } + + if((sccp = SSL_CONF_CTX_new()) != NULL){ SSL_CONF_CTX_set_flags(sccp, SSL_CONF_FLAG_FILE | SSL_CONF_FLAG_CLIENT | SSL_CONF_FLAG_CERTIFICATE | SSL_CONF_FLAG_SHOW_ERRORS); SSL_CONF_CTX_set_ssl_ctx(sccp, ctxp); - } else + }else ssl_gen_err(_("SSL_CONF_CTX_new() failed")); - - NYD_LEAVE; +jleave: + NYD2_LEAVE; return sccp; } static bool_t -_ssl_conf(void *confp, enum a_xssl_conf_type ct, char const *value) -{ +a_xssl_conf(void *confp, char const *cmd, char const *value){ int rv; - char const *cmsg; - SSL_CONF_CTX *sccp = (SSL_CONF_CTX*)confp; - NYD_ENTER; + SSL_CONF_CTX *sccp; + NYD2_ENTER; - switch (ct) { - case a_XSSL_CT_CERTIFICATE: - cmsg = "ssl-cert"; - rv = SSL_CONF_cmd(sccp, "Certificate", value); - break; - case a_XSSL_CT_CIPHER_STRING: - cmsg = "ssl-cipher-list"; - rv = SSL_CONF_cmd(sccp, "CipherString", value); - break; - case a_XSSL_CT_PRIVATE_KEY: - cmsg = "ssl-key"; - rv = SSL_CONF_cmd(sccp, "PrivateKey", value); - break; - default: - case a_XSSL_CT_OPTIONS: - cmsg = "ssl-options"; - rv = SSL_CONF_cmd(sccp, "Options", "Bugs"); - break; - case a_XSSL_CT_PROTOCOL: - cmsg = "ssl-protocol"; - rv = SSL_CONF_cmd(sccp, "Protocol", value); - break; - case a_XSSL_CT_CURVES: - cmsg = "ssl-curves"; - rv = SSL_CONF_cmd(sccp, "Curves", value); - break; - } + if(n_poption & n_PO_D_V) + n_err(_("SSL/TLS: applying config: %s = %s\n"), + n_shexp_quote_cp(cmd, FAL0), n_shexp_quote_cp(value, FAL0)); - if (rv == 2) + rv = SSL_CONF_cmd(sccp = confp, cmd, value); + if(rv == 2) rv = 0; - else { - if (rv == 0) - ssl_gen_err(_("SSL_CONF_CTX_cmd() failed for *%s*"), cmsg); + else{ + cmd = n_shexp_quote_cp(cmd, FAL0); + value = n_shexp_quote_cp(value, FAL0); + if(rv == 0) + ssl_gen_err(_("SSL/TLS: config failure: %s = %s"), cmd, value); else - n_err(_("%s: *%s* implementation error, please report this\n"), - n_uagent, cmsg); + n_err(_("SSL/TLS: please report this config error: %s = %s\n"), + cmd, value); rv = 1; } - - NYD_LEAVE; + NYD2_LEAVE; return (rv == 0); } static bool_t -_ssl_conf_finish(void **confp, bool_t error) -{ - SSL_CONF_CTX **sccp = (SSL_CONF_CTX**)confp; +a_xssl_conf_finish(void **confp, bool_t error){ + SSL_CONF_CTX **sccp; bool_t rv; - NYD_ENTER; + NYD2_ENTER; - if (!(rv = error)) + sccp = (SSL_CONF_CTX**)confp; + + if(!(rv = error)) rv = (SSL_CONF_CTX_finish(*sccp) != 0); SSL_CONF_CTX_free(*sccp); *sccp = NULL; - NYD_LEAVE; + NYD2_LEAVE; return rv; } #else /* HAVE_XSSL_CONF_CTX */ +# ifdef HAVE_XSSL_CTX_CONFIG +# error SSL_CTX_config(3) support unexpected without SSL_CONF_CTX support +# endif + static void * -_ssl_conf_setup(SSL_CTX* ctxp) -{ +a_xssl_conf_setup(SSL_CTX* ctxp, struct url const *urlp){ + char const *cp; + NYD2_ENTER; + + if((cp = xok_vlook(ssl_config_module, urlp, OXM_ALL)) != NULL){ + n_err(_("*ssl-config-module*: set but not supported: %s\n"), + n_shexp_quote_cp(cp, FAL0)); + ctxp = NULL; + } + NYD2_LEAVE; return ctxp; } static bool_t -_ssl_conf(void *confp, enum a_xssl_conf_type ct, char const *value){ +a_xssl_conf(void *confp, char const *cmd, char const *value){ + char const *xcmd, *emsg; SSL_CTX *ctxp; NYD2_ENTER; + if(n_poption & n_PO_D_V) + n_err(_("SSL/TLS: applying config: %s = %s\n"), + n_shexp_quote_cp(cmd, FAL0), n_shexp_quote_cp(value, FAL0)); + ctxp = confp; - switch(ct){ - case a_XSSL_CT_CERTIFICATE: + if(!asccasecmp(cmd, xcmd = "Certificate")){ if(SSL_CTX_use_certificate_chain_file(ctxp, value) != 1){ - ssl_gen_err(_("Can't load certificate from file %s\n"), - n_shexp_quote_cp(value, FAL0)); - confp = NULL; + emsg = N_("SSL/TLS: %s: cannot load from file %s\n"); + goto jerr; } - break; - case a_XSSL_CT_CIPHER_STRING: + }else if(!asccasecmp(cmd, xcmd = "CipherList")){ if(SSL_CTX_set_cipher_list(ctxp, value) != 1){ - ssl_gen_err(_("Invalid cipher string: %s\n"), value); - confp = NULL; + emsg = N_("SSL/TLS: %s: invalid: %s\n"); + goto jerr; } - break; - case a_XSSL_CT_CURVES: + }else if(!asccasecmp(cmd, xcmd = "Curves")){ #ifdef SSL_CTRL_SET_CURVES_LIST if(SSL_CTX_set1_curves_list(ctxp, value) != 1){ - ssl_gen_err(_("Invalid curves string: %s\n"), value); - confp = NULL; + emsg = N_("SSL/TLS: %s: invalid: %s\n"); + goto jerr; } #else - n_err(_("*ssl-curves*: as such not supported\n")); - confp = NULL; + value = NULL; + emsg = N_("SSL/TLS: %s: directive not supported\n"); + goto jxerr; #endif - break; - case a_XSSL_CT_PRIVATE_KEY: - if(SSL_CTX_use_PrivateKey_file(ctxp, value, SSL_FILETYPE_PEM) != 1){ - ssl_gen_err(_("Can't load private key from file %s\n"), - n_shexp_quote_cp(value, FAL0)); - confp = NULL; + }else if((emsg = NULL, !asccasecmp(cmd, xcmd = "MaxProtocol")) || + (emsg = (char*)-1, !asccasecmp(cmd, xcmd = "MinProtocol"))){ +#ifndef HAVE_XSSL_SET_MIN_PROTO_VERSION + value = NULL; + emsg = N_("SSL/TLS: %s: directive not supported\n"); + goto jxerr; +#else + struct a_xssl_protocol const *xpp; + size_t i; + + for(i = 1 /* [0] == ALL */;;){ + xpp = &a_xssl_protocols[i]; + + if(xpp->sp_ok_minmaxproto && !asccasecmp(value, xpp->sp_name)) + break; + + if(++i >= n_NELEM(a_xssl_protocols)){ + emsg = N_("SSL/TLS: %s: unsupported element: %s\n"); + goto jxerr; + } + } + + if((emsg == NULL ? SSL_CTX_set_max_proto_version(ctxp, xpp->sp_version) + : SSL_CTX_set_min_proto_version(ctxp, xpp->sp_version)) != 1){ + emsg = N_("SSL/TLS: %s: invalid protocol: %s\n"); + goto jerr; + } +#endif /* !HAVE_XSSL_SET_MIN_PROTO_VERSION */ + }else if(!asccasecmp(cmd, xcmd = "Options")){ + if(asccasecmp(value, "Bugs")){ + emsg = N_("SSL/TLS: %s: fallback only supports value \"Bugs\": %s\n"); + goto jxerr; } - break; - case a_XSSL_CT_OPTIONS: - /* "Options"="Bugs" TODO *ssl-options* */ SSL_CTX_set_options(ctxp, SSL_OP_ALL); - break; - case a_XSSL_CT_PROTOCOL:{ + }else if(!asccasecmp(cmd, xcmd = "PrivateKey")){ + if(SSL_CTX_use_PrivateKey_file(ctxp, value, SSL_FILETYPE_PEM) != 1){ + emsg = N_("%s: cannot load from file %s\n"); + goto jerr; + } + }else if(!asccasecmp(cmd, xcmd = "Protocol")){ char *iolist, *cp, addin; size_t i; - sl_i opts = 0; + sl_i opts; + + opts = 0; - confp = NULL; for(iolist = cp = savestr(value); (cp = n_strsep(&iolist, ',', FAL0)) != NULL;){ if(*cp == '\0'){ - n_err(_("*ssl-protocol*: empty arguments are not supported\n")); - goto jleave; + value = NULL; + emsg = N_("SSL/TLS: %s: empty elements are not supported\n"); + goto jxerr; } addin = TRU1; @@ -763,32 +828,51 @@ _ssl_conf(void *confp, enum a_xssl_conf_type ct, char const *value){ } for(i = 0;;){ - if(!asccasecmp(cp, a_xssl_protocols[i].sp_name)){ + struct a_xssl_protocol const *xpp; + + xpp = &a_xssl_protocols[i]; + + if(xpp->sp_ok_proto && !asccasecmp(cp, xpp->sp_name)){ /* We need to inverse the meaning of the _NO_s */ if(!addin) - opts |= a_xssl_protocols[i].sp_flag; + opts |= xpp->sp_op_no; else - opts &= ~a_xssl_protocols[i].sp_flag; + opts &= ~xpp->sp_op_no; break; } - if(++i < n_NELEM(a_xssl_protocols)) - continue; - n_err(_("*ssl-protocol*: unsupported value: %s\n"), cp); - goto jleave; + + if(++i >= n_NELEM(a_xssl_protocols)){ + emsg = N_("SSL/TLS: %s: unsupported element: %s\n"); + goto jxerr; + } } } - confp = ctxp; + + SSL_CTX_clear_options(ctxp, SSL_OP_NO_SSL_MASK); SSL_CTX_set_options(ctxp, opts); - } break; + }else{ + xcmd = n_shexp_quote_cp(cmd, FAL0); + emsg = N_("SSL/TLS: unsupported directive: %s: value: %s\n"); + goto jxerr; } + jleave: NYD2_LEAVE; return (confp != NULL); +jerr: + ssl_gen_err(V_(emsg), xcmd, n_shexp_quote_cp(value, FAL0)); + confp = NULL; + goto jleave; +jxerr: + if(value != NULL) + value = n_shexp_quote_cp(value, FAL0); + n_err(V_(emsg), xcmd, value); + confp = NULL; + goto jleave; } static bool_t -_ssl_conf_finish(void **confp, bool_t error) -{ +a_xssl_conf_finish(void **confp, bool_t error){ n_UNUSED(confp); n_UNUSED(error); return TRU1; @@ -796,31 +880,221 @@ _ssl_conf_finish(void **confp, bool_t error) #endif /* !HAVE_XSSL_CONF_CTX */ static bool_t -_ssl_load_verifications(SSL_CTX *ctxp) -{ +a_xssl_obsolete_conf_vars(void *confp, struct url const *urlp){ + char const *cp, *cp_base, *certchain; + bool_t rv; + NYD2_ENTER; + + rv = FAL0; + + /* Certificate via ssl-cert */ + if((certchain = cp = xok_vlook(ssl_cert, urlp, OXM_ALL)) != NULL){ + n_OBSOLETE(_("please use *ssl-config-pairs* instead of *ssl-cert*")); + if((cp_base = fexpand(cp, FEXP_LOCAL | FEXP_NOPROTO)) == NULL){ + n_err(_("*ssl-cert* value expansion failed: %s\n"), + n_shexp_quote_cp(cp, FAL0)); + goto jleave; + } + if(!a_xssl_conf(confp, "Certificate", certchain = cp_base)) + goto jleave; + } + + /* CipherList via ssl-ciper-list */ + if((cp = xok_vlook(ssl_cipher_list, urlp, OXM_ALL)) != NULL){ + n_OBSOLETE(_("please use *ssl-config-pairs* instead of " + "*ssl-cipher-list*")); + if(!a_xssl_conf(confp, "CipherList", cp)) + goto jleave; + } + + /* Curves via ssl-curves */ + if((cp = xok_vlook(ssl_curves, urlp, OXM_ALL)) != NULL){ + n_OBSOLETE(_("please use *ssl-config-pairs* instead of *ssl-curves*")); + if(!a_xssl_conf(confp, "Curves", cp)) + goto jleave; + } + + /* PrivateKey via ssl-key */ + if((cp = xok_vlook(ssl_key, urlp, OXM_ALL)) != NULL){ + n_OBSOLETE(_("please use *ssl-config-pairs* instead of *ssl-curves*")); + if((cp_base = fexpand(cp, FEXP_LOCAL | FEXP_NOPROTO)) == NULL){ + n_err(_("*ssl-key* value expansion failed: %s\n"), + n_shexp_quote_cp(cp, FAL0)); + goto jleave; + } + cp = cp_base; + if(certchain == NULL){ + n_err(_("*ssl-key* can only be used together with *ssl-cert*! " + "And use *ssl-config-pairs*!\n")); + goto jleave; + } + } + if((cp != NULL || (cp = certchain) != NULL) && + !a_xssl_conf(confp, "PrivateKey", cp)) + goto jleave; + + /* Protocol via ssl-method or ssl-protocol */ + if((cp = xok_vlook(ssl_method, urlp, OXM_ALL)) != NULL){ + size_t i; + + n_OBSOLETE(_("please use *ssl-config-pairs* instead of *ssl-method*")); + for(i = 0;;){ + if(!asccasecmp(_ssl_methods[i].sm_name, cp)){ + cp = _ssl_methods[i].sm_map; + break; + } + if(++i == n_NELEM(_ssl_methods)){ + n_err(_("Unsupported TLS/SSL method: %s\n"), cp); + goto jleave; + } + } + } + if((cp_base = xok_vlook(ssl_protocol, urlp, OXM_ALL)) != NULL){ + n_OBSOLETE(_("please use *ssl-config-pairs* instead of *ssl-protocol*")); + if(cp != NULL && (n_poption & n_PO_D_V)) + n_err(_("*ssl-protocol* overrides *ssl-method*! " + "And please use *ssl-config-pairs* instead!\n")); + cp = cp_base; + } + if(cp != NULL && !a_xssl_conf(confp, "Protocol", cp)) + goto jleave; + + rv = TRU1; +jleave: + NYD2_LEAVE; + return rv; +} + +static bool_t +a_xssl_config_pairs(void *confp, struct url const *urlp){ + /* Due to interdependencies some commands have to be delayed a bit */ + static char const cmdcert[] = "Certificate", cmdprivkey[] = "PrivateKey"; + char const *valcert, *valprivkey; + char *pairs, *cp, *cmd, *val; + NYD2_ENTER; + + if((pairs = n_UNCONST(xok_vlook(ssl_config_pairs, urlp, OXM_ALL))) == NULL) + goto jleave; + pairs = savestr(pairs); + + valcert = valprivkey = NULL; + + while((cp = n_strsep_esc(&pairs, ',', FAL0)) != NULL){ + char c; + enum{ + a_NONE, + a_EXPAND = 1u<<0, + a_CERT = 1u<<1, + a_PRIVKEY = 1u<<2, + a_EXPAND_MASK = a_EXPAND | a_CERT | a_PRIVKEY + } f; + + /* Directive, space trimmed */ + if((cmd = strchr(cp, '=')) == NULL){ +jenocmd: + if(pairs == NULL) + pairs = n_UNCONST(n_empty); + n_err(_("*ssl-config-pairs*: missing directive: %s; rest: %s\n"), + n_shexp_quote_cp(cp, FAL0), n_shexp_quote_cp(pairs, FAL0)); + goto jleave; + } + val = &cmd[1]; + + if((cmd > cp && cmd[-1] == '*')){ + --cmd; + f = a_EXPAND; + }else + f = a_NONE; + while(cmd > cp && (c = cmd[-1], blankspacechar(c))) + --cmd; + if(cmd == cp) + goto jenocmd; + *cmd = '\0'; + cmd = cp; + + /* Command with special treatment? */ + if(!asccasecmp(cmd, cmdcert)) + f |= a_CERT; + else if(!asccasecmp(cmd, cmdprivkey)) + f |= a_PRIVKEY; + + /* Value, space trimmed */ + while((c = *val) != '\0' && blankspacechar(c)) + ++val; + cp = &val[strlen(val)]; + while(cp > val && (c = cp[-1], blankspacechar(c))) + --cp; + *cp = '\0'; + if(cp == val){ + if(pairs == NULL) + pairs = n_UNCONST(n_empty); + n_err(_("*ssl-config-pairs*: missing value: %s; rest: %s\n"), + n_shexp_quote_cp(cmd, FAL0), n_shexp_quote_cp(pairs, FAL0)); + goto jleave; + } + + /* Filename transformations to be applied? */ + if(f & a_EXPAND_MASK){ + if((cp = fexpand(val, FEXP_LOCAL | FEXP_NOPROTO)) == NULL){ + if(pairs == NULL) + pairs = n_UNCONST(n_empty); + n_err(_("*ssl-config-pairs*: value expansion failed: %s: %s; " + "rest: %s\n"), + n_shexp_quote_cp(cmd, FAL0), n_shexp_quote_cp(val, FAL0), + n_shexp_quote_cp(pairs, FAL0)); + goto jleave; + } + val = cp; + } + + /* Some things have to be delayed */ + if(f & a_CERT) + valcert = val; + else if(f & a_PRIVKEY) + valprivkey = val; + else if(!a_xssl_conf(confp, cmd, val)){ + pairs = n_UNCONST(n_empty); + goto jleave; + } + } + + /* Work the delayed ones */ + if((valcert != NULL && !a_xssl_conf(confp, cmdcert, valcert)) || + ((valprivkey != NULL || (valprivkey = valcert) != NULL) && + !a_xssl_conf(confp, cmdprivkey, valprivkey))) + pairs = n_UNCONST(n_empty); + +jleave: + NYD2_LEAVE; + return (pairs == NULL); +} + +static bool_t +a_xssl_load_verifications(SSL_CTX *ctxp, struct url const *urlp){ char *ca_dir, *ca_file; X509_STORE *store; - bool_t rv = FAL0; - NYD_ENTER; + bool_t rv; + NYD2_ENTER; - if (ssl_verify_level == SSL_VERIFY_IGNORE) { + if(ssl_verify_level == SSL_VERIFY_IGNORE){ rv = TRU1; goto jleave; } + rv = FAL0; - if ((ca_dir = ok_vlook(ssl_ca_dir)) != NULL) + if((ca_dir = xok_vlook(ssl_ca_dir, urlp, OXM_ALL)) != NULL) ca_dir = fexpand(ca_dir, FEXP_LOCAL | FEXP_NOPROTO); - if ((ca_file = ok_vlook(ssl_ca_file)) != NULL) + if((ca_file = xok_vlook(ssl_ca_file, urlp, OXM_ALL)) != NULL) ca_file = fexpand(ca_file, FEXP_LOCAL | FEXP_NOPROTO); - if ((ca_dir != NULL || ca_file != NULL) && - SSL_CTX_load_verify_locations(ctxp, ca_file, ca_dir) != 1) { + if((ca_dir != NULL || ca_file != NULL) && + SSL_CTX_load_verify_locations(ctxp, ca_file, ca_dir) != 1){ char const *m1, *m2, *m3; - if (ca_dir != NULL) { + if(ca_dir != NULL){ m1 = ca_dir; m2 = (ca_file != NULL) ? _(" or ") : n_empty; - } else + }else m1 = m2 = n_empty; m3 = (ca_file != NULL) ? ca_file : n_empty; ssl_gen_err(_("Error loading %s%s%s\n"), m1, m2, m3); @@ -833,7 +1107,7 @@ _ssl_load_verifications(SSL_CTX *ctxp) if((xv15 = ok_blook(ssl_no_default_ca))) n_OBSOLETE(_("please use *ssl-ca-no-defaults*, " "not *ssl-no-default-ca*")); - if(!ok_blook(ssl_ca_no_defaults) && !xv15 && + if(!xok_blook(ssl_ca_no_defaults, urlp, OXM_ALL) && !xv15 && SSL_CTX_set_default_verify_paths(ctxp) != 1) { ssl_gen_err(_("Error loading built-in default CA locations\n")); goto jleave; @@ -845,11 +1119,11 @@ _ssl_load_verifications(SSL_CTX *ctxp) SSL_CTX_set_verify(ctxp, SSL_VERIFY_PEER, &_ssl_verify_cb); store = SSL_CTX_get_cert_store(ctxp); load_crls(store, ok_v_ssl_crl_file, ok_v_ssl_crl_dir); - a_xssl_ca_flags(store, ok_vlook(ssl_ca_flags)); + a_xssl_ca_flags(store, xok_vlook(ssl_ca_flags, urlp, OXM_ALL)); rv = TRU1; jleave: - NYD_LEAVE; + NYD2_LEAVE; return rv; } @@ -1416,8 +1690,8 @@ FL void ssl_rand_bytes(void *buf, size_t blen){ NYD_ENTER; - if(!(a_xssl_state & a_XSSL_S_RAND_INIT) && a_xssl_rand_init()) - a_xssl_state |= a_XSSL_S_RAND_INIT; + if(!(a_xssl_state & a_XSSL_S_RAND_INIT)) + a_xssl_rand_init(); while(blen > 0){ si32_t i; @@ -1432,20 +1706,18 @@ ssl_rand_bytes(void *buf, size_t blen){ #endif FL enum okay -ssl_open(struct url const *urlp, struct sock *sp) -{ - SSL_CTX *ctxp; +ssl_open(struct url const *urlp, struct sock *sp){ void *confp; - char const *cp, *cp_base; - size_t i; - enum okay rv = STOP; + SSL_CTX *ctxp; + enum okay rv; NYD_ENTER; a_xssl_init(); + rv = STOP; ssl_set_verify_level(urlp); - if ((ctxp = SSL_CTX_new(n_XSSL_CLIENT_METHOD())) == NULL) { + if((ctxp = SSL_CTX_new(n_XSSL_CLIENT_METHOD())) == NULL){ ssl_gen_err(_("SSL_CTX_new() failed")); goto jleave; } @@ -1455,78 +1727,18 @@ ssl_open(struct url const *urlp, struct sock *sp) SSL_CTX_set_mode(ctxp, SSL_MODE_AUTO_RETRY); #endif - if ((confp = _ssl_conf_setup(ctxp)) == NULL) + if((confp = a_xssl_conf_setup(ctxp, urlp)) == NULL) goto jerr0; - /* TODO obsolete Check for *ssl-method*, warp to a *ssl-protocol* value */ - if ((cp = xok_vlook(ssl_method, urlp, OXM_ALL)) != NULL) { - n_OBSOLETE(_("please use *ssl-protocol* instead of *ssl-method*")); - if (n_poption & n_PO_D_V) - n_err(_("*ssl-method*: %s\n"), cp); - for (i = 0;;) { - if (!asccasecmp(_ssl_methods[i].sm_name, cp)) { - cp = _ssl_methods[i].sm_map; - break; - } - if (++i == n_NELEM(_ssl_methods)) { - n_err(_("Unsupported TLS/SSL method: %s\n"), cp); - goto jerr1; - } - } - } - /* *ssl-protocol* */ - if ((cp_base = xok_vlook(ssl_protocol, urlp, OXM_ALL)) != NULL) { - if (n_poption & n_PO_D_V) - n_err(_("*ssl-protocol*: %s\n"), cp_base); - cp = cp_base; - } - cp = (cp != NULL ? savecatsep(cp, ',', n_XSSL_DISABLED_PROTOCOLS) - : n_XSSL_DISABLED_PROTOCOLS); - if (!_ssl_conf(confp, a_XSSL_CT_PROTOCOL, cp)) + if(!a_xssl_obsolete_conf_vars(confp, urlp)) goto jerr1; - - /* *ssl-cert* */ - if ((cp = xok_vlook(ssl_cert, urlp, OXM_ALL)) != NULL) { - if (n_poption & n_PO_D_V) - n_err(_("*ssl-cert* %s\n"), n_shexp_quote_cp(cp, FAL0)); - if ((cp_base = fexpand(cp, FEXP_LOCAL | FEXP_NOPROTO)) == NULL) { - n_err(_("*ssl-cert* value expansion failed: %s\n"), - n_shexp_quote_cp(cp, FAL0)); - goto jerr1; - } - cp = cp_base; - if (!_ssl_conf(confp, a_XSSL_CT_CERTIFICATE, cp)) - goto jerr1; - - /* *ssl-key* */ - if ((cp_base = xok_vlook(ssl_key, urlp, OXM_ALL)) != NULL) { - if (n_poption & n_PO_D_V) - n_err(_("*ssl-key* %s\n"), n_shexp_quote_cp(cp_base, FAL0)); - if ((cp = fexpand(cp_base, FEXP_LOCAL | FEXP_NOPROTO)) == NULL) { - n_err(_("*ssl-key* value expansion failed: %s\n"), - n_shexp_quote_cp(cp_base, FAL0)); - goto jerr1; - } - } - if (!_ssl_conf(confp, a_XSSL_CT_PRIVATE_KEY, cp)) - goto jerr1; - } - - if ((cp = xok_vlook(ssl_cipher_list, urlp, OXM_ALL)) != NULL && - !_ssl_conf(confp, a_XSSL_CT_CIPHER_STRING, cp)) - goto jerr1; - if ((cp = xok_vlook(ssl_curves, urlp, OXM_ALL)) != NULL && - !_ssl_conf(confp, a_XSSL_CT_CURVES, cp)) + if(!a_xssl_config_pairs(confp, urlp)) goto jerr1; - - if (!_ssl_load_verifications(ctxp)) - goto jerr1; - - if (!_ssl_conf(confp, a_XSSL_CT_OPTIONS, NULL)) /* TODO *ssl-options* */ + if(!a_xssl_load_verifications(ctxp, urlp)) goto jerr1; /* Done with context setup, create our new per-connection structure */ - if (!_ssl_conf_finish(&confp, FAL0)) + if(!a_xssl_conf_finish(&confp, FAL0)) goto jerr0; if ((sp->s_ssl = SSL_new(ctxp)) == NULL) { @@ -1537,7 +1749,7 @@ ssl_open(struct url const *urlp, struct sock *sp) /* Try establish SNI extension; even though this is a TLS extension the * protocol isn't checked once the host name is set, and therefore i've * refrained from changing so much code just to check out whether we are - * using SSLv3, which should become rarer and rarer */ + * using SSLv3, which should become more and more rare */ #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME if((urlp->url_flags & n_URL_TLS_MASK) && (urlp->url_flags & n_URL_HOST_IS_NAME)){ @@ -1577,7 +1789,7 @@ jerr2: sp->s_ssl = NULL; jerr1: if (confp != NULL) - _ssl_conf_finish(&confp, TRU1); + a_xssl_conf_finish(&confp, TRU1); jerr0: SSL_CTX_free(ctxp); goto jleave; -- 2.11.4.GIT