Hello community, here is the log from the commit of package apache2 for openSUSE:Factory checked in at 2019-10-25 18:38:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/apache2 (Old) and /work/SRC/openSUSE:Factory/.apache2.new.2990 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "apache2" Fri Oct 25 18:38:19 2019 rev:161 rq:741682 version:2.4.41 Changes: -------- --- /work/SRC/openSUSE:Factory/apache2/apache2.changes 2019-10-14 12:31:02.672340325 +0200 +++ /work/SRC/openSUSE:Factory/.apache2.new.2990/apache2.changes 2019-10-25 18:38:20.683682706 +0200 @@ -1,0 +2,10 @@ +Tue Oct 22 07:01:23 UTC 2019 - pgaj...@suse.com + +- load private keys and certificates from pkcs11 token [SLE-7653] +- added patches + load certificates from openssl engine + + apache2-load-certificates-from-pkcs11.patch + load private keys from openssl engine + + apache2-load-private-keys-from-pkcs11.patch + +------------------------------------------------------------------- New: ---- apache2-load-certificates-from-pkcs11.patch apache2-load-private-keys-from-pkcs11.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ apache2.spec ++++++ --- /var/tmp/diff_new_pack.X5dmyR/_old 2019-10-25 18:38:21.695683659 +0200 +++ /var/tmp/diff_new_pack.X5dmyR/_new 2019-10-25 18:38:21.695683659 +0200 @@ -146,6 +146,10 @@ # PATCH-FEATURE-UPSTREAM kstreit...@suse.com -- backport of HttpContentLengthHeadZero and HttpExpectStrict Patch115: httpd-2.4.x-fate317766-config-control-two-protocol-options.diff Patch116: deprecated-scripts-arch.patch +# load private keys from openssl engine +Patch117: apache2-load-private-keys-from-pkcs11.patch +# load certificates from openssl engine +Patch118: apache2-load-certificates-from-pkcs11.patch BuildRequires: apache-rpm-macros-control BuildRequires: apr-util-devel #Since 2.4.7 the event MPM requires apr 1.5.0 or later. @@ -338,6 +342,8 @@ %if 0%{?suse_version} == 1110 %patch116 -p1 %endif +%patch117 -p1 +%patch118 -p1 cat %{_sourcedir}/SUSE-NOTICE >> NOTICE # install READMEs a=$(basename %{SOURCE22}) ++++++ apache2-load-certificates-from-pkcs11.patch ++++++ Index: httpd-2.4.41/modules/ssl/ssl_util.c =================================================================== --- httpd-2.4.41.orig/modules/ssl/ssl_util.c 2019-10-21 21:29:44.081536735 +0200 +++ httpd-2.4.41/modules/ssl/ssl_util.c 2019-10-21 21:29:44.093536806 +0200 @@ -481,7 +481,7 @@ void ssl_util_thread_id_setup(apr_pool_t #endif /* #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API */ -int modssl_is_engine_key(const char *name) +int modssl_is_engine_id(const char *name) { #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) /* ### Can handle any other special ENGINE key names here? */ Index: httpd-2.4.41/modules/ssl/ssl_engine_config.c =================================================================== --- httpd-2.4.41.orig/modules/ssl/ssl_engine_config.c 2019-10-21 21:29:44.081536735 +0200 +++ httpd-2.4.41/modules/ssl/ssl_engine_config.c 2019-10-21 21:31:14.970078134 +0200 @@ -916,7 +916,9 @@ const char *ssl_cmd_SSLCertificateFile(c SSLSrvConfigRec *sc = mySrvConfig(cmd->server); const char *err; - if ((err = ssl_cmd_check_file(cmd, &arg))) { + /* Only check for non-ENGINE based certs. */ + if (!modssl_is_engine_id(arg) + && (err = ssl_cmd_check_file(cmd, &arg))) { return err; } @@ -933,7 +935,7 @@ const char *ssl_cmd_SSLCertificateKeyFil const char *err; /* Check keyfile exists for non-ENGINE keys. */ - if (!modssl_is_engine_key(arg) + if (!modssl_is_engine_id(arg) && (err = ssl_cmd_check_file(cmd, &arg))) { return err; } Index: httpd-2.4.41/modules/ssl/ssl_engine_init.c =================================================================== --- httpd-2.4.41.orig/modules/ssl/ssl_engine_init.c 2019-10-21 21:29:44.081536735 +0200 +++ httpd-2.4.41/modules/ssl/ssl_engine_init.c 2019-10-21 21:29:44.097536830 +0200 @@ -1248,13 +1248,17 @@ static apr_status_t ssl_init_server_cert const char *)); i++) { EVP_PKEY *pkey; + const char *engine_certfile = NULL; key_id = apr_psprintf(ptemp, "%s:%d", vhost_id, i); ERR_clear_error(); /* first the certificate (public key) */ - if (mctx->cert_chain) { + if (modssl_is_engine_id(certfile)) { + engine_certfile = certfile; + } + else if (mctx->cert_chain) { if ((SSL_CTX_use_certificate_file(mctx->ssl_ctx, certfile, SSL_FILETYPE_PEM) < 1)) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02561) @@ -1283,13 +1287,28 @@ static apr_status_t ssl_init_server_cert ERR_clear_error(); - if (modssl_is_engine_key(keyfile)) { + if (modssl_is_engine_id(keyfile)) { apr_status_t rv; - if ((rv = modssl_load_engine_pkey(s, ptemp, keyfile, &pkey))) { + cert = NULL; + if ((rv = modssl_load_engine_keypair(s, ptemp, engine_certfile, + keyfile, &cert, &pkey))) { return rv; } + if (cert) { + if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) < 1) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() + "Failed to configure engine certificate %s, check %s", + key_id, certfile); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return APR_EGENERAL; + } + + /* SSL_CTX now owns the cert. */ + X509_free(cert); + } + if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10130) "Failed to configure private key %s from engine", Index: httpd-2.4.41/modules/ssl/ssl_engine_pphrase.c =================================================================== --- httpd-2.4.41.orig/modules/ssl/ssl_engine_pphrase.c 2019-10-21 21:29:44.081536735 +0200 +++ httpd-2.4.41/modules/ssl/ssl_engine_pphrase.c 2019-10-21 21:29:44.097536830 +0200 @@ -616,11 +616,11 @@ int ssl_pphrase_Handle_CB(char *buf, int } #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) -apr_status_t modssl_load_engine_pkey(server_rec *s, apr_pool_t *p, - const char *keyid, EVP_PKEY **ppkey) +apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p, + const char *certid, const char *keyid, + X509 **pubkey, EVP_PKEY **privkey) { SSLModConfigRec *mc = myModConfig(s); - EVP_PKEY *pPrivateKey = NULL; ENGINE *e; UI_METHOD *ui_method; @@ -648,16 +648,30 @@ apr_status_t modssl_load_engine_pkey(ser ENGINE_ctrl_cmd_string(e, "VERBOSE", NULL, 0); } - pPrivateKey = ENGINE_load_private_key(e, keyid, ui_method, NULL); - if (pPrivateKey == NULL) { + if (certid) { + struct { + const char *cert_id; + X509 *cert; + } params = { certid, NULL }; + + if (!ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10136) + "Init: Unable to get the certificate"); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return ssl_die(s); + } + + *pubkey = params.cert; + } + + *privkey = ENGINE_load_private_key(e, keyid, ui_method, NULL); + if (*privkey == NULL) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10133) "Init: Unable to get the private key"); ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); return ssl_die(s); } - *ppkey = pPrivateKey; - ENGINE_free(e); return APR_SUCCESS; Index: httpd-2.4.41/modules/ssl/ssl_private.h =================================================================== --- httpd-2.4.41.orig/modules/ssl/ssl_private.h 2019-10-21 21:29:44.081536735 +0200 +++ httpd-2.4.41/modules/ssl/ssl_private.h 2019-10-21 21:29:44.097536830 +0200 @@ -1001,10 +1001,13 @@ BOOL ssl_util_vhost_matches(cons /** Pass Phrase Support */ apr_status_t ssl_load_encrypted_pkey(server_rec *, apr_pool_t *, int, const char *, apr_array_header_t **); -/* Load private key from the configured ENGINE, returned as **pkey. - * Errors logged on failure. */ -apr_status_t modssl_load_engine_pkey(server_rec *s, apr_pool_t *p, - const char *keyid, EVP_PKEY **ppkey); + +/* Load public and/or private key from the configured ENGINE. Private + * key returned as *pkey. certid can be NULL, in which case *pubkey + * is not altered. Errors logged on failure. */ +apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p, + const char *certid, const char *keyid, + X509 **pubkey, EVP_PKEY **privkey); /** Diffie-Hellman Parameter Support */ DH *ssl_dh_GetParamFromFile(const char *); @@ -1111,8 +1114,8 @@ DH *modssl_get_dh_params(unsigned keylen int modssl_request_is_tls(const request_rec *r, SSLConnRec **sslconn); /* Returns non-zero if the cert/key filename should be handled through - * the configure ENGINE. */ -int modssl_is_engine_key(const char *name); + * the configured ENGINE. */ +int modssl_is_engine_id(const char *name); int ssl_is_challenge(conn_rec *c, const char *servername, X509 **pcert, EVP_PKEY **pkey); ++++++ apache2-load-private-keys-from-pkcs11.patch ++++++ Index: httpd-2.4.41/modules/ssl/ssl_engine_config.c =================================================================== --- httpd-2.4.41.orig/modules/ssl/ssl_engine_config.c 2018-10-18 12:06:37.000000000 +0200 +++ httpd-2.4.41/modules/ssl/ssl_engine_config.c 2019-10-21 21:20:32.102340905 +0200 @@ -932,7 +932,9 @@ const char *ssl_cmd_SSLCertificateKeyFil SSLSrvConfigRec *sc = mySrvConfig(cmd->server); const char *err; - if ((err = ssl_cmd_check_file(cmd, &arg))) { + /* Check keyfile exists for non-ENGINE keys. */ + if (!modssl_is_engine_key(arg) + && (err = ssl_cmd_check_file(cmd, &arg))) { return err; } Index: httpd-2.4.41/modules/ssl/ssl_engine_init.c =================================================================== --- httpd-2.4.41.orig/modules/ssl/ssl_engine_init.c 2019-08-06 14:16:14.000000000 +0200 +++ httpd-2.4.41/modules/ssl/ssl_engine_init.c 2019-10-21 21:20:32.102340905 +0200 @@ -1247,6 +1247,8 @@ static apr_status_t ssl_init_server_cert (certfile = APR_ARRAY_IDX(mctx->pks->cert_files, i, const char *)); i++) { + EVP_PKEY *pkey; + key_id = apr_psprintf(ptemp, "%s:%d", vhost_id, i); ERR_clear_error(); @@ -1281,12 +1283,26 @@ static apr_status_t ssl_init_server_cert ERR_clear_error(); - if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile, - SSL_FILETYPE_PEM) < 1) && - (ERR_GET_FUNC(ERR_peek_last_error()) - != X509_F_X509_CHECK_PRIVATE_KEY)) { + if (modssl_is_engine_key(keyfile)) { + apr_status_t rv; + + if ((rv = modssl_load_engine_pkey(s, ptemp, keyfile, &pkey))) { + return rv; + } + + if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10130) + "Failed to configure private key %s from engine", + keyfile); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return APR_EGENERAL; + } + } + else if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile, + SSL_FILETYPE_PEM) < 1) + && (ERR_GET_FUNC(ERR_peek_last_error()) + != X509_F_X509_CHECK_PRIVATE_KEY)) { ssl_asn1_t *asn1; - EVP_PKEY *pkey; const unsigned char *ptr; ERR_clear_error(); Index: httpd-2.4.41/modules/ssl/ssl_engine_pphrase.c =================================================================== --- httpd-2.4.41.orig/modules/ssl/ssl_engine_pphrase.c 2018-12-11 15:14:40.000000000 +0100 +++ httpd-2.4.41/modules/ssl/ssl_engine_pphrase.c 2019-10-21 21:20:32.102340905 +0200 @@ -614,3 +614,52 @@ int ssl_pphrase_Handle_CB(char *buf, int */ return (len); } + +#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) +apr_status_t modssl_load_engine_pkey(server_rec *s, apr_pool_t *p, + const char *keyid, EVP_PKEY **ppkey) +{ + SSLModConfigRec *mc = myModConfig(s); + EVP_PKEY *pPrivateKey = NULL; + ENGINE *e; + UI_METHOD *ui_method; + + if (!mc->szCryptoDevice) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10131) + "Init: Cannot load private key `%s' without engine", + keyid); + return ssl_die(s); + } + + /* + * Using the builtin OpenSSL UI only, for now... + */ + ui_method = UI_OpenSSL(); + + if (!(e = ENGINE_by_id(mc->szCryptoDevice))) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10132) + "Init: Failed to load Crypto Device API `%s'", + mc->szCryptoDevice); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return ssl_die(s); + } + + if (APLOGdebug(s)) { + ENGINE_ctrl_cmd_string(e, "VERBOSE", NULL, 0); + } + + pPrivateKey = ENGINE_load_private_key(e, keyid, ui_method, NULL); + if (pPrivateKey == NULL) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10133) + "Init: Unable to get the private key"); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + return ssl_die(s); + } + + *ppkey = pPrivateKey; + + ENGINE_free(e); + + return APR_SUCCESS; +} +#endif Index: httpd-2.4.41/modules/ssl/ssl_private.h =================================================================== --- httpd-2.4.41.orig/modules/ssl/ssl_private.h 2018-11-23 16:10:24.000000000 +0100 +++ httpd-2.4.41/modules/ssl/ssl_private.h 2019-10-21 21:20:32.102340905 +0200 @@ -1001,6 +1001,10 @@ BOOL ssl_util_vhost_matches(cons /** Pass Phrase Support */ apr_status_t ssl_load_encrypted_pkey(server_rec *, apr_pool_t *, int, const char *, apr_array_header_t **); +/* Load private key from the configured ENGINE, returned as **pkey. + * Errors logged on failure. */ +apr_status_t modssl_load_engine_pkey(server_rec *s, apr_pool_t *p, + const char *keyid, EVP_PKEY **ppkey); /** Diffie-Hellman Parameter Support */ DH *ssl_dh_GetParamFromFile(const char *); @@ -1106,6 +1110,10 @@ DH *modssl_get_dh_params(unsigned keylen * corresponding SSLConnRec structure for the connection. */ int modssl_request_is_tls(const request_rec *r, SSLConnRec **sslconn); +/* Returns non-zero if the cert/key filename should be handled through + * the configure ENGINE. */ +int modssl_is_engine_key(const char *name); + int ssl_is_challenge(conn_rec *c, const char *servername, X509 **pcert, EVP_PKEY **pkey); Index: httpd-2.4.41/modules/ssl/ssl_util.c =================================================================== --- httpd-2.4.41.orig/modules/ssl/ssl_util.c 2018-11-23 16:10:24.000000000 +0100 +++ httpd-2.4.41/modules/ssl/ssl_util.c 2019-10-21 21:20:32.106340927 +0200 @@ -480,3 +480,13 @@ void ssl_util_thread_id_setup(apr_pool_t } #endif /* #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API */ + +int modssl_is_engine_key(const char *name) +{ +#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) + /* ### Can handle any other special ENGINE key names here? */ + return strncmp(name, "pkcs11:", 7) == 0; +#else + return 0; +#endif +}