[EXTERNAL] - Validating Client Certificates
Michael Wojcik
mwojcik at opentext.com
Thu Mar 14 13:30:13 UTC 2024
> From: openssl-users <openssl-users-bounces at openssl.org> On Behalf Of Doug Hardie
> Sent: Wednesday, 13 March, 2024 21:50
> I am developing an application that clients will access. I don't want to use passwords as the users
> have shown a propensity to use easily guessed passwords etc. I am trying to use client certificates.
Client certificates and TLS mutual authentication (sometimes called "mTLS") do not in themselves fix
the weak-passwords problem. The end user needs access to the private key associated with the client
certificate. How that happens depends on the client software, but private keys are often protected
with passwords, those passwords are often selected by the end user, and often nothing ensures *they*
aren't weak.
Using client certificates might be a step in improving the strength of the authentication mechanism,
but they don't do so inherently.
> I have setup a local CA that is used to generate the client certificates. The user's identity is entered into
> the subject CN.
It's not clear what you mean by "the user's identity". If a certificate identifies a person, then (more or less
by definition) the Subject *DN* should be a sufficient description of that person. Since it's rarely the case
that a person's name is unique across a sufficiently large set - the world population, or even in many
cases within an organization, for common names - the X.500 Common Name RDN (attribute), if its value
is a person's name, is often not sufficient to identify an individual non-ambiguously.
If the CN uses a value that *is* guaranteed to map to a unique individual in some domain, such as an OS
username (properly administered), then that's not an issue, of course. But then the certificate really
identifies an OS account, not a person. Whether it identifies a "user" depends on your definition of that
term.
> My client certificates are properly accepted. However, I am unable to tell just what SSL_accept validates.
A definitive description of everything that happens in peer certificate validation would require analyzing
the OpenSSL source to make sure I'm not missing anything. From a high-level perspective:
- OpenSSL must be able to build one or more chains from the entity certificate presented by the client to
one of the roots in the trust collection supplied to OpenSSL by the caller, possibly using intermediate
certificates from the collection sent by the client (if any) and from the trust collection (if there are any).
- Each certificate in the chain must be valid: It must be well-formed, its signature must be valid (which
means it has to be checked against the public key of the certificate that signed it), the current time must
be within the validity times of the certificate, and so on.
- Each certificate in the chain must be appropriate: Fields and extensions such as Basic Constraints, Key
Usage, Extended Key Usage, and so forth must meet certain requirements. I don't recall offhand quite
what requirements OpenSSL imposes, and it depends to some extent on version (you didn't say) and
perhaps on options set by the program (I don't recall offhand what might be available in the API for
validating client certificates). Generally my advice to customers using client certificates is to use a
commercial CA or ensure their organizational CA follows both PKIX and the CA/Browser Forum Basic
Requirements. The CA/BF BR isn't strictly necessary in most cases, but it's a superset of what various
peers might want to see.
Key strength and use of appropriate algorithms will also be checked; you'll have trouble if you
use a signing algorithm that uses MD5, for example.
If the program has a certificate-validation callback, it could alter or suppress any of these checks, or
impose others of its own.
> I have not been able to find any documentation on what it actually checks. My testing shows that the
> client certificate must be signed by a known root certificate,
That's not an accurate description. It must be signed by a root or intermediate that can be chained back to
a root in the trust collection.
> but does SSL_accept verify that the signing certificate is the one indicated in the client certificate,
All certificates must be signed using the private key that corresponds to the public key in the certificate
that's listed as the signer. That's how the signature is verified. (Identifying the signing certificate is a bit
complicated, involving the optional AKID extension as well as the Issuer DN, but the short answer is that
OpenSSL has to find the signing certificate in order to verify the signature.)
> and how does it check that? In my server, I am checking the certificate serial number.
That's only necessary if your server includes roots in its trust collection that you don't actually want to trust
for this purpose. While there are use cases for that, they're unusual. If you only put roots you want to trust
into your trust collection, you don't need to do any further checks of the signing chain.
> It seems that it might be possible to create a CA that is certified by one of the known root certificates
It's not entirely clear what you mean by this. "known root certificates" is not a technical description. Known
to whom? If you're referring to commercial CAs, then note that, by definition, you can't have a root signed
by a different root -- root certificates are self-signed. It's possible to have a root that's cross-signed by
another root, so you can have a CA that's endorsed by another CA in that sense. You can also have a
trusted CA (note that "trusted" always means only that the peer you're communicating with has decided
to trust it!) issue an intermediate certificate which is then used to sign other intermediates or entity
certificates.
Good luck getting a commercial CA to cross-sign your root or sell you an intermediate. Won't be cheap.
That's their business, after all.
> and use it to generate a client certificate with the identical issuer information.
"identical" to what? It's really not clear what situation you're contemplating here.
In general, my advice is that PKI is very complex, difficult to get right, and full of pitfalls and unfortunate
failure modes in general, and PKIX (i.e. certificates) is particularly bad. Using TLS mutual authentication is
sometimes an improvement over other authentication mechanisms, but it needs careful and vigilant
administration. If the user base is of significant size, geographically distributed, or otherwise difficult to
deal with, user certificates are likely to become a large source of problems. And they may not actually
offer any improvement in security because there still has to be some mechanism by which the user gains
access to the certificate (by getting access to the private key). Some operating systems offer private-key
storage, but that just defers the problem: how does the user get access to private-key storage? By logging
in, possibly with a weak password?
The fact is that the IT industry is a long way from having any good solution to user authentication. The
current hotness is Passkey, and Passkey is loaded with undesirable properties like poor device portability
and often being tied to biometrics (the worst sort of authentication). Delegated authentication with OIDC
is similarly a horrible mess, for different reasons. Passwords are terrible (passphrases are slightly better)
and weak multifactor authentication hasn't helped much. There's no silver bullet for authentication. There
isn't even a lead bullet.
--
Michael Wojcik
More information about the openssl-users
mailing list