On Tue, Mar 17, 2020 at 05:04:59PM -0400, Endi Sukma Dewata wrote:
----- Original Message -----
> Hi Endi,
>
> Just want to quickly discuss certificate IDs.
>
> Currently on ACMEBackend interface we have
>
> public BigInteger issueCertificate(String csr);
>
> I think this is a bit of a problem. e.g. Dogtag currently supports
> multiple issuers (LWCAs). It is incidental that serial numbers do
> not collide. This might not hold for other backends. Yet we need
> the certificate ID to uniquely identify the certificate, so that we
> can retrieve it, revoke it, etc.
>
> I suggest changing the return value to a string (which is how it
> gets stored in the ACMEOrder object anyway).
>
> I'd further suggest that by convention, where possible, the string
> be a representation of issuer+serial, which is a bit nicer for
> humans looking at the stored objects than a base64url-encoded
> big-endian bigint.
>
> What do you think?
>
> Cheers,
> Fraser
Hi Fraser,
I agree there is a problem, but I'm not sure about using issuer+serial
as certificate ID. What do we use as "issuer", is it the issuer DN
or the authority ID?
The issuer DN.
Is issuer DN unique enough?
(issuer, serial) pair must be globally unique.
How do we join with
the serial number?
What format do we use for serial number?
Doesn't really matter as long as it is unambiguous. For example,
serial as decimal number, followed by ';', followed by string
representation of Issuer DN.
What if we need to add another field in the future? It seems
there's going to
be many questions/issues with this solution.
It is up to the ACMEBackend to produce a certificate ID. I'm simply
proposing this because a backend could contain multiple CAs with
separate serial number domains, hence deriving certificate ID from
serial number alone would not be unique. The idea of
(issuer,serial) pair is just a suggested convention. Some backends
e.g. might prefer UUIDs or whatever makes it easy to retrieve a
certificate/chain.
How about this instead?
1. Change issueCertificate() to return the full cert chain.
2. Store the cert chain in a "certs" table in ACME database.
3. Autogenerate the cert ID for each cert record.
4. Store the account ID in the cert record.
5. Store the cert ID in the order record.
So a copy of the cert will be stored in ACME database. The cert
ID will be unique for that particular ACME server. We don't need
to include the issuer DN/ID. The cert serial number will not matter
either. We can also use the certs table to authorize revocation
requests.
I thought about this a little while back, and I prefer the current
approach of storing an identifier as a "handle" to retrieve the cert
from the backend. Cert objects will increase the size of
records/objects significantly. For the LDAP backend it could be a
problem, both for disk usage but in particular for replication.
I'm OK with the idea of *optional* certificate/chain storage in the
ACME database, e.g. for backends that do not support retrieval. But
I don't think we need that with the current backends (certainly not
with the PKIBackend).
The cert ID is not meant to be human readable anyway (as
shown in RFC 8555).
But it doesn't matter if it is human readable. Either way, storing
only the serial number is not enough IMO.
Cheers,
Fraser