The pyOpenSSL PKCS#10 parser doesn't support attributes so we can't identify
requests with subject alt names.
Subject alt names are only allowed if:
- the host for the alt name exists in IPA
- if binding as host principal, the host is in the services managedBy attr
Using the client IP address was a rather poor mechanism for controlling
who could request certificates for whom. Instead the client machine will
bind using the host service principal and request the certificate.
In order to do this:
* the service will need to exist
* the machine needs to be in the certadmin rolegroup
* the host needs to be in the managedBy attribute of the service
It might look something like:
admin
ipa host-add client.example.com --password=secret123
ipa service-add HTTP/client.example.com
ipa service-add-host --hosts=client.example.com HTTP/client.example.com
ipa rolegroup-add-member --hosts=client.example.com certadmin
client
ipa-client-install
ipa-join -w secret123
kinit -kt /etc/krb5.keytab host/client.example.com
ipa -d cert-request file://web.csr --principal=HTTP/client.example.com
We want to only allow a machine to request a certificate for itself, not for
other machines. I've added a new taksgroup which will allow this.
The requesting IP is resolved and compared to the subject of the CSR to
determine if they are the same host. The same is done with the service
principal. Subject alt names are not queried yet.
This does not yet grant machines actual permission to request certificates
yet, that is still limited to the taskgroup request_certs.
External CA signing is a 2-step process. You first have to run the IPA
installer which will generate a CSR. You pass this CSR to your external
CA and get back a cert. You then pass this cert and the CA cert and
re-run the installer. The CSR is always written to /root/ipa.csr.
A run would look like:
# ipa-server-install --ca --external-ca -p password -a password -r EXAMPLE.COM -u dirsrv -n example.com --hostname=ipa.example.com -U
[ sign cert request ]
# ipa-server-install --ca --external-ca -p password -a password --external_cert_file=/tmp/rob.crt --external_ca_file=/tmp/cacert.crt -U -p password -a password -r EXAMPLE.COM -u dirsrv -n example.com --hostname=ipa.example.com
This also abstracts out the RA backend plugin so the self-signed CA we
create can be used in a running server. This means that the cert plugin
can request certs (and nothing else). This should let us do online replica
creation.
To handle the self-signed CA the simple ca_serialno file now contains
additional data so we don't have overlapping serial numbers in replicas.
This isn't used yet. Currently the cert plugin will not work on self-signed
replicas.
One very important change for self-signed CAs is that the CA is no longer
held in the DS database. It is now in the Apache database.
Lots of general fixes were also made in ipaserver.install.certs including:
- better handling when multiple CA certificates are in a single file
- A temporary directory for request certs is not always created when the
class is instantiated (you have to call setup_cert_request())
There are some operations, like those for the certificate system, that
don't need to write to the directory server. So instead we have an entry
that we test against to determine whether the operation is allowed or not.
This is done by attempting a write on the entry. If it would succeed then
permission is granted. If not then denied. The write we attempt is actually
invalid so the write itself will fail but the attempt will fail first if
access is not permitted, so we can distinguish between the two without
polluting the entry.