This discussion does not include self-signed end entity certificates for hosts like web servers and mail servers.

OpenSSL's default configuration for a CA certificate has the following keyUsage:

  • cRLSign
  • keyCertSign

The Federal Public Key Infrastructure (PKI) X.509 Certificate and CRL Extensions Profile has the following keyUsage:

  • cRLSign
  • keyCertSign

Microsoft uses the following for its root certificates (from How to make a stand-alone certification authority):

  • Certificate Signing
  • Off-line CRL Signing
  • CRL Signing

RFC5280 defines CA or CRL issuer certificate key usage bits, and states the following MAY be present for a CA root using RSA:

  • digitalSignature
  • nonRepudiation
  • keyEncipherment
  • dataEncipherment
  • keyCertSign
  • cRLSign

For a DSA key under RFC5280, the following MAY be set:

  • digitalSignature
  • nonRepudiation
  • keyCertSign
  • cRLSign

And ECDSA keys under RFC5280, the following MAY be set:

  • digitalSignature
  • nonRepudiation
  • keyAgreement
  • keyCertSign
  • cRLSign.

And then RFC5280 goes on to say with respect to ECDSA:

if the keyUsage extension asserts keyAgreement then it MAY assert either encipherOnly and decipherOnly

Why is the IETF so fast-and-loose with key usage?

Why is keyEncipherment and dataEncipherment allowed for an RSA root certificate?

Why is a key agreement usage allowed on an ECDSA certificate?

Is the IETF usage a case where the standard was crafted to fit the existing practices?

  • 3
    Peter Gutmann's "Godzilla Crypto Tutorial" and related pdf's are just full of X.509 examples like this, even profiles that directly contradict each other. – grawity Jan 24 '14 at 11:19
  • I'd like to give you +10 for mentioning Guttman's stuff. His Engineering Security book is kind of comical at times when he starts discussing CA and PKI failures. – jww Jan 24 '14 at 11:39
up vote 8 down vote accepted

The Key Usage extension, when present, contains the exhaustive list of usage types that are allowed with the public key. When a system processes a certificate, it does so for a given purpose, and thus must verify that the Key Usage extension, if present, allows that usage. Specifically, when a system analyses a CA certificate and wants to use its public key in order to verify the signature over another certificate (that the CA purportedly issued), then this is a "certificate sign" usage; so if the CA certificate contains a Key Usage extension, then the system will require that the extension contains the keyCertSign flag.

Nothing prevents a Key Usage extension from containing other flags as well ! The verification is positive-only: systems check whether the flag they want is indeed there; they never check that a flag they don't want is absent.

Since a CA is supposed to issue certificate and CRL, it should have, on a general basis, the keyCertSign and cRLSign flags. These two flags are sufficient. If the CA does not intend to sign its own CRL, then it may omit the cRLSign flag; however, a CA without the keyCertSign flag makes little sense. One may want to include other flags if the CA key is meant to do other things as well (although this is not recommended: a general rule is that a cryptographic key should be used for one thing only). One may imagine, for instance, doing some key escrowing by encrypting the private key of issued certificates with the CA's public key, so that the CA may recover the private key under certain conditions (this is not a bad idea when the user's key is meant for data encryption).

Therefore, nothing prevents the Key Usage extension from containing other flags. Alternatively, the Key Usage extension may be missing altogether; this is equivalent to "all usages allowed".


Microsoft's "Off-line CRL signing" is just another name for "CRL signing". Indeed, the page you link to says this:

To apply this key usage if a CA certificate is requested, type the following at a command prompt, and then press ENTER:

echo 03 02 01 06>File_Name.txt

We here recognize the ASN.1/DER encoding of a BIT STRING of length 7 bits, with bits 5 and 6 set, and bits 0 to 4 cleared; this is the encoding of a Key Usage extension with flags keyCertSign and cRLSign. Though they use their own terminology, Microsoft actually conforms to the standard for that point (they did not invent a new, non-standard key usage flag for "offline CRL signing").


All of the above is the normal interpretation of certificates. It so happens that, as far as standards are concerned, "root CA certificates" do not exist. A "root" is called a trust anchor and consists in, mostly, a name (DN) and a public key. It is Traditional to encode trust anchor as "certificates", i.e. sequence of bytes which follow the encoding rules of certificates (such certificates are often self-signed, because the format for a certificate has a non-optional slot for a "signature", so there must be something in that slot).

Since this is non-standard, interpretation of certificate extension in such a certificate-like structure is open to local variants. Some implementations interpret the Key Usage extension in a root certificate in the ways explained above. Some ignore that extension altogether.

In general, it is safe (for interoperability) to fill root CA certificates with contents which would be perfectly valid if that "certificate" was a real one, instead of a convenient encoding vessel for a trust anchor.

  • Last I checked, the signature was optional... At least, when I forgot to actually sign certificates in my CA script (Ruby+OpenSSL) and it output them anyway. But the signature is still useful to prevent the root's DN or expiry date from being changed by anyone. – grawity Jan 24 '14 at 11:22
  • The signature field is not optional, but almost nobody actually verifies it, so any sequence of bytes will be "accepted" (when importing a certificate, Windows uses that signature to suggest, at the GUI level, to send the certificate to the "trusted root" or the "intermediate CA" store, depending on whether the certificate is self-signed or not; but that's only in the import interface; once the certificate has been stored in the "trusted root", its signature field, though present, is wholly ignored). – Thomas Pornin Jan 24 '14 at 12:04
  • Ah, apparently, what OpenSSL did (when I forgot to cert.sign()) was store OID 1 as algorithm, and a null byte as the signature. dumpasn1 and GnuTLS both choke on it, though. – grawity Jan 24 '14 at 13:16
  • 1
    And, are you saying that Windows would let me import a certificate to the root CA store, even if the certificate was altered to no longer match the self-signature? Sounds a bit insecure to me. – grawity Jan 24 '14 at 13:18
  • The self-signature on a root CA certificate has no meaning: if the attacker replaces the public key with a copy of his own, then he can also replace the signature with a self-signature which matches the altered certificate contents. It would be a delusion to believe that the self-signature adds any security in that context. – Thomas Pornin Jan 24 '14 at 13:47

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.