> From: openssl-users <openssl-users-bounces@xxxxxxxxxxx> 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