- Sun 12 June 2016
- freeipa
- Benjamin Lipton
This post records the results some experimentation with the Dogtag API. Specifically, we will show how to authenticate against the API using credentials that are automatically generated by FreeIPA installation, how to use debug tools distributed with certmonger to issue certificates via the API, and a method of tweaking the created cert via the API parameters passed.
Acquiring the tool
We will be using the submit-d
tool, included in the certmonger source distribution but not the binary packages. First we download the source and build it:
$ git clone git://git.fedorahosted.org/git/certmonger.git
$ cd certmonger
$ sudo dnf install dbus-devel gettext-devel libidn-devel
$ ./autogen.sh
$ make
Authentication setup
FreeIPA uses a client certificate stored in the NSS database /etc/httpd/alias
to authenticate to Dogtag. Unfortunately, this database uses the older DBM format, while the tool we will be using requires the newer SQLite format. So first we must create a new database and copy the cert we need into it, via a PKCS12 file:
mkdir /tmp/certs
certutil -N -d sql:/tmp/certs
sudo pk12util -o ipaCert.p12 -n ipaCert -d /etc/httpd/alias -k /etc/httpd/alias/pwdfile.txt
sudo pk12util -i ipaCert.p12 -n ipaCert -d sql:/tmp/certs
At all password prompts, hit enter. We now have two certs in the file - ipaCert
, the client cert we will use for authentication, and the CA cert that signs all of the certs issued by FreeIPA:
[admin@vm-166 certs]$ certutil -L -d sql:/tmp/certs
Certificate Nickname Trust Attributes
SSL,S/MIME,JAR/XPI
ipaCert u,u,u
DOMAIN.EXAMPLE.COM IPA CA ,,
Mark the CA cert as trusted, otherwise the client will refuse to talk to the server:
certutil -M -t TC,, -d sql:/tmp/certs -n 'DOMAIN.EXAMPLE.COM IPA CA'
Making requests
Generate a keypair and a CSR to submit to the CA. The openssl req
command will prompt for the certificate subject; fill it out however you like.
$ openssl genrsa -out test.key
$ openssl req -new -key /tmp/certs/test.key -out /tmp/certs/test.req
Use the submit-d
tool to submit the request to Dogtag. If we use the caIPAserviceCert
template, the request goes through immediately and we are presented with a certificate:
$ src/submit-d -u https://server.example.com:8443/ca/ee/ca -U https://server.example.com:8443/ca/agent/ca \
-vv -d /tmp/certs -C ipaCert -a -T caIPAserviceCert -s /tmp/certs/test.req
We can see from the output that the tool makes a POST request to the profileSubmit
endpoint of the server.
On the other hand, if we use a non-IPA cert such as caServerCert
, the tool makes the same call but the request will be deferred until approved:
$ src/submit-d -u https://server.example.com:8443/ca/ee/ca -U https://server.example.com:8443/ca/agent/ca \
-vv -d /tmp/certs -C ipaCert -a -T caServerCert -s /tmp/certs/test.req
In this case, a requestId
is provided; we will use this to approve the request:
result = "<?xml version="1.0" encoding="UTF-8" standalone="no"?><XMLResponse><Status>2</Status><Error>Request Deferred - {0}</Error><RequestId> 31</RequestId></XMLResponse>"
error: Request Deferred - {0}
status: 2
requestId: 31
We can approve the request with the -A
flag and receive the certificate:
$ src/submit-d -u https://server.example.com:8443/ca/ee/ca -U https://server.example.com:8443/ca/agent/ca \
-vv -d /tmp/certs -C ipaCert -a -T caServerCert -A 31
Tweaking certificate parameters
If we look through the output of the approval command run above, we see a call to the profileProcess
endpoint on the Dogtag server. Interestingly, this call includes many of the parameters of the certificate:
GET /ca/agent/ca/profileProcess?requestId=31&op=approve&xml=true&name=CN%3Dserver.example.com%2CO%3DDOMAIN.EXAMPLE.COM¬Before=2016-06-13+02%3A50%3A46¬After=2018-06-03+02%3A50%3A46&authInfoAccessCritical=false&authInfoAccessGeneralNames=Record+%230%0AMethod%3A1.3.6.1.5.5.7.48.1%0ALocation+Type%3AURIName%0ALocation%3Ahttp%3A%2F%2Fserver.example.com%3A80%2Fca%2Focsp%0AEnable%3Atrue&keyUsageCritical=true&keyUsageDigitalSignature=true&keyUsageNonRepudiation=true&keyUsageKeyEncipherment=true&keyUsageDataEncipherment=true&keyUsageKeyAgreement=false&keyUsageKeyCertSign=false&keyUsageCrlSign=false&keyUsageEncipherOnly=false&keyUsageDecipherOnly=false&exKeyUsageCritical=false&exKeyUsageOIDs=1.3.6.1.5.5.7.3.1%2C1.3.6.1.5.5.7.3.2&signingAlg=SHA256withRSA HTTP/1.1
The tool gets these parameters by parsing the output of a call to the profileReview
endpoint. However, we will just re-use the same values, making a small modification to the name
parameter.
What happens if we submit the request again, and then approve it with the modified parameters?
src/submit-d -u https://server.example.com:8443/ca/ee/ca -U https://server.example.com:8443/ca/agent/ca \
-vv -d /tmp/certs -C ipaCert -a -T caServerCert -A 32 \
-V 'name=CN%3Dnewname%2CO%3DEXAMPLE.COM¬Before=2016-06-13+02%3A50%3A46¬After=2018-06-03+02%3A50%3A46&authInfoAccessCritical=false&authInfoAccessGeneralNames=Record+%230%0AMethod%3A1.3.6.1.5.5.7.48.1%0ALocation+Type%3AURIName%0ALocation%3Ahttp%3A%2F%2Fserver.example.com%3A80%2Fca%2Focsp%0AEnable%3Atrue&keyUsageCritical=true&keyUsageDigitalSignature=true&keyUsageNonRepudiation=true&keyUsageKeyEncipherment=true&keyUsageDataEncipherment=true&keyUsageKeyAgreement=false&keyUsageKeyCertSign=false&keyUsageCrlSign=false&keyUsageEncipherOnly=false&keyUsageDecipherOnly=false&exKeyUsageCritical=false&exKeyUsageOIDs=1.3.6.1.5.5.7.3.1%2C1.3.6.1.5.5.7.3.2&signingAlg=SHA256withRSA'
Our new name shows up in the certificate!
Certificate:
Data:
Version: v3
Serial Number: 0x1E
Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
Issuer: CN=Certificate Authority,O=DOMAIN.EXAMPLE.COM
Validity:
Not Before: Monday, June 13, 2016 2:50:46 AM GMT
Not After: Sunday, June 3, 2018 2:50:46 AM GMT
Subject: CN=newname,O=EXAMPLE.COM