Merge ~paelzer/ubuntu/+source/apache2:eoan-bug-1830728-keys-from-pkcs into ubuntu/+source/apache2:ubuntu/eoan-devel

Proposed by Christian Ehrhardt 
Status: Work in progress
Proposed branch: ~paelzer/ubuntu/+source/apache2:eoan-bug-1830728-keys-from-pkcs
Merge into: ubuntu/+source/apache2:ubuntu/eoan-devel
Diff against target: 764 lines (+730/-0)
5 files modified
debian/changelog (+7/-0)
debian/patches/series (+3/-0)
debian/patches/ubuntu/lp-1830728-Hook-up-PKCS-11-PIN-entry-through-configured-passphr.patch (+328/-0)
debian/patches/ubuntu/lp-1830728-mod_ssl-Add-support-for-loading-TLS-certificates-thr.patch (+207/-0)
debian/patches/ubuntu/lp-1830728-mod_ssl-Add-support-for-loading-private-keys-from-EN.patch (+185/-0)
Reviewer Review Type Date Requested Status
Canonical Server Pending
Canonical Server packageset reviewers Pending
git-ubuntu developers Pending
Review via email: mp+370701@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

This is WIP for now as we still need to find how to carry the doc changes properly into 2.4.x
Upstream changes XML files which are no more bundled (or not exiting in 2.4) in our tarball.
The HTML files in the tarball are the usual "do not edit this is generated" style so I'll need to check where to correctly add the doc changes.

But for now the PPA is enough for IBM to evaluate if this is even what they want (before spending more on the docs).

Revision history for this message
Dimitri John Ledkov (xnox) wrote :

What's the status of said evaluation?

Unmerged commits

0db4573... by Christian Ehrhardt 

changelog: support loading private keys via PKCS#11 token (LP: #1830728)

Signed-off-by: Christian Ehrhardt <email address hidden>

e93ffde... by Christian Ehrhardt 

d/p/ubuntu/lp-1830728-*: support loading private keys via PKCS#11 token (LP: #1830728)

Signed-off-by: Christian Ehrhardt <email address hidden>

5a4aa4d... by Dimitri John Ledkov

Import patches-unapplied version 2.4.38-3ubuntu2 to ubuntu/eoan-proposed

Imported using git-ubuntu import.

Changelog parent: e936130b355fd0cbf58c47c7cd36cf3a0d49a6fb

New changelog entries:
  * Cherrypick upstream test suite fix for buffer.

e936130... by Dimitri John Ledkov

Import patches-unapplied version 2.4.38-3ubuntu1 to ubuntu/eoan-proposed

Imported using git-ubuntu import.

Changelog parent: 6f896d33242900b08c8788338c9e90e23713055c

New changelog entries:
  * Merge from Debian unstable. Remaining changes:
    - Cherrypick upstream testsuite fix:
      + r1850941 Skip tests for TLSv1.3 (where there is no "renegotiation"
      as such).
    - Similarly use TLSv1.2 for pr12355 and pr43738.
    - debian/{control, apache2.install, apache2-utils.ufw.profile,
      apache2.dirs}: Add ufw profiles.
    - debian/apache2.py, debian/apache2-bin.install: Add apport hook.
    - debian/patches/086_svn_cross_compiles: Backport several cross
      fixes from upstream
      [Removed configure chunk, not needed since configure.in is being
       patched.]
    - d/index.html, d/icons/ubuntu-logo.png, d/apache2.postrm: replace
      Debian with Ubuntu on default page.
      + d/source/include-binaries: add Ubuntu icon file
    - d/t/control, d/t/check-http2: add basic test for http2 support

6f896d3... by Stefan Fritsch

Import patches-unapplied version 2.4.38-3 to debian/sid

Imported using git-ubuntu import.

Changelog parent: 847b2dd6c945b42d4b49bbc8fbb24a7dd4fc4897

New changelog entries:
  [ Marc Deslauriers ]
  * SECURITY UPDATE: read-after-free on a string compare in mod_http2
    - debian/patches/CVE-2019-0196.patch: disentangelment of stream and
      request method in modules/http2/h2_request.c.
    - CVE-2019-0196
  * SECURITY UPDATE: privilege escalation from modules' scripts
    - debian/patches/CVE-2019-0211.patch: bind the bucket number of each
      child to its slot number in include/scoreboard.h,
      server/mpm/event/event.c, server/mpm/prefork/prefork.c,
      server/mpm/worker/worker.c.
    - CVE-2019-0211
  * SECURITY UPDATE: mod_ssl access control bypass
    - debian/patches/CVE-2019-0215.patch: restore SSL verify state after
      PHA failure in TLSv1.3 in modules/ssl/ssl_engine_kernel.c.
    - CVE-2019-0215
  * SECURITY UPDATE: mod_auth_digest access control bypass
    - debian/patches/CVE-2019-0217.patch: fix a race condition in
      modules/aaa/mod_auth_digest.c.
    - CVE-2019-0217
  * SECURITY UPDATE: URL normalization inconsistincy
    - debian/patches/CVE-2019-0220-1.patch: merge consecutive slashes in
      the path in include/http_core.h, include/httpd.h, server/core.c,
      server/request.c, server/util.c.
    - debian/patches/CVE-2019-0220-2.patch: fix r->parsed_uri.path safety
      in server/request.c, server/util.c.
    - debian/patches/CVE-2019-0220-3.patch: maintainer mode fix in
      server/util.c.
    - CVE-2019-0220
  [ Stefan Fritsch ]
  * Pull security fixes from 2.4.39 via Ubuntu
  * CVE-2019-0197: mod_http2: Fix possible crash on late upgrade

847b2dd... by Xavier Guimard <email address hidden>

Import patches-unapplied version 2.4.38-2 to debian/sid

Imported using git-ubuntu import.

Changelog parent: 9da9dfa1e43b5d69d2783d1a3e1a5b6dcde606c1

New changelog entries:
  * Disable "reset" test in allowmethods.t (Closes: #921024)

9da9dfa... by Xavier Guimard <email address hidden>

Import patches-unapplied version 2.4.38-1 to debian/sid

Imported using git-ubuntu import.

Changelog parent: 7387d718ca26d92498f9ed1584fea8cbcb4f704e

New changelog entries:
  [ Jelmer Vernooij ]
  * Reverted for now: Transition to automatic debug package (from: apache2-dbg)
  * Trim trailing whitespace
  * Use secure copyright file specification URI
  [ Niels Thykier ]
  * Add Rules-Requires-Root: binary-targets
  [ Xavier Guimard ]
  * Convert signing-key.pgp into signing-key.asc
  * Add http2.conf (Closes: #880993)
  * Remove unnecessary greater-than versioned dependency to dpkg-dev,
    libbrotli-dev and libapache2-mod-md
  * Declare compliance with policy 4.2.1
  * Add spelling errors patch (reported)
  * Fix some spelling errors in debian files
  * Add myself to uploaders
  * Refresh patches
  * Bump debhelper compatibility level to 10
  * debian/rules:
    - Remove unnecessary dh argument --parallel
    - use /usr/share/dpkg/pkg-info.mk instead of dpkg-parsechangelog
  * Add upstream/metadata
  * Replace MIT by Expat in debian/copyright
  * debian/watch: use https url
  * Add documentation links in systemd service files
  * Team upload
  [ Cyrille Bollu ]
  * Put HTTP2 configuration within <IfModule !mpm_prefork></IfModule> tags as
    it gets automatically de-activated upon apache 'startup when using
    mpm_prefork.
  * Updated http2.conf to inform user that they may want to change their
    LogFormat directives.
  [ Xavier Guimard ]
  * New upstream version 2.4.38 (Closes: #920220, #920302, #920303)
  * Refresh patches
  * Remove setenvifexpr.diff patch now included in upstream
  * Replace libapache2-mod-proxy-uwsgi.{post*,prerm} by a maintscript
  * Add a "sleep" in debian/tests/htcacheclean and skip result if "stop" failed
  * Declare compliance with policy 4.3.0
  * Fix homepage to https
  * Update debian/copyright

7387d71... by Stefan Fritsch

Import patches-unapplied version 2.4.37-1 to debian/sid

Imported using git-ubuntu import.

Changelog parent: bf7f8f045ccf34c2c08f02ecdd0f46ef7a97ee46

New changelog entries:
  * New upstream version
    - mod_ssl: Add support for TLSv1.3
  * Add docs symlink for libapache2-mod-proxy-uwsgi. Closes: #910218
  * Update test-framework to r1845652
  * Fix test suite to actually run by creating a test user. It turns out
    the test suite refuses to run as root but returns true even in that
    case. It seems this has been broken since 2.4.27-4, where the test suite
    had been updated and the debci test duration dropped from 15min to
    3min. Also, don't rely on the exit status anymore but parse the test
    output.
  * Backport a fix from trunk for SetEnvIfExpr. This fixes a test failure.

bf7f8f0... by Stefan Fritsch

Import patches-unapplied version 2.4.35-1 to debian/sid

Imported using git-ubuntu import.

Changelog parent: ef5d2450201d96722e86ff11a816bf14e3b9cfca

New changelog entries:
  * New upstream version 2.4.35
    Security fix:
    - CVE-2018-11763: DoS for HTTP/2 connections by continuous SETTINGS
      Closes: #909591
  * Fix lintian warning: Don't force xz in builddeb override.

ef5d245... by Stefan Fritsch

Import patches-unapplied version 2.4.34-1 to debian/sid

Imported using git-ubuntu import.

Changelog parent: f9135dfca55cef91c3af3074fc3ba3826d3f95d8

New changelog entries:
  [ Ondřej Surý ]
  * New upstream version 2.4.34
    Security fixes:
    - CVE-2018-1333: Denial of service in mod_http2. Closes: #904106
    - CVE-2018-8011: Denial of service in mod_md. Closes: #904107
  * Refresh patches for Apache2 2.4.34 release
  * Update the suexec-custom.patch for 2.4.34 release
  [ Stefan Fritsch ]
  * Remove load order dependency introduced in mod_lbmethod_* in 2.4.34
  * Remove debian/gbp.conf. Closes: #904641
  * Fix typo in apache2_switch_mpm() in apache2-maintscript-helper.
    Closes: #904150

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/changelog b/debian/changelog
index 24b7788..9c74c1b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
1apache2 (2.4.38-3ubuntu3) eoan; urgency=medium
2
3 * d/p/ubuntu/lp-1830728-*: support loading private keys via PKCS#11
4 token (LP: #1830728)
5
6 -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Mon, 29 Jul 2019 08:52:19 +0200
7
1apache2 (2.4.38-3ubuntu2) eoan; urgency=medium8apache2 (2.4.38-3ubuntu2) eoan; urgency=medium
29
3 * Cherrypick upstream test suite fix for buffer.10 * Cherrypick upstream test suite fix for buffer.
diff --git a/debian/patches/series b/debian/patches/series
index b570181..f11f226 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -20,3 +20,6 @@ CVE-2019-0197.patch
2020
21# Patches added by Ubuntu21# Patches added by Ubuntu
22086_svn_cross_compiles22086_svn_cross_compiles
23ubuntu/lp-1830728-mod_ssl-Add-support-for-loading-private-keys-from-EN.patch
24ubuntu/lp-1830728-mod_ssl-Add-support-for-loading-TLS-certificates-thr.patch
25ubuntu/lp-1830728-Hook-up-PKCS-11-PIN-entry-through-configured-passphr.patch
diff --git a/debian/patches/ubuntu/lp-1830728-Hook-up-PKCS-11-PIN-entry-through-configured-passphr.patch b/debian/patches/ubuntu/lp-1830728-Hook-up-PKCS-11-PIN-entry-through-configured-passphr.patch
23new file mode 10064426new file mode 100644
index 0000000..6d2117b
--- /dev/null
+++ b/debian/patches/ubuntu/lp-1830728-Hook-up-PKCS-11-PIN-entry-through-configured-passphr.patch
@@ -0,0 +1,328 @@
1From ae480ad7738038e26063b67b545a8e1b85df5451 Mon Sep 17 00:00:00 2001
2From: Joe Orton <jorton@apache.org>
3Date: Fri, 6 Jul 2018 12:01:29 +0000
4Subject: [PATCH] Hook up PKCS#11 PIN entry through configured passphrase entry
5 method.
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10* modules/ssl/ssl_engine_pphrase.c: Add wrappers for OpenSSL UI * API
11 around passphrase entry.
12 (modssl_load_engine_keypair): Take vhost ID and use above rather than
13 default OpenSSL UI.
14
15* modules/ssl/ssl_engine_init.c (ssl_init_server_certs): Pass vhost ID.
16
17Submitted by: Anderson Sasaki<ansaski redhat.com>, jorton
18
19
20git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1835240 13f79535-47bb-0310-9956-ffa450edef68
21
22Origin: upstream, https://github.com/apache/httpd/commit/ae480ad7738038e26063b67b545a8e1b85df5451
23Bug-Ubuntu: https://bugs.launchpad.net/bugs/1830728
24Last-Update: 2019-07-29
25
26---
27 modules/ssl/ssl_engine_init.c | 5 +-
28 modules/ssl/ssl_engine_pphrase.c | 235 ++++++++++++++++++++++++++++++-
29 modules/ssl/ssl_private.h | 1 +
30 3 files changed, 232 insertions(+), 9 deletions(-)
31
32diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
33index c8a3365e0c..be4184ff86 100644
34--- a/modules/ssl/ssl_engine_init.c
35+++ b/modules/ssl/ssl_engine_init.c
36@@ -1293,8 +1293,9 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
37
38 cert = NULL;
39
40- if ((rv = modssl_load_engine_keypair(s, ptemp, engine_certfile,
41- keyfile, &cert, &pkey))) {
42+ if ((rv = modssl_load_engine_keypair(s, ptemp, vhost_id,
43+ engine_certfile, keyfile,
44+ &cert, &pkey))) {
45 return rv;
46 }
47
48diff --git a/modules/ssl/ssl_engine_pphrase.c b/modules/ssl/ssl_engine_pphrase.c
49index 85982c80c1..7688b2425c 100644
50--- a/modules/ssl/ssl_engine_pphrase.c
51+++ b/modules/ssl/ssl_engine_pphrase.c
52@@ -588,13 +588,239 @@ int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv)
53 }
54
55 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
56+
57+/* OpenSSL UI implementation for passphrase entry; largely duplicated
58+ * from ssl_pphrase_Handle_CB but adjusted for UI API. TODO: Might be
59+ * worth trying to shift pphrase handling over to the UI API
60+ * completely. */
61+static int passphrase_ui_open(UI *ui)
62+{
63+ pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui);
64+ SSLSrvConfigRec *sc = mySrvConfig(ppcb->s);
65+
66+ ppcb->nPassPhraseDialog++;
67+ ppcb->nPassPhraseDialogCur++;
68+
69+ /*
70+ * Builtin or Pipe dialog
71+ */
72+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN
73+ || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
74+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
75+ if (!readtty) {
76+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s,
77+ APLOGNO()
78+ "Init: Creating pass phrase dialog pipe child "
79+ "'%s'", sc->server->pphrase_dialog_path);
80+ if (ssl_pipe_child_create(ppcb->p,
81+ sc->server->pphrase_dialog_path)
82+ != APR_SUCCESS) {
83+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ppcb->s,
84+ APLOGNO()
85+ "Init: Failed to create pass phrase pipe '%s'",
86+ sc->server->pphrase_dialog_path);
87+ return 0;
88+ }
89+ }
90+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO()
91+ "Init: Requesting pass phrase via piped dialog");
92+ }
93+ else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */
94+#ifdef WIN32
95+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ppcb->s, APLOGNO()
96+ "Init: Failed to create pass phrase pipe '%s'",
97+ sc->server->pphrase_dialog_path);
98+ return 0;
99+#else
100+ /*
101+ * stderr has already been redirected to the error_log.
102+ * rather than attempting to temporarily rehook it to the terminal,
103+ * we print the prompt to stdout before EVP_read_pw_string turns
104+ * off tty echo
105+ */
106+ apr_file_open_stdout(&writetty, ppcb->p);
107+
108+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO()
109+ "Init: Requesting pass phrase via builtin terminal "
110+ "dialog");
111+#endif
112+ }
113+
114+ /*
115+ * The first time display a header to inform the user about what
116+ * program he actually speaks to, which module is responsible for
117+ * this terminal dialog and why to the hell he has to enter
118+ * something...
119+ */
120+ if (ppcb->nPassPhraseDialog == 1) {
121+ apr_file_printf(writetty, "%s mod_ssl (Pass Phrase Dialog)\n",
122+ AP_SERVER_BASEVERSION);
123+ apr_file_printf(writetty,
124+ "A pass phrase is required to access the private key.\n");
125+ }
126+ if (ppcb->bPassPhraseDialogOnce) {
127+ ppcb->bPassPhraseDialogOnce = FALSE;
128+ apr_file_printf(writetty, "\n");
129+ apr_file_printf(writetty, "Private key %s (%s)\n",
130+ ppcb->key_id, ppcb->pkey_file);
131+ }
132+ }
133+
134+ return 1;
135+}
136+
137+static int passphrase_ui_read(UI *ui, UI_STRING *uis)
138+{
139+ pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui);
140+ SSLSrvConfigRec *sc = mySrvConfig(ppcb->s);
141+ const char *prompt;
142+ int i;
143+ int bufsize;
144+ int len;
145+ char *buf;
146+
147+ prompt = UI_get0_output_string(uis);
148+ if (prompt == NULL) {
149+ prompt = "Enter pass phrase:";
150+ }
151+
152+ /*
153+ * Get the maximum expected size and allocate the buffer
154+ */
155+ bufsize = UI_get_result_maxsize(uis);
156+ buf = apr_pcalloc(ppcb->p, bufsize);
157+
158+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN
159+ || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
160+ /*
161+ * Get the pass phrase through a callback.
162+ * Empty input is not accepted.
163+ */
164+ for (;;) {
165+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
166+ i = pipe_get_passwd_cb(buf, bufsize, "", FALSE);
167+ }
168+ else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */
169+ i = EVP_read_pw_string(buf, bufsize, "", FALSE);
170+ }
171+ if (i != 0) {
172+ OPENSSL_cleanse(buf, bufsize);
173+ return 0;
174+ }
175+ len = strlen(buf);
176+ if (len < 1){
177+ apr_file_printf(writetty, "Apache:mod_ssl:Error: Pass phrase"
178+ "empty (needs to be at least 1 character).\n");
179+ apr_file_puts(prompt, writetty);
180+ }
181+ else {
182+ break;
183+ }
184+ }
185+ }
186+ /*
187+ * Filter program
188+ */
189+ else if (sc->server->pphrase_dialog_type == SSL_PPTYPE_FILTER) {
190+ const char *cmd = sc->server->pphrase_dialog_path;
191+ const char **argv = apr_palloc(ppcb->p, sizeof(char *) * 3);
192+ char *result;
193+
194+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO()
195+ "Init: Requesting pass phrase from dialog filter "
196+ "program (%s)", cmd);
197+
198+ argv[0] = cmd;
199+ argv[1] = ppcb->key_id;
200+ argv[2] = NULL;
201+
202+ result = ssl_util_readfilter(ppcb->s, ppcb->p, cmd, argv);
203+ apr_cpystrn(buf, result, bufsize);
204+ len = strlen(buf);
205+ }
206+
207+ /*
208+ * Ok, we now have the pass phrase, so give it back
209+ */
210+ ppcb->cpPassPhraseCur = apr_pstrdup(ppcb->p, buf);
211+ UI_set_result(ui, uis, buf);
212+
213+ /* Clear sensitive data. */
214+ OPENSSL_cleanse(buf, bufsize);
215+ return 1;
216+}
217+
218+static int passphrase_ui_write(UI *ui, UI_STRING *uis)
219+{
220+ pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui);
221+ SSLSrvConfigRec *sc;
222+ const char *prompt;
223+
224+ sc = mySrvConfig(ppcb->s);
225+
226+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN
227+ || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
228+ prompt = UI_get0_output_string(uis);
229+ apr_file_puts(prompt, writetty);
230+ }
231+
232+ return 1;
233+}
234+
235+static int passphrase_ui_close(UI *ui)
236+{
237+ /*
238+ * Close the pipes if they were opened
239+ */
240+ if (readtty) {
241+ apr_file_close(readtty);
242+ apr_file_close(writetty);
243+ readtty = writetty = NULL;
244+ }
245+ return 1;
246+}
247+
248+static apr_status_t pp_ui_method_cleanup(void *uip)
249+{
250+ UI_METHOD *uim = uip;
251+
252+ UI_destroy_method(uim);
253+
254+ return APR_SUCCESS;
255+}
256+
257+static UI_METHOD *get_passphrase_ui(apr_pool_t *p)
258+{
259+ UI_METHOD *ui_method = UI_create_method("Passphrase UI");
260+
261+ UI_method_set_opener(ui_method, passphrase_ui_open);
262+ UI_method_set_reader(ui_method, passphrase_ui_read);
263+ UI_method_set_writer(ui_method, passphrase_ui_write);
264+ UI_method_set_closer(ui_method, passphrase_ui_close);
265+
266+ apr_pool_cleanup_register(p, ui_method, pp_ui_method_cleanup,
267+ pp_ui_method_cleanup);
268+
269+ return ui_method;
270+}
271+
272+
273 apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p,
274+ const char *vhostid,
275 const char *certid, const char *keyid,
276 X509 **pubkey, EVP_PKEY **privkey)
277 {
278 SSLModConfigRec *mc = myModConfig(s);
279 ENGINE *e;
280- UI_METHOD *ui_method;
281+ UI_METHOD *ui_method = get_passphrase_ui(p);
282+ pphrase_cb_arg_t ppcb;
283+
284+ memset(&ppcb, 0, sizeof ppcb);
285+ ppcb.s = s;
286+ ppcb.p = p;
287+ ppcb.bPassPhraseDialogOnce = TRUE;
288+ ppcb.key_id = vhostid;
289+ ppcb.pkey_file = keyid;
290
291 if (!mc->szCryptoDevice) {
292 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10131)
293@@ -603,11 +829,6 @@ apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p,
294 return ssl_die(s);
295 }
296
297- /*
298- * Using the builtin OpenSSL UI only, for now...
299- */
300- ui_method = UI_OpenSSL();
301-
302 if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
303 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10132)
304 "Init: Failed to load Crypto Device API `%s'",
305@@ -636,7 +857,7 @@ apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p,
306 *pubkey = params.cert;
307 }
308
309- *privkey = ENGINE_load_private_key(e, keyid, ui_method, NULL);
310+ *privkey = ENGINE_load_private_key(e, keyid, ui_method, &ppcb);
311 if (*privkey == NULL) {
312 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10133)
313 "Init: Unable to get the private key");
314diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
315index 1f629a46e3..8524c515ba 100644
316--- a/modules/ssl/ssl_private.h
317+++ b/modules/ssl/ssl_private.h
318@@ -994,6 +994,7 @@ apr_status_t ssl_load_encrypted_pkey(server_rec *, apr_pool_t *, int,
319 * key returned as *pkey. certid can be NULL, in which case *pubkey
320 * is not altered. Errors logged on failure. */
321 apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p,
322+ const char *vhostid,
323 const char *certid, const char *keyid,
324 X509 **pubkey, EVP_PKEY **privkey);
325
326--
3272.22.0
328
diff --git a/debian/patches/ubuntu/lp-1830728-mod_ssl-Add-support-for-loading-TLS-certificates-thr.patch b/debian/patches/ubuntu/lp-1830728-mod_ssl-Add-support-for-loading-TLS-certificates-thr.patch
0new file mode 100644329new file mode 100644
index 0000000..a07d8b9
--- /dev/null
+++ b/debian/patches/ubuntu/lp-1830728-mod_ssl-Add-support-for-loading-TLS-certificates-thr.patch
@@ -0,0 +1,207 @@
1From 9007b62ecc0ad59edb37ec5f267a08868064699c Mon Sep 17 00:00:00 2001
2From: Joe Orton <jorton@apache.org>
3Date: Tue, 8 May 2018 12:39:22 +0000
4Subject: [PATCH] mod_ssl: Add support for loading TLS certificates through the
5 PKCS#11 engine.
6
7* modules/ssl/ssl_util.c (modssl_is_engine_id): Renamed
8 from modssl_is_engine_key.
9
10* modules/ssl/ssl_engine_config.c (ssl_cmd_SSLCertificateKeyFile):
11 Adjust accordingly.
12 (ssl_cmd_SSLCertificateFile): Also allow ENGINE cert ids.
13
14* modules/ssl/ssl_engine_pphrase.c (modssl_load_engine_keypair):
15 Rename from modssl_load_engine_key; load certificate if
16 cert id is passed.
17
18* modules/ssl/ssl_engine_init.c (ssl_init_server_certs): Optionally
19 load the certificate from the engine as well.
20
21* docs/manual/: Update manual.
22
23
24git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1831168 13f79535-47bb-0310-9956-ffa450edef68
25
26Origin: backport, https://github.com/apache/httpd/commit/9007b62ecc0ad59edb37ec5f267a08868064699c
27Bug-Ubuntu: https://bugs.launchpad.net/bugs/1830728
28Last-Update: 2019-07-29
29
30---
31 modules/ssl/ssl_engine_config.c | 6 ++++--
32 modules/ssl/ssl_engine_init.c | 26 +++++++++++++++++++++++---
33 modules/ssl/ssl_engine_pphrase.c | 30 ++++++++++++++++++++++--------
34 modules/ssl/ssl_private.h | 15 +++++++++------
35 modules/ssl/ssl_util.c | 2 +-
36 8 files changed, 85 insertions(+), 27 deletions(-)
37
38--- a/modules/ssl/ssl_engine_config.c
39+++ b/modules/ssl/ssl_engine_config.c
40@@ -1008,7 +1008,9 @@ const char *ssl_cmd_SSLCACertificateFile
41 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
42 const char *err;
43
44- if ((err = ssl_cmd_check_file(cmd, &arg))) {
45+ /* Only check for non-ENGINE based certs. */
46+ if (!modssl_is_engine_id(arg)
47+ && (err = ssl_cmd_check_file(cmd, &arg))) {
48 return err;
49 }
50
51@@ -1044,7 +1046,7 @@ const char *ssl_cmd_SSLCADNRequestFile(c
52 const char *err;
53
54 /* Check keyfile exists for non-ENGINE keys. */
55- if (!modssl_is_engine_key(arg)
56+ if (!modssl_is_engine_id(arg)
57 && (err = ssl_cmd_check_file(cmd, &arg))) {
58 return err;
59 }
60--- a/modules/ssl/ssl_engine_init.c
61+++ b/modules/ssl/ssl_engine_init.c
62@@ -1229,13 +1229,17 @@ static apr_status_t ssl_init_server_cert
63 const char *));
64 i++) {
65 EVP_PKEY *pkey;
66+ const char *engine_certfile = NULL;
67
68 key_id = apr_psprintf(ptemp, "%s:%d", vhost_id, i);
69
70 ERR_clear_error();
71
72 /* first the certificate (public key) */
73- if (mctx->cert_chain) {
74+ if (modssl_is_engine_id(certfile)) {
75+ engine_certfile = certfile;
76+ }
77+ else if (mctx->cert_chain) {
78 if ((SSL_CTX_use_certificate_file(mctx->ssl_ctx, certfile,
79 SSL_FILETYPE_PEM) < 1)) {
80 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02561)
81@@ -1264,12 +1268,28 @@ static apr_status_t ssl_init_server_cert
82
83 ERR_clear_error();
84
85- if (modssl_is_engine_key(keyfile)) {
86+ if (modssl_is_engine_id(keyfile)) {
87 apr_status_t rv;
88
89- if ((rv = modssl_load_engine_pkey(s, ptemp, keyfile, &pkey))) {
90+ cert = NULL;
91+
92+ if ((rv = modssl_load_engine_keypair(s, ptemp, engine_certfile,
93+ keyfile, &cert, &pkey))) {
94 return rv;
95 }
96+
97+ if (cert) {
98+ if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) < 1) {
99+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO()
100+ "Failed to configure engine certificate %s, check %s",
101+ key_id, certfile);
102+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
103+ return APR_EGENERAL;
104+ }
105+
106+ /* SSL_CTX now owns the cert. */
107+ X509_free(cert);
108+ }
109
110 if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1) {
111 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10130)
112--- a/modules/ssl/ssl_engine_pphrase.c
113+++ b/modules/ssl/ssl_engine_pphrase.c
114@@ -616,11 +616,11 @@ int ssl_pphrase_Handle_CB(char *buf, int
115 }
116
117 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
118-apr_status_t modssl_load_engine_pkey(server_rec *s, apr_pool_t *p,
119- const char *keyid, EVP_PKEY **ppkey)
120+apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p,
121+ const char *certid, const char *keyid,
122+ X509 **pubkey, EVP_PKEY **privkey)
123 {
124 SSLModConfigRec *mc = myModConfig(s);
125- EVP_PKEY *pPrivateKey = NULL;
126 ENGINE *e;
127 UI_METHOD *ui_method;
128
129@@ -647,17 +647,31 @@ apr_status_t modssl_load_engine_pkey(ser
130 if (APLOGdebug(s)) {
131 ENGINE_ctrl_cmd_string(e, "VERBOSE", NULL, 0);
132 }
133-
134- pPrivateKey = ENGINE_load_private_key(e, keyid, ui_method, NULL);
135- if (pPrivateKey == NULL) {
136+
137+ if (certid) {
138+ struct {
139+ const char *cert_id;
140+ X509 *cert;
141+ } params = { certid, NULL };
142+
143+ if (!ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &params, NULL, 1)) {
144+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10136)
145+ "Init: Unable to get the certificate");
146+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
147+ return ssl_die(s);
148+ }
149+
150+ *pubkey = params.cert;
151+ }
152+
153+ *privkey = ENGINE_load_private_key(e, keyid, ui_method, NULL);
154+ if (*privkey == NULL) {
155 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10133)
156 "Init: Unable to get the private key");
157 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
158 return ssl_die(s);
159 }
160
161- *ppkey = pPrivateKey;
162-
163 ENGINE_free(e);
164
165 return APR_SUCCESS;
166--- a/modules/ssl/ssl_private.h
167+++ b/modules/ssl/ssl_private.h
168@@ -1001,10 +1001,13 @@ BOOL ssl_util_vhost_matches(cons
169 /** Pass Phrase Support */
170 apr_status_t ssl_load_encrypted_pkey(server_rec *, apr_pool_t *, int,
171 const char *, apr_array_header_t **);
172-/* Load private key from the configured ENGINE, returned as **pkey.
173- * Errors logged on failure. */
174-apr_status_t modssl_load_engine_pkey(server_rec *s, apr_pool_t *p,
175- const char *keyid, EVP_PKEY **ppkey);
176+
177+/* Load public and/or private key from the configured ENGINE. Private
178+ * key returned as *pkey. certid can be NULL, in which case *pubkey
179+ * is not altered. Errors logged on failure. */
180+apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p,
181+ const char *certid, const char *keyid,
182+ X509 **pubkey, EVP_PKEY **privkey);
183
184 /** Diffie-Hellman Parameter Support */
185 DH *ssl_dh_GetParamFromFile(const char *);
186@@ -1111,8 +1114,8 @@ DH *modssl_get_dh_params(unsigned keylen
187 int modssl_request_is_tls(const request_rec *r, SSLConnRec **sslconn);
188
189 /* Returns non-zero if the cert/key filename should be handled through
190- * the configure ENGINE. */
191-int modssl_is_engine_key(const char *name);
192+ * the configured ENGINE. */
193+int modssl_is_engine_id(const char *name);
194
195 int ssl_is_challenge(conn_rec *c, const char *servername,
196 X509 **pcert, EVP_PKEY **pkey);
197--- a/modules/ssl/ssl_util.c
198+++ b/modules/ssl/ssl_util.c
199@@ -481,7 +481,7 @@ void ssl_util_thread_id_setup(apr_pool_t
200
201 #endif /* #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API */
202
203-int modssl_is_engine_key(const char *name)
204+int modssl_is_engine_id(const char *name)
205 {
206 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
207 /* ### Can handle any other special ENGINE key names here? */
diff --git a/debian/patches/ubuntu/lp-1830728-mod_ssl-Add-support-for-loading-private-keys-from-EN.patch b/debian/patches/ubuntu/lp-1830728-mod_ssl-Add-support-for-loading-private-keys-from-EN.patch
0new file mode 100644208new file mode 100644
index 0000000..8fbf151
--- /dev/null
+++ b/debian/patches/ubuntu/lp-1830728-mod_ssl-Add-support-for-loading-private-keys-from-EN.patch
@@ -0,0 +1,185 @@
1From e71764a49d1276b8051b83e6ad346482f3e7bc06 Mon Sep 17 00:00:00 2001
2From: Joe Orton <jorton@apache.org>
3Date: Thu, 3 May 2018 13:06:46 +0000
4Subject: [PATCH] mod_ssl: Add support for loading private keys from ENGINEs.
5 Support for PKCS#11 URIs only, and PIN entry is not threaded through
6 SSLPassPhraseDialog config yet.
7
8* modules/ssl/ssl_util.c (modssl_is_engine_key): New function.
9
10* modules/ssl/ssl_engine_config.c (ssl_cmd_SSLCertificateKeyFile):
11 Use it, skip check for file existence for engine keys.
12
13* modules/ssl/ssl_engine_pphrase.c (modssl_load_engine_pkey):
14 New function.
15
16* modules/ssl/ssl_engine_init.c (ssl_init_server_certs):
17 For engine keys, load via modssl_load_engine_pkey.
18
19Submitted by: Anderson Sasaki <ansasaki redhat.com>, jorton
20
21
22git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1830819 13f79535-47bb-0310-9956-ffa450edef68
23
24Origin: backport, https://github.com/apache/httpd/commit/e71764a49d1276b8051b83e6ad346482f3e7bc06
25Last-Update: 2019-07-29
26
27---
28 modules/ssl/ssl_engine_config.c | 4 ++-
29 modules/ssl/ssl_engine_init.c | 26 ++++++++++++----
30 modules/ssl/ssl_engine_pphrase.c | 49 +++++++++++++++++++++++++++++++
31 modules/ssl/ssl_private.h | 8 +++++
32 modules/ssl/ssl_util.c | 10 +++++++
33 8 files changed, 112 insertions(+), 10 deletions(-)
34
35--- a/modules/ssl/ssl_engine_config.c
36+++ b/modules/ssl/ssl_engine_config.c
37@@ -1043,7 +1043,9 @@ const char *ssl_cmd_SSLCADNRequestFile(c
38 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
39 const char *err;
40
41- if ((err = ssl_cmd_check_file(cmd, &arg))) {
42+ /* Check keyfile exists for non-ENGINE keys. */
43+ if (!modssl_is_engine_key(arg)
44+ && (err = ssl_cmd_check_file(cmd, &arg))) {
45 return err;
46 }
47
48--- a/modules/ssl/ssl_engine_init.c
49+++ b/modules/ssl/ssl_engine_init.c
50@@ -1228,6 +1228,8 @@ static apr_status_t ssl_init_server_cert
51 (certfile = APR_ARRAY_IDX(mctx->pks->cert_files, i,
52 const char *));
53 i++) {
54+ EVP_PKEY *pkey;
55+
56 key_id = apr_psprintf(ptemp, "%s:%d", vhost_id, i);
57
58 ERR_clear_error();
59@@ -1262,12 +1264,26 @@ static apr_status_t ssl_init_server_cert
60
61 ERR_clear_error();
62
63- if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile,
64- SSL_FILETYPE_PEM) < 1) &&
65- (ERR_GET_FUNC(ERR_peek_last_error())
66- != X509_F_X509_CHECK_PRIVATE_KEY)) {
67+ if (modssl_is_engine_key(keyfile)) {
68+ apr_status_t rv;
69+
70+ if ((rv = modssl_load_engine_pkey(s, ptemp, keyfile, &pkey))) {
71+ return rv;
72+ }
73+
74+ if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1) {
75+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10130)
76+ "Failed to configure private key %s from engine",
77+ keyfile);
78+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
79+ return APR_EGENERAL;
80+ }
81+ }
82+ else if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile,
83+ SSL_FILETYPE_PEM) < 1)
84+ && (ERR_GET_FUNC(ERR_peek_last_error())
85+ != X509_F_X509_CHECK_PRIVATE_KEY)) {
86 ssl_asn1_t *asn1;
87- EVP_PKEY *pkey;
88 const unsigned char *ptr;
89
90 ERR_clear_error();
91--- a/modules/ssl/ssl_engine_pphrase.c
92+++ b/modules/ssl/ssl_engine_pphrase.c
93@@ -614,3 +614,52 @@ int ssl_pphrase_Handle_CB(char *buf, int
94 */
95 return (len);
96 }
97+
98+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
99+apr_status_t modssl_load_engine_pkey(server_rec *s, apr_pool_t *p,
100+ const char *keyid, EVP_PKEY **ppkey)
101+{
102+ SSLModConfigRec *mc = myModConfig(s);
103+ EVP_PKEY *pPrivateKey = NULL;
104+ ENGINE *e;
105+ UI_METHOD *ui_method;
106+
107+ if (!mc->szCryptoDevice) {
108+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10131)
109+ "Init: Cannot load private key `%s' without engine",
110+ keyid);
111+ return ssl_die(s);
112+ }
113+
114+ /*
115+ * Using the builtin OpenSSL UI only, for now...
116+ */
117+ ui_method = UI_OpenSSL();
118+
119+ if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
120+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10132)
121+ "Init: Failed to load Crypto Device API `%s'",
122+ mc->szCryptoDevice);
123+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
124+ return ssl_die(s);
125+ }
126+
127+ if (APLOGdebug(s)) {
128+ ENGINE_ctrl_cmd_string(e, "VERBOSE", NULL, 0);
129+ }
130+
131+ pPrivateKey = ENGINE_load_private_key(e, keyid, ui_method, NULL);
132+ if (pPrivateKey == NULL) {
133+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10133)
134+ "Init: Unable to get the private key");
135+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
136+ return ssl_die(s);
137+ }
138+
139+ *ppkey = pPrivateKey;
140+
141+ ENGINE_free(e);
142+
143+ return APR_SUCCESS;
144+}
145+#endif
146--- a/modules/ssl/ssl_private.h
147+++ b/modules/ssl/ssl_private.h
148@@ -1001,6 +1001,10 @@ BOOL ssl_util_vhost_matches(cons
149 /** Pass Phrase Support */
150 apr_status_t ssl_load_encrypted_pkey(server_rec *, apr_pool_t *, int,
151 const char *, apr_array_header_t **);
152+/* Load private key from the configured ENGINE, returned as **pkey.
153+ * Errors logged on failure. */
154+apr_status_t modssl_load_engine_pkey(server_rec *s, apr_pool_t *p,
155+ const char *keyid, EVP_PKEY **ppkey);
156
157 /** Diffie-Hellman Parameter Support */
158 DH *ssl_dh_GetParamFromFile(const char *);
159@@ -1106,6 +1110,10 @@ DH *modssl_get_dh_params(unsigned keylen
160 * corresponding SSLConnRec structure for the connection. */
161 int modssl_request_is_tls(const request_rec *r, SSLConnRec **sslconn);
162
163+/* Returns non-zero if the cert/key filename should be handled through
164+ * the configure ENGINE. */
165+int modssl_is_engine_key(const char *name);
166+
167 int ssl_is_challenge(conn_rec *c, const char *servername,
168 X509 **pcert, EVP_PKEY **pkey);
169
170--- a/modules/ssl/ssl_util.c
171+++ b/modules/ssl/ssl_util.c
172@@ -480,3 +480,13 @@ void ssl_util_thread_id_setup(apr_pool_t
173 }
174
175 #endif /* #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API */
176+
177+int modssl_is_engine_key(const char *name)
178+{
179+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
180+ /* ### Can handle any other special ENGINE key names here? */
181+ return strncmp(name, "pkcs11:", 7) == 0;
182+#else
183+ return 0;
184+#endif
185+}

Subscribers

People subscribed via source and target branches