Bug 1372597

Summary: Incorrect CA ACL evaluation of SAN DNS names in certificate request
Product: Red Hat Enterprise Linux 7 Reporter: Martin Babinsky <mbabinsk>
Component: ipaAssignee: IPA Maintainers <ipa-maint>
Status: CLOSED ERRATA QA Contact: Kaleem <ksiddiqu>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 7.3CC: akasurde, ftweedal, lmiksik, mbabinsk, pvoborni, rcritten
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: ipa-4.4.0-10.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-11-04 06:02:42 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1360757    
Attachments:
Description Flags
verification steps with console output none

Description Martin Babinsky 2016-09-02 07:57:07 UTC
This bug is created as a clone of upstream ticket:
https://fedorahosted.org/freeipa/ticket/6291

`ipa cert-request` is supposed to check that the DNS names included in the SubjectAltName extension of CSR are authorized to be used with the certificate profile used with the CSR.

A regression introduced in c2af032c0333f7e210c54369159d1d9f5e3fec74 effectively bypassed this check, allowing the host principal to succesfully submit CSR with SAN DNS names of any host enrolled in FreeIPA domain.

Comment 1 Martin Babinsky 2016-09-02 08:02:16 UTC
Fixed upstream
master:

https://fedorahosted.org/freeipa/changeset/c2af032c0333f7e210c54369159d1d9f5e3fec74/

Comment 6 Martin Babinsky 2016-09-09 11:21:25 UTC
I have managed to slap together a rudimentary test case. It would be nice if Fraser could review and approve it, since the issue is pretty complex and quite hard for me to grasp. I hope I got it right:

1.)
Set up:

two host entries: host1.ipa.test, host2.ipa.test
two service entries: srv/host1.ipa.test, srv/host2.ipa.test

Request and store keytab for host1

2.) allow host1 to manage service2:

ipa service-add-host srv/host2.ipa.test --hosts host1.ipa.test

3.) generate CSR for host1.ipa.test having both hosts as the subjectAltName DNS fields

# cat openssl.conf 
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name

[ req_distinguished_name ]
commonName = host1.ipa.test

[ v3_req ]

# Extensions to add to a certificate request

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = host1.ipa.test
DNS.2 = host2.ipa.test

# openssl req -out test_csr.csr -new -newkey rsa:2048 -nodes -keyout test.key -config openssl.conf

4.) set up testing sub-CA and CAACL, add the sub-CA and caIPAserviceCert to CAACL

# ipa ca-add test_ca --subject 'CN=Test CA,O=IPA.TEST' --desc 'Test CA'
# ipa caacl-add test_caacl
# ipa caacl-add-ca test_caacl --cas test_ca
# ipa caacl-add-profile test_caacl --certprofiles caIPAserviceCert

5.) add host1.ipa.test to CAACL

# ipa caacl-add-host test_caacl --hosts host1.ipa.test

6.) add only service1 to CA ACL

# ipa caacl-add-service test_caacl --services srv/host1.ipa.test

7.) kinit as host1 and try to request certificate using test sub-CA. This should fail w/ ACIError as the `srv/host2.ipa.test` inferred from subjectAltNames is not part of CAACL
# kinit -kt /host/keytab host/host1.ipa.test
# ipa cert-request test_csr.csr --principal srv/`hostname` --ca test_ca

8.) kinit as admin and add srv/host2.ipa.test to the CA ACL
# kinit admin
# ipa caacl-add-service test_caacl --services srv/host2.ipa.test

9.) repeat step 7.), now it should succeed because srv/host2.ipa.test inferred from subjectAltNames is listed in the CA ACL.

Comment 7 Fraser Tweedale 2016-09-12 05:11:18 UTC
I believe the test case can be as simple as:

1. Request a cert for a host or service with a SAN dnsName extension request
   of an unrelated host (it need not even refer to an existing entity).  CN
   should match an existing host/service, which is used as the --principal
   option in cert-request.

2. Request the cert.  The request should be refused.

I will confirm that this simpler scenario does indeed trigger the bug.

Comment 8 Fraser Tweedale 2016-09-12 06:18:58 UTC
OK, my previous comment was not right, but the test case can be simpler
than Martin's example: it can be done just with host principals and not
involve service principals.


1.)
Set up:

two host entries: host1.ipa.test, host2.ipa.test

Request and store keytab for host1

2.) allow host1 to manage host2:

ipa host-add-managedby host2.ipa.test --hosts host1.ipa.test

3.) generate CSR with CN=host1.ipa.test having both hosts as the subjectAltName DNS fields

# cat openssl.conf 
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name

[ req_distinguished_name ]
commonName = host1.ipa.test

[ v3_req ]
subjectAltName = @alt_names

[alt_names]
DNS.1 = host1.ipa.test
DNS.2 = host2.ipa.test

# openssl req -out test_csr.csr -new -newkey rsa:2048 -nodes -keyout test.key -config openssl.conf

4.) set up testing sub-CA and CAACL, add the sub-CA and caIPAserviceCert to CAACL

# ipa ca-add test_ca --subject 'CN=Test CA,O=IPA.TEST' --desc 'Test CA'
# ipa caacl-add test_caacl
# ipa caacl-add-ca test_caacl --cas test_ca
# ipa caacl-add-profile test_caacl --certprofiles caIPAserviceCert

5.) add host1.ipa.test to CAACL

# ipa caacl-add-host test_caacl --hosts host1.ipa.test

6.) kinit as host1 and try to request certificate using test sub-CA. This should fail w/ ACIError as the `host/host2.ipa.test` inferred from subjectAltNames is not part of CAACL

# kinit -kt /host/keytab host/host1.ipa.test
# ipa cert-request test_csr.csr --principal host/host1.ipa.test --ca test_ca

7.) kinit as admin and add host2.ipa.test to the CA ACL

# kinit admin
# ipa caacl-add-host test_caacl --hosts host2.ipa.test

8.) repeat step 6.), now it should succeed because host2.ipa.test inferred
from subjectAltNames is listed in the CA ACL.

-----

Commentary: the creation of a sub-CA in steps above is not crucial to the
issue - instead it is a way to get around the default `hosts_services_caIPAserviceCert' CA ACL which allows all hosts and services
for profile `caIPAserviceCert' on default CA 'ipa'.  One could equivalently
disable the `hosts_services_caIPAserviceCert' CA ACL and create a new CA
ACL similar to steps above, but referring to existing 'ipa' CA (or all CAs)
instead of newly-created 'test_ca'.


Hope that helps; let me know if you have further questions!

Comment 9 Kaleem 2016-09-21 13:50:56 UTC
Verified.

IPA Version:
============
[root@dhcp207-129 ~]# rpm -q ipa-server pki-ca
ipa-server-4.4.0-12.el7.x86_64
pki-ca-10.3.3-10.el7.noarch
[root@dhcp207-129 ~]# 

Please find the attached file for verification steps with console output.

Comment 10 Kaleem 2016-09-21 13:52:30 UTC
Created attachment 1203305 [details]
verification steps with console output

Comment 12 errata-xmlrpc 2016-11-04 06:02:42 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHBA-2016-2404.html