From 612126365b2097e124748f7fd002e996c1b2f3f4 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 27 2021 04:56:20 +0000 Subject: import pki-core-10.10.5-2.module+el8.4.0+10466+9830f79e --- diff --git a/SOURCES/0001-Fix-renewal-profile-approval-process.patch b/SOURCES/0001-Fix-renewal-profile-approval-process.patch new file mode 100644 index 0000000..2aa7f35 --- /dev/null +++ b/SOURCES/0001-Fix-renewal-profile-approval-process.patch @@ -0,0 +1,170 @@ +From 608e9bbe537aba314b124ceef70f9b606ab7e121 Mon Sep 17 00:00:00 2001 +From: Fraser Tweedale +Date: Wed, 13 Jan 2021 18:27:46 +1100 +Subject: [PATCH] Fix renewal profile approval process + +Due to a recent change in PKI CLI, the CLI now passes along user +authentication with submissions to the renewal endpoint. Unlike the EE +pages, the REST API has passed along this authentication for a while. +Due to a bug in the RenewalProcessor, requests with credentials against +profiles with no authentication method and no ACLs result in the +certificiate automatically being approved. This occurs because, when +an earlier commit (cb9eb967b5e24f5fde8bbf8ae87aa615b7033db7) modified +the code to allow Light-Weight SubCAs to issue certificates, validation +wasn't done on the passed principal, to see if it was a trusted agent. +Because profiles requring Agent approval have an empty ACL list (as, no +user should be able to submit a certificate request and have it +automatically signed without agent approval), authorize allows any user +to approve this request and thus accepts the AuthToken. + +Critical analysis: the RenewalProcessor code interprets (authToken +!= null) as evidence that the authenticated user is /authorized/ to +immediately issue the certificate. This mismatch of concerns (authn +vs authz) resulted in a misunderstanding of system behaviour. The +"latent" AuthToken (from the HTTP request) was assigned to authToken +without realising that authorization needed to be performed. + +We fix this by splitting the logic on whether the profile defines an +authenticator. If so, we (re)authenticate and authorize the user +according to the profile configuration. + +If the profile does not define an authenticator but there is a +principal in the HTTP request, if (and only if) the user has +permission to approve certificate requests *and* the requested +renewal profile is caManualRenewal (which is hardcoded to be used +for LWCA renewal), then we issue the certificate immediately. This +special case ensures that LWCA renewal keeps working. + +Otherwise, if there is no principal in the HTTP request or the +principal does not have permission to approve certificate requests, +we leave the authToken unset. The resulting renewal request will be +created with status PENDING, i.e. enqueued for agent review. + +Signed-off-by: Fraser Tweedale +Signed-off-by: Alexander Scheel +--- + .../com/netscape/ca/CertificateAuthority.java | 10 +++ + .../cms/servlet/cert/RenewalProcessor.java | 75 +++++++++++++++++-- + 2 files changed, 79 insertions(+), 6 deletions(-) + +diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java +index 560507168a..431ce9ff78 100644 +--- a/base/ca/src/com/netscape/ca/CertificateAuthority.java ++++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java +@@ -1929,6 +1929,16 @@ public class CertificateAuthority + } + + ProfileSubsystem ps = engine.getProfileSubsystem(); ++ /* NOTE: hard-coding the profile to use for Lightweight CA renewal ++ * might be OK, but caManualRenewal was not the right one to use. ++ * As a consequence, we have an undesirable special case in ++ * RenewalProcessor.processRenewal(). ++ * ++ * We should introduce a new profile specifically for LWCA renewal, ++ * with an authenticator and ACLs to match the authz requirements ++ * for the renewAuthority REST resource itself. Then we can use ++ * it here, and remove the workaround from RenewalProcessor. ++ */ + Profile profile = ps.getProfile("caManualRenewal"); + CertEnrollmentRequest req = CertEnrollmentRequestFactory.create( + new ArgBlock(), profile, httpReq.getLocale()); +diff --git a/base/ca/src/com/netscape/cms/servlet/cert/RenewalProcessor.java b/base/ca/src/com/netscape/cms/servlet/cert/RenewalProcessor.java +index 4293cdd064..fd20f48267 100644 +--- a/base/ca/src/com/netscape/cms/servlet/cert/RenewalProcessor.java ++++ b/base/ca/src/com/netscape/cms/servlet/cert/RenewalProcessor.java +@@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletRequest; + + import org.apache.commons.lang3.StringUtils; + import org.dogtagpki.server.ca.CAEngine; ++import org.dogtagpki.server.authorization.AuthzToken; + import org.mozilla.jss.netscape.security.x509.BasicConstraintsExtension; + import org.mozilla.jss.netscape.security.x509.X509CertImpl; + +@@ -267,16 +268,78 @@ public class RenewalProcessor extends CertProcessor { + + // before creating the request, authenticate the request + IAuthToken authToken = null; +- Principal principal = request.getUserPrincipal(); +- if (principal instanceof PKIPrincipal) +- authToken = ((PKIPrincipal) principal).getAuthToken(); +- if (authToken == null && authenticator != null) { +- authToken = authenticate(request, origReq, authenticator, context, true, credentials); ++ ++ if (authenticator != null) { ++ /* The profile specifies an authenticator. Use it to ++ * authenticate the user. Ignore the "latent" session ++ * principal (if any). ++ */ ++ authToken = authenticate( ++ request, ++ origReq, ++ authenticator, ++ context, ++ true /* isRenewal */, ++ credentials); ++ } else { ++ /* When authenticator is null, we expect manual agent ++ * review (leave authToken as null). ++ * ++ * But as a special case to ensure Lightweight CA (LWCA) ++ * renewal works, if there is a latent user in the HTTP ++ * request, we use that user (i.e. set authToken to the ++ * principal's IAuthToken) if and only if: ++ * ++ * - The renewal profile is caManualRenewal (LWCA renewal ++ * is hardcoded to use this profile); AND ++ * ++ * - The latent user is authorized to "execute" ++ * certificate requests (i.e. agent approval) ++ * ++ * See also CertificateAuthority.renewAuthority(). ++ */ ++ ++ Principal principal = request.getUserPrincipal(); ++ if ( ++ renewProfileId.equals("caManualRenewal") ++ && principal instanceof PKIPrincipal ++ ) { ++ IAuthToken latentToken = ((PKIPrincipal) principal).getAuthToken(); ++ AuthzToken authzToken = authorize( ++ "DirAclAuthz", latentToken, "certServer.ca.certrequests", "execute"); ++ if (authzToken != null) { ++ // Success (no exception); user is authorized to approve ++ // cert requests. Set the authToken. ++ // ++ // NOTE: This authz does not replace or subsume the ++ // profile-specific authz check below. ++ authToken = latentToken; ++ } else { ++ // leave authToken as null to enqueue a pending request. ++ } ++ } else { ++ // not caManualRenewal or no latent principal; ++ // leave authToken as null to enqueue a pending request. ++ } + } + +- // authentication success, now authorize ++ /* Authorize the request. ++ * ++ * If authToken != null, it will be checked against ACLs specified ++ * in the profile (if any). If ACLs are defined and authToken does ++ * not match, throws an authorization exception. ++ * ++ * If authToken == null, no check is performed (even if the profile ++ * defines ACLs). This is fine, because null authToken will cause ++ * the request status to be 'pending' [agent approval]. ++ */ + authorize(profileId, renewProfile, authToken); + ++ /* At this point, the request will be created. If authToken ++ * is non-null, then the certificate will be issued ++ * immediately. Otherwise the request will be pending. */ ++ ++ + /////////////////////////////////////////////// + // create and populate requests + /////////////////////////////////////////////// +-- +2.26.2 + diff --git a/SPECS/pki-core.spec b/SPECS/pki-core.spec index a23ca6b..05309bb 100644 --- a/SPECS/pki-core.spec +++ b/SPECS/pki-core.spec @@ -13,7 +13,7 @@ License: GPLv2 and LGPLv2 # For development (i.e. unsupported) releases, use x.y.z-0.n.. # For official (i.e. supported) releases, use x.y.z-r where r >=1. Version: 10.10.5 -Release: 1%{?_timestamp}%{?_commit_id}%{?dist} +Release: 2%{?_timestamp}%{?_commit_id}%{?dist} #global _phase -beta1 # To create a tarball from a version tag: @@ -36,6 +36,15 @@ Source: https://github.com/dogtagpki/pki/archive/v%{version}%{?_phase}/pki-%{ver # BUILDSTDERR: Download error on https://pypi.org/simple/pytest-runner/: # [Errno 111] Connection refused -- Some packages may not be found! Patch1: 0001-Removed-dependency-on-pytest-runner.patch +Patch2: 0001-Fix-renewal-profile-approval-process.patch + +# md2man isn't available on i686. Additionally, we aren't generally multi-lib +# compatible (https://fedoraproject.org/wiki/Packaging:Java) +# so dropping i686 everywhere but RHEL-8 (which we've already shipped) seems +# safest. +%if ! 0%{?rhel} || 0%{?rhel} > 8 +ExcludeArch: i686 +%endif ################################################################################ # NSS @@ -47,7 +56,7 @@ Patch1: 0001-Removed-dependency-on-pytest-runner.patch # Python ################################################################################ -%if 0%{?rhel} +%if 0%{?rhel} && 0%{?rhel} <= 8 %global python_executable /usr/libexec/platform-python %else %global python_executable /usr/bin/python3 @@ -60,7 +69,7 @@ Patch1: 0001-Removed-dependency-on-pytest-runner.patch %define java_devel java-devel %define java_headless java-headless -%if 0%{?fedora} && 0%{?fedora} >= 33 +%if 0%{?fedora} >= 33 || 0%{?rhel} > 8 %define min_java_version 1:11 %define java_home /usr/lib/jvm/java-11-openjdk %else @@ -204,7 +213,7 @@ BuildRequires: velocity BuildRequires: xalan-j2 BuildRequires: xerces-j2 -%if 0%{?rhel} +%if 0%{?rhel} && ! 0%{?eln} BuildRequires: resteasy >= 3.0.26 %else BuildRequires: jboss-annotations-1.2-api @@ -228,9 +237,7 @@ BuildRequires: python3-nss BuildRequires: python3-requests >= 2.6.0 BuildRequires: python3-six -%if 0%{?rhel} -# no python3-pytest-runner -%else +%if 0%{?fedora} || 0%{?rhel} > 8 BuildRequires: python3-pytest-runner %endif @@ -245,7 +252,7 @@ BuildRequires: jna %endif BuildRequires: systemd-units -%if 0%{?rhel} +%if 0%{?rhel} && ! 0%{?eln} BuildRequires: pki-servlet-engine %else BuildRequires: tomcat >= 1:9.0.7 @@ -263,7 +270,7 @@ BuildRequires: zlib BuildRequires: zlib-devel # build dependency to build man pages -%if 0%{?fedora} && 0%{?fedora} <= 30 || 0%{?rhel} +%if 0%{?fedora} && 0%{?fedora} <= 30 || 0%{?rhel} && 0%{?rhel} <= 8 BuildRequires: go-md2man %else BuildRequires: golang-github-cpuguy83-md2man @@ -327,8 +334,10 @@ Requires: pki-console = %{version} Requires: pki-javadoc = %{version} # Make certain that this 'meta' package requires the latest version(s) -# of ALL PKI clients +# of ALL PKI clients -- except for s390/s390x where 'esc' is not built +%ifnarch s390 s390x Requires: esc >= 1.1.1 +%endif # description for top-level package (unless there is a separate meta package) %if "%{name}" == "%{vendor_id}-pki" @@ -405,7 +414,7 @@ BuildArch: noarch Obsoletes: pki-base-python3 < %{version} Provides: pki-base-python3 = %{version} -%if 0%{?fedora} +%if 0%{?fedora} || 0%{?rhel} > 8 %{?python_provide:%python_provide python3-pki} %endif @@ -444,7 +453,7 @@ Requires: jss >= 4.7.0 Requires: ldapjdk >= 4.22.0 Requires: pki-base = %{version}-%{release} -%if 0%{?rhel} +%if 0%{?rhel} && 0%{?rhel} <= 8 Requires: resteasy >= 3.0.26 %else Requires: resteasy-atom-provider >= 3.0.17-1 @@ -454,7 +463,7 @@ Requires: resteasy-core >= 3.0.17-1 Requires: resteasy-jackson2-provider >= 3.0.17-1 %endif -%if 0%{?fedora} && 0%{?fedora} >= 33 +%if 0%{?fedora} >= 33 || 0%{?rhel} > 8 Requires: jaxb-impl >= 2.3.3 Requires: jakarta-activation >= 1.2.2 %endif @@ -517,8 +526,8 @@ Requires: python3-policycoreutils Requires: selinux-policy-targeted >= 3.13.1-159 -%if 0%{?rhel} -Requires: pki-servlet-engine >= 1:9.0.7 +%if 0%{?rhel} && ! 0%{?eln} +Requires: pki-servlet-engine %else Requires: tomcat >= 1:9.0.7 %endif @@ -865,7 +874,7 @@ java_version=`echo $java_version | sed -e 's/^1\.//' -e 's/\..*$//'` # assume tomcat app_server app_server=tomcat-8.5 -%if 0%{?rhel} +%if 0%{?rhel} && 0%{?rhel} <= 8 %{__mkdir_p} build cd build %endif @@ -900,13 +909,13 @@ cd build -DWITH_TEST:BOOL=%{?with_test:ON}%{!?with_test:OFF} \ -DBUILD_PKI_CONSOLE:BOOL=%{?with_console:ON}%{!?with_console:OFF} \ -DTHEME=%{?with_theme:%{vendor_id}} \ -%if 0%{?rhel} +%if 0%{?rhel} && 0%{?rhel} <= 8 .. %else -B %{_vpath_builddir} %endif -%if 0%{?fedora} +%if 0%{?fedora} || 0%{?rhel} > 8 cd %{_vpath_builddir} %endif @@ -923,7 +932,7 @@ cd %{_vpath_builddir} %install ################################################################################ -%if 0%{?rhel} +%if 0%{?rhel} && 0%{?rhel} <= 8 cd build %else cd %{_vpath_builddir} @@ -1191,9 +1200,8 @@ fi %{_sbindir}/pkidestroy %{_sbindir}/pki-server %{_sbindir}/pki-server-upgrade -%{python3_sitelib}/pki/server/ %{_sbindir}/pki-healthcheck -%{python3_sitelib}/pki/server/healthcheck/ +%{python3_sitelib}/pki/server/ %{python3_sitelib}/pkihealthcheck-*.egg-info/ %config(noreplace) %{_sysconfdir}/pki/healthcheck.conf @@ -1249,7 +1257,6 @@ fi ################################################################################ %{_javadir}/pki/pki-acme.jar -%dir %{_datadir}/pki/acme %{_datadir}/pki/acme/ # with acme @@ -1262,7 +1269,6 @@ fi %license base/ca/LICENSE %{_javadir}/pki/pki-ca.jar -%dir %{_datadir}/pki/ca %{_datadir}/pki/ca/ # with ca @@ -1275,7 +1281,6 @@ fi %license base/kra/LICENSE %{_javadir}/pki/pki-kra.jar -%dir %{_datadir}/pki/kra %{_datadir}/pki/kra/ # with kra @@ -1288,7 +1293,6 @@ fi %license base/ocsp/LICENSE %{_javadir}/pki/pki-ocsp.jar -%dir %{_datadir}/pki/ocsp %{_datadir}/pki/ocsp/ # with ocsp @@ -1301,7 +1305,6 @@ fi %license base/tks/LICENSE %{_javadir}/pki/pki-tks.jar -%dir %{_datadir}/pki/tks %{_datadir}/pki/tks/ # with tks @@ -1314,7 +1317,6 @@ fi %license base/tps/LICENSE %{_javadir}/pki/pki-tps.jar -%dir %{_datadir}/pki/tps %{_datadir}/pki/tps/ %{_mandir}/man5/pki-tps-connector.5.gz %{_mandir}/man5/pki-tps-profile.5.gz @@ -1393,6 +1395,9 @@ fi ################################################################################ %changelog +* Tue Mar 23 2021 Red Hat PKI Team 10.10.5-2 +- Bug 1914396 - CVE-2021-20179 pki-core:10.6/pki-core: Unprivileged users can renew any certificate + * Tue Feb 23 2021 Red Hat PKI Team 10.10.5-1 - Rebase to PKI 10.10.5 - Bug 1929067 - PKI instance creation failed with new 389-ds-base build