summaryrefslogtreecommitdiff
path: root/home/pim/0002-gnutls-implement-token-insertion-and-PKCS-11-PIN-pro.patch
blob: 2f13e682c39101b0b65aa3d45ca3bfd51d91d86c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
From 276cf337346e0ea111883a05bc00f764d201d6ab Mon Sep 17 00:00:00 2001
From: Alejandro Soto <alejandro@34project.org>
Date: Sun, 29 Jun 2025 11:35:57 -0600
Subject: [PATCH 2/2] gnutls: implement token insertion and PKCS#11 PIN prompts

---
 conn/gnutls.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/conn/gnutls.c b/conn/gnutls.c
index 379580871..32ad1ae85 100644
--- a/conn/gnutls.c
+++ b/conn/gnutls.c
@@ -29,6 +29,7 @@
 
 #include "config.h"
 #include <gnutls/gnutls.h>
+#include <gnutls/pkcs11.h>
 #include <gnutls/x509.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -39,10 +40,14 @@
 #include "mutt/lib.h"
 #include "config/lib.h"
 #include "core/lib.h"
-#include "lib.h"
 #include "connaccount.h"
 #include "connection.h"
+#include "editor/lib.h"
 #include "globals.h"
+#include "gui/lib.h"
+#include "history/lib.h"
+#include "lib.h"
+#include "mutt.h"
 #include "muttlib.h"
 #include "ssl.h"
 
@@ -84,6 +89,64 @@ struct TlsSockData
   gnutls_certificate_credentials_t xcred;
 };
 
+int tls_pkcs11_token_callback(void *userdata, const char *label, unsigned retry)
+{
+  (void) userdata;
+
+  if (OptNoCurses) {
+    mutt_error(_("Unable to prompt for PKCS#11 token insertion in batch mode"));
+    return GNUTLS_E_INVALID_REQUEST;
+  }
+
+  char msg[256] = { 0 };
+
+  size_t len = 0;
+  if (retry > 0)
+    len += snprintf(msg, sizeof msg, _("[Not found - attempt %u] "), retry + 1);
+
+  snprintf(msg + len, sizeof msg - len, _("Insert PKCS#11 token '%s' and press any key..."), label);
+
+  mutt_any_key_to_continue(msg);
+  return 0;
+}
+
+int tls_pin_callback(void *userdata, int attempt, const char *url, const char *label,
+                     unsigned int flags, char *pin, size_t pin_max)
+{
+  (void) url;
+  const intptr_t is_token = (intptr_t) userdata;
+
+  if (OptNoCurses) {
+    mutt_error(_("Unable to prompt for pin in batch mode"));
+    return GNUTLS_E_INVALID_REQUEST;
+  }
+
+  char prompt[256] = { 0 };
+
+  size_t len = 0;
+  if (attempt > 0)
+    len += snprintf(prompt, sizeof prompt, _("[Attempt %d] "), attempt + 1);
+
+  if (flags & GNUTLS_PIN_FINAL_TRY)
+    len += mutt_str_copy(prompt + len, _("FINAL TRY - "), sizeof prompt - len);
+
+  if (is_token)
+    snprintf(prompt + len, sizeof prompt - len, _("Pin for PKCS#11 token '%s': "), label);
+  else
+    snprintf(prompt + len, sizeof prompt - len, _("Password for certificate '%s': "), label);
+
+  struct Buffer *buf = buf_pool_get();
+  const int rc = mw_get_field(prompt, buf, MUTT_COMP_PASS | MUTT_COMP_UNBUFFERED,
+                              HC_OTHER, NULL, NULL);
+  mutt_str_copy(pin, buf_string(buf), pin_max);
+  buf_pool_release(&buf);
+
+  if (rc != 0)
+    return GNUTLS_E_APPLICATION_ERROR_MIN;
+
+  return 0;
+}
+
 /**
  * tls_init - Set up Gnu TLS
  * @retval  0 Success
@@ -104,6 +167,10 @@ static int tls_init(void)
     return -1;
   }
 
+  const intptr_t is_token = 1;
+  gnutls_pkcs11_set_pin_function(tls_pin_callback, (void *)is_token);
+  gnutls_pkcs11_set_token_function(tls_pkcs11_token_callback, NULL);
+
   init_complete = true;
   return 0;
 }
@@ -904,6 +971,9 @@ static int tls_negotiate(struct Connection *conn)
     mutt_debug(LL_DEBUG2, "Using client certificate %s, key %s\n", c_ssl_client_cert, c_ssl_client_key);
     gnutls_certificate_set_x509_key_file(data->xcred, c_ssl_client_cert,
                                          c_ssl_client_key, GNUTLS_X509_FMT_PEM);
+
+    const intptr_t is_token = 0;
+    gnutls_certificate_set_pin_function(data->xcred, tls_pin_callback, (void *)is_token);
   }
 
 #ifdef HAVE_DECL_GNUTLS_VERIFY_DISABLE_TIME_CHECKS
-- 
2.49.0