On Mon, Sep 21, 2015 at 10:34:55AM +0100, Mike Crowe wrote:
> The gnutls vtls back-end was previously ignoring any password set via
> CURLOPT_KEYPASSWD. Presumably this was because
> gnutls_certificate_set_x509_key_file did not support encrypted keys.
> 
> gnutls now has a gnutls_certificate_set_x509_key_file2 function that
> does support encrypted keys. Let's determine at compile time whether the
> available gnutls supports this new function. If it does then use it to
> pass the password. If it does not then emit a helpful diagnostic if a
> password is set. This is preferable to the previous behaviour of just
> failing to read the certificate without giving a reason in that case.
> 
> Signed-off-by: Mike Crowe <[email protected]>
> ---
>  configure.ac    |  1 +
>  lib/vtls/gtls.c | 44 +++++++++++++++++++++++++++++++++++---------
>  2 files changed, 36 insertions(+), 9 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 843a3ba..26d77eb 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1836,6 +1836,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
>              AC_MSG_NOTICE([Added $gtlslib to LD_LIBRARY_PATH])
>            fi
>          fi
> +        AC_CHECK_FUNCS(gnutls_certificate_set_x509_key_file2)
>        fi
>  
>      fi
> diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
> index c54dfc1..9f3ea10 100644
> --- a/lib/vtls/gtls.c
> +++ b/lib/vtls/gtls.c
> @@ -656,15 +656,41 @@ gtls_connect_step1(struct connectdata *conn,
>  #endif
>  
>    if(data->set.str[STRING_CERT]) {
> -    if(gnutls_certificate_set_x509_key_file(
> -         conn->ssl[sockindex].cred,
> -         data->set.str[STRING_CERT],
> -         data->set.str[STRING_KEY] ?
> -         data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
> -         do_file_type(data->set.str[STRING_CERT_TYPE]) ) !=
> -       GNUTLS_E_SUCCESS) {
> -      failf(data, "error reading X.509 key or certificate file");
> -      return CURLE_SSL_CONNECT_ERROR;
> +    if(data->set.str[STRING_KEY_PASSWD]) {
> +#if HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2
> +      const unsigned int supported_key_encryption_algorithms =
> +        GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
> +        GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
> +        GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
> +        GNUTLS_PKCS_USE_PBES2_AES_256;
> +      if(gnutls_certificate_set_x509_key_file2(
> +           conn->ssl[sockindex].cred,
> +           data->set.str[STRING_CERT],
> +           data->set.str[STRING_KEY] ?
> +           data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
> +           do_file_type(data->set.str[STRING_CERT_TYPE]),
> +           data->set.str[STRING_KEY_PASSWD],
> +           supported_key_encryption_algorithms) !=
> +         GNUTLS_E_SUCCESS) {
> +        failf(data,
> +              "error reading X.509 potentially-encrypted key certificate 
> file");
> +        return CURLE_SSL_CONNECT_ERROR;
> +#else
> +        failf(data, "gnutls lacks support for encrypted key files");
> +        return CURLE_SSL_CONNECT_ERROR;

IMO this failure should happen much earlier, ideally when CURLOPT_KEYPASSWD is
set in Curl_setopt(), like we do for e.g. CURLOPT_SSL_VERIFYSTATUS. Other TLS
backends that support CURLOPT_KEYPASSWD should be updated as well, but that
should probably go in a separate patch.

Cheers

Attachment: signature.asc
Description: PGP signature

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to