Certificate renewal and revocation in FreeIPA

A recent FreeIPA ticket has prompted a discussion about what revocation behaviour should occur upon certificate renewal. The ticket reported a regression: when renewing a certificate, ipa cert-request was no longer revoking the old certificate. But is revoking the certificate the correct behaviour in the first place?

This post discusses the motivations and benefits of automatically revoking a principal’s certificates when a new certificate is issued. It is assumed that subjects of certificates are FreeIPA principals. Conclusions do not necessarily apply to other environments or use cases.

Description of current behaviour

Notwithstanding the purported regression mentioned above, the current behaviour of FreeIPA is:

The revocation behaviour that occurs during ipa cert-request is actually defined in ipa {host,service}-mod. That is, when a userCertificate attribute value is removed, the removed certificates get revoked.

One certificate per service: a bad assumption?

The automatic revocation regime makes a big assumption. Host or service principals are assumed to need only one certificate. This is usually the case. But it is not inconceivable that a service may need multiple certificates for different purposes. The current (intended) behaviour prevents a service from possessing multiple valid (non-revoked) certificates concurrently.

Certificate issuance scenarios

Let us abandon the assumption that a host or service only needs one certificate at a time. There are three basic scenarios where cert-request would be revoked to issue a certificate to a particular principal. In each scenario, there are different motivations and consequences related to revocation. We will discuss each scenario in turn.

Certificate for new purpose (non-renewal)

A certificate is being requested for some new purpose. The subject may already have certs issued to it for other purposes. Existing certificates should not be revoked. FreeIPA’s revocation behaviour excludes this use case for host and service certificates.

Renewal due to impending expiry

A certificate may be requested to renew an existing certificate. After the new certificate is issued, it does no harm to revoke the old certificate. But it is not necessary to revoke it; it will expire soon.

Renewal for other reasons

A certificate could be renewed in advance of its expiration time for any reasons (e.g. re-key due to compromise, add a Subject Alternative Name, etc.) Conservatively, we’ll lump all the possible reasons together and say that it is necessary to revoke the certificate that is being replaced.

What if the subject possesses multiple certificates for different purposes? Right now, for host and service principals we revoke them all.

Proposed changes

A common theme is emerging. When we request a certificate, we want to revoke at most one certificate, i.e. the certificate being renewed (if any). This suggestion is applicable to service/host certificates as well as user certificates. It would admit the multiple certificates for different purposes use case for all principal types.

How do we get there from where we are now?

Observe that the ipa cert-request currently does not know (a) whether the request is a renewal or (b) what certificate is being renewed. Could we make cert-request smart enough to guess what it should do? Fuzzy heuristics that could be employed to make a guess, e.g. by examining certificate attributes, validity period, the subject public key, the profile and CA that were used, and so on. The guessing logic would be complex, and could not guarantee a correct answer. It is not the right approach.

Perhaps we could remove all revocation behaviour from ipa cert-request. This would actually be a matter of suppressing the revocation behaviour of ipa {host,service}-mod. Revocation has always been available via the ipa cert-revoke command. This approach makes revocation a separate, explicit step.

Note that renewals via Certmonger could perform revocation via ipa cert-revoke in the renewal helper. If you had to re-key or reissue a certificate via getcert resubmit, it could revoke the old certificate automatically. The nice thing here is that there is no guesswork involved. Certmonger knows what cert it is tracking so it can nominate the certificate to revoke and leave the subject’s other certificates alone.

A nice middle ground might be to add a new option to ipa cert-request to specify the certificate that is being renewed/replaced, so that cert-request can revoke just that certificate, and remove it from the subject principal’s LDAP entry. The command might look something like:

% ipa cert-request /path/to/req.csr \
    --principal HTTP/www.example.com \
    --replace "CN=Certificate Authority,O=EXAMPLE.COM;42"

The replace option specifies the issuer and serial number of the certificate being replaced. After the new certificate is issued, ipa cert-request would attempt to revoke the specified certificate, and remove it from the principal’s userCertificate attribute. Certmonger would be able to supply the replace option (or whatever we call it).

For any of the above suggestions it would be necessary to prominently and clearly outline the changes in release notes. The change in revocation behaviour could catch users off guard. It is important not to rush any changes through. We’ll need to engage with our user base to explain the changes, and outline steps to preserve the existing revocation behaviour if so desired.

ipa {host,service}-mod changes

Another (independent) enhancement to consider is an option to suppress the revocation behaviour of ipa {host,service}-mod, so that certificates could be removed from host/service entries without revoking them. A simple --no-revoke flag would suffice.

Conclusion

In this post I discussed how the current revocation behaviour of FreeIPA prevents hosts and services from using multiple certificates for different purposes. This is not the majority use case but I feel that we should support the use case. And we can, with a refinement of ipa cert-request behaviour.

We ought to make it possible to revoke only the certificate being renewed. We can do this by preventing ipa cert-request from revoking certs and requiring a separate call to ipa cert-revoke. behaviour of cert-request Alternatively, we can add an option to ipa cert-request for explicitly specifying the certificate(s) to revoke. In either case, the Certmonger renewal helpers can be changed to ensure that renewals via Certmonger revoke the old certificate (while leaving the subject’s other certificates alone!)

What do you think of the changes I’ve suggested? You can contribute to the discussion on the freeipa-devel mailing list.

Creative Commons License
Except where otherwise noted, this work is licensed under a Creative Commons Attribution 4.0 International License .