19

My program has the following flow: a client sends a CSR to server, the server sends back a client certificate and after that the client communicates with the server to a path that requires a certificate signed by the server (the client certificate)

My questions are:

  1. I've set clientAuth extended key usage in the generated client certificate. Should I add any additional key usages? Maybe "digitalSignature" KU?

  2. What does "digitalSignature" key usage mean? I have read about it as much as I can, but I'm still not sure if it's applicable to me (the best source of information I could find so far was this).

  3. What is the practical meaning of adding this key usage? (which actions will be prevented by well behaved SSL clients/servers?) As opposed to not specifying any key usages? (only the clientAuth EKU)

Matthew
  • 27,263
  • 7
  • 89
  • 101
yair
  • 339
  • 1
  • 3
  • 6

2 Answers2

20

TL-DR SSL client cert doesn't need KeyUsage but if present it should be digitalSignature except for very-rare-if-ever fixed-*DH.

Caveat: You tagged SSL so I assume by "path that requires a certificate" you mean SSL/TLS or something over SSL/TLS (not necessarily HTTP/S). If you mean something more like CMS or S/MIME, or XML-sig, or even PGP, the answer may be different.

I'm surprised you don't find other references since X.509 certs are so widely used. My first page of google X.509 key usage extension gives PKIX rfc5280 which is the currently effective Internet spec and (the text form of) its predecessor rfc3280; the not-terribly-good wikipedia article; and https://access.redhat.com/documentation/en-us/red_hat_certificate_system/10/html/administration_guide/standard_x.509_v3_certificate_extensions which has (possibly over-) specific instructions for several cases including SSL client. Quoting the relevant part of 5280 (which your IBM site more or less copies):

   Bits in the KeyUsage type are used as follows:

      The digitalSignature bit is asserted when the subject public key
      is used for verifying digital signatures, other than signatures on
      certificates (bit 5) and CRLs (bit 6), such as those used in an
      entity authentication service, a data origin authentication
      service, and/or an integrity service.

      The nonRepudiation bit is asserted when the subject public key is
      used to verify digital signatures, other than signatures on
      certificates (bit 5) and CRLs (bit 6), used to provide a non-
      repudiation service that protects against the signing entity
      falsely denying some action.  In the case of later conflict, a
      reliable third party may determine the authenticity of the signed
      data.  (Note that recent editions of X.509 have renamed the
      nonRepudiation bit to contentCommitment.)

      The keyEncipherment bit is asserted when the subject public key is
      used for enciphering private or secret keys, i.e., for key
      transport.  For example, this bit shall be set when an RSA public
      key is to be used for encrypting a symmetric content-decryption
      key or an asymmetric private key.

      The dataEncipherment bit is asserted when the subject public key
      is used for directly enciphering raw user data without the use of
      an intermediate symmetric cipher.  Note that the use of this bit
      is extremely uncommon; almost all applications use key transport
      or key agreement to establish a symmetric key.


      The keyAgreement bit is asserted when the subject public key is
      used for key agreement.  For example, when a Diffie-Hellman key is
      to be used for key management, then this bit is set.

      The keyCertSign bit is asserted when the subject public key is
      used for verifying signatures on public key certificates.  If the
      keyCertSign bit is asserted, then the cA bit in the basic
      constraints extension (Section 4.2.1.9) MUST also be asserted.

      The cRLSign bit is asserted when the subject public key is used
      for verifying signatures on certificate revocation lists (e.g.,
      CRLs, delta CRLs, or ARLs).

      The meaning of the encipherOnly bit is undefined in the absence of
      the keyAgreement bit.  When the encipherOnly bit is asserted and
      the keyAgreement bit is also set, the subject public key may be
      used only for enciphering data while performing key agreement.

      The meaning of the decipherOnly bit is undefined in the absence of
      the keyAgreement bit.  When the decipherOnly bit is asserted and
      the keyAgreement bit is also set, the subject public key may be
      used only for deciphering data while performing key agreement.

This is necessarily somewhat general because X.509 (and PKIX) certs were designed to be used for a range of things, not just SSL/TLS, although that's the only usage most people know about. It does distinguish several types of signing, encryption, and keyagreement (which in practice is used for encryption).

5280/3280 only mandate KeyUsage for CA certs, implicitly leaving it optional for EE certs. I don't have actual X.509 but AFAIU it says if KeyUsage is not present it is treated as all bits set, because that is compatible with v1 and v2 before there were any extensions. CABforum baseline explicitly specifies it as required for CA certs but optional for "subscriber" (meaning EE) certs.

TLSv1.2 (or its predecessors) requires a client cert "allow ... signing" except for the fixed-DH and fixed-ECDH key-exchanges which no one seems to use at least on the public net, and related sections explain how except for fixed-DH the client key is actually used only for signing handshake data to prove possession by and thus authenticate the client. This means if KeyUsage is present for SSL client it must include digitalSignature, and since in general a crypto key should not be used for multiple purposes without strong justification, KeyUsage for SSL client should not include anything else. If the client cert does not have KeyUsage or has a non-restrictive KeyUsage, a conforming SSL/TLS implementation will still use that key and cert only in the way specified by the protocol, which except fixed-DH as noted is only signing/verifying data that is not a cert or CRL.

dave_thompson_085
  • 10,064
  • 1
  • 26
  • 29
  • Thanks for the detailed answer. I've read that quote but since it's so general (as you noted) i'm having a hard time connecting it to TLS. The terms there are too abstract So i understand from you i get no added security value for adding a KU in my case. 1. What actual TLS actions fall into the category where "subject public key is used for verifying digital signatures other than signatures on certificates and CRLs"? preferably in the context i described in the first sentence of my question. 2. What falls into keyEncipherment (in TLS)? Thanks again! – yair Sep 29 '14 at 21:01
  • 1
    1. In SSL/TLS (except for fixed-*DH as already noted) a client key is used to authenticate the client by signing (a hash of) certain handshake data as detailed in rfc5246 7.4.8 and 4.7, or if ECC as modified by rfc4492 5.8 and 5.10, and this signature needs to be verified by the server using the publickey in the client cert. The handshake data is data and is not a cert or CRL, so verifying the signature on the handshake data is verifying a signature on data that is not a cert or CRL. – dave_thompson_085 Sep 30 '14 at 06:42
  • 1
    2. keyEncipherment is used only with the *server* key and thus the *server* cert, for "plain" RSA key-exchange (NOT DHE_RSA or ECDHE_RSA) (also RSA_PSK, but all PSK doesn't make sense on the public net). Plain-RSA was the only method in early versions of SSL, and still the most widely used even though arguably better options have been available for almost 20 years, although after Snowden visible use of "Perfect Forward Secrecy" has increased from tiny to small. See 7.4.2 for server cert and 7.4.7.1 for using it to encrypt the (per-session) premaster secret. – dave_thompson_085 Sep 30 '14 at 06:54
  • 1
    ... To be strict the (RSA-encrypted) premaster secret isn't exactly "the key" as some people oversimplify it; it is only part of the input used to derive *several* working keys. However, it is the only *secret* key input, and has the same security properties as an actual key, so it is treated as such. – dave_thompson_085 Sep 30 '14 at 07:04
12

Here an answer for libNSS :

For libNSS used by Mozilla Firefox answer is hidden within ./certdb/certdb.c :

When actualy checking usage :

  case certUsageSSLClient:
    /* 
     * RFC 5280 lists digitalSignature and keyAgreement for
     * id-kp-clientAuth.  NSS does not support the *_fixed_dh and
     * *_fixed_ecdh client certificate types.
     */
    requiredKeyUsage = KU_DIGITAL_SIGNATURE;
    requiredCertType = NS_CERT_TYPE_SSL_CLIENT;

if KeyUsage extension is not set, then it behaves like if it was fully set :

/* if the extension is not present, then we allow all uses */
cert->keyUsage = KU_ALL;

if it set then , well, it is set

    if (keyUsage & PKIX_DIGITAL_SIGNATURE){
            nssKeyUsage = nssKeyUsage | KU_DIGITAL_SIGNATURE;
    }

NSS Cert Type should have NS_CERT_TYPE_SSL_CLIENT set. CertType is derived from EKU :

if no EKU then NS_CERT_TYPE_SSL_CLIENT is set.

/* If no NS Cert Type extension and no EKU extension, then */
nsCertType = 0;
...
/* allow any ssl or email (no ca or object signing. */
nsCertType |= NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER |
              NS_CERT_TYPE_EMAIL;

If there are EKU then NS_CERT_TYPE_SSL_CLIENT is set ONLY if not a CA.

if (findOIDinOIDSeqByTagNum(extKeyUsage,
                SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) ==
    SECSuccess){
    if (basicConstraintPresent == PR_TRUE &&
    (basicConstraint.isCA)) {
    nsCertType |= NS_CERT_TYPE_SSL_CA;
    } else {
    nsCertType |= NS_CERT_TYPE_SSL_CLIENT;
    }
}

So in practice for libNSS ( as got from mercurial reposoritory https://hg.mozilla.org/projects/nss on 25th October 2015 ) to be valid client certificate, it should match one of those assertions :

  • EKU AND KU are NOT set.
  • KU is not set AND EKU is set to clientAuth AND cert is NOT a CA.
  • KU contains digitalSignature AND EKU is NOT set
  • KU contains digitalSignature AND EKU is set to clientAuth AND cert is NOT a CA.
philippe lhardy
  • 277
  • 2
  • 8