Re: [PATCH] Prompt for password when using encrypted client certificate

2021-08-11 Thread Kevin J. McCarthy

On Wed, Aug 11, 2021 at 03:02:30PM -0400, Craig Gallek wrote:

This already worked when compiled against openssl, but not with gnutls.


Looks like this is based on the OpenSSL calls.  If you can verify it 
works for you, I have no problem with the patch.



I figured it would be good to get some early feedback on this, though.
In particular, do you care that this duplicates a translation string?
It could certainly be put in a common place, but I wasn't sure where.


It's not a problem to duplicate translation strings, so this is fine.


This change is safe with or without the gnutls change.  It simply won't
call the prompt callback with older versions of gnutls (though, it's proabably
best to wait for that change anyway to ensure that this callback mechanism
will be the one actually used).


I agree.  Let's wait until your merge request is accepted.  If you 
wouldn't mind sending a followup email then, I'll be glad to merge it 
at that point.


--
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA


signature.asc
Description: PGP signature


[PATCH] Prompt for password when using encrypted client certificate

2021-08-11 Thread Craig Gallek
This already worked when compiled against openssl, but not with gnutls.

Signed-off-by: Craig Gallek 
---

NOTE: this depends on a yet-to-be-merged change to gnutls:
https://gitlab.com/gnutls/gnutls/-/merge_requests/1459

I figured it would be good to get some early feedback on this, though.
In particular, do you care that this duplicates a translation string?
It could certainly be put in a common place, but I wasn't sure where.

This change is safe with or without the gnutls change.  It simply won't
call the prompt callback with older versions of gnutls (though, it's proabably
best to wait for that change anyway to ensure that this callback mechanism
will be the one actually used).

 mutt_ssl_gnutls.c | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/mutt_ssl_gnutls.c b/mutt_ssl_gnutls.c
index a576ab1537cb..b4540ad09ced 100644
--- a/mutt_ssl_gnutls.c
+++ b/mutt_ssl_gnutls.c
@@ -93,6 +93,10 @@ static int tls_starttls_close (CONNECTION* conn);
 static int tls_init (void);
 static int tls_negotiate (CONNECTION* conn);
 static int tls_check_certificate (CONNECTION* conn);
+static int tls_passwd_cb (void* userdata, int attempt, const char* token_url,
+  const char* token_label,
+  unsigned int flags,
+  char* pin, size_t pin_max);
 
 
 static int tls_init (void)
@@ -426,6 +430,8 @@ static int tls_negotiate (CONNECTION * conn)
 mutt_sleep (2);
 return -1;
   }
+  gnutls_certificate_set_pin_function (data->xcred, tls_passwd_cb,
+   >account);
 
   gnutls_certificate_set_x509_trust_file (data->xcred, SslCertFile,
  GNUTLS_X509_FMT_PEM);
@@ -1262,3 +1268,32 @@ static int tls_check_certificate (CONNECTION* conn)
 
   return rc;
 }
+
+static void client_cert_prompt (char *prompt, size_t prompt_size, ACCOUNT 
*account)
+{
+  /* L10N:
+ When using a $ssl_client_cert, GNUTLS may prompt for the password
+ to decrypt the cert.  %s is the hostname.
+  */
+  snprintf (prompt, prompt_size, _("Password for %s client cert: "),
+account->host);
+}
+
+static int tls_passwd_cb (void* userdata, int attempt, const char* token_url,
+  const char* token_label,
+  unsigned int flags,
+  char* buf, size_t size)
+{
+  ACCOUNT *account;
+
+  if (!buf || size <= 0 || !userdata)
+return GNUTLS_E_INVALID_PASSWORD;
+
+  account = (ACCOUNT *) userdata;
+
+  if (_mutt_account_getpass (account, client_cert_prompt))
+return GNUTLS_E_INVALID_PASSWORD;
+
+  snprintf(buf, size, "%s", account->pass);
+  return GNUTLS_E_SUCCESS;
+}
-- 
2.30.2