Verification of certificate trustworthiness (e.g. in JWS and Client Certificate)
emmalee last edited by
I am comparing implementation complexity of JWS and Client Certificate and troubleshooting Client Certificate at the same time.
I understand that both methods require to prove that the certificate (
x5cin JWS or the actual Client Certificate) is trustworthy (as per https://tools.ietf.org/html/rfc7515#section-10.3). How should this validation process be achieved? Where do I get the root certificate from if I wanted to extract public key from the root?
For JWS I intended to hold a copy of a certificate (or at least its public key) in application memory. Before I validate the signature wih
x5ccertificate, I would validate the certificate itself. Is this correct approach?
For Client Certificates - the plot thickens, especially in my scenario (*) and it is not transparent to me since it is handled by HTTP server, not by my application, therefore I believe it can differ between server implementations, unless there is some standard? RFC5280 Section 6 on Path Validation cover this? My HTTP server expects me to install a "client certificate" (yes, on the server) and I am curious what the validation procedure would be (what is compared - just the keys or entire certificate, maybe just the root certificate?) and why it cannot use the same certificate that is already used for authenticating the server/domain (since they share the root certificate). In reality, each client has been issued their own certificate (with a shared root), so which client certificate am I expected to provide? Should I provide 1K client certificates for 1K clients?
(*) I am not a CA that self-signed client certificates, but they have issued a server certificate for my subdomain that is intended to handle the traffic. This means that I do not have direct access to private key and the root certificate.
By 'Client Certificate' do you mean in SSL/TLS and (thus) HTTPS? If so, 8446 (for TLS1.3) references 5280 for cert validation, although earlier versions were not explicit, and libraries generally implement this (or at least its predecessors; in OpenSSL for example the cert validation code didn't change much from about 2000 to about 2015). Typically a server wants you to configure one or more trust anchor(s) for the client certificate(s); while (often) this can be (an) individual cert(s), it can also be a cert for the/each CA that issued the child cert(s) (or usually its root) -- as long as you consider that CA reliable, i.e. you trust it adequately ensures the certs it issues (and does not revoke) are legitimate. Often this will even say something like 'tls-client-ca'. But a definite answer depends on the specific server: apache? nginx? haproxy? tomcat? Jboss/Wildfly? Liberty? other (custom) Java? Or C or C++? Or rust, or go, or whatever comes next? Or python, or nodejs, or perl, or ruby?
JWS also specifies 5280, in 7515 4.1.6, but implementations can vary a lot.
Added for comment:
(1) Okay, this is for Azure Gateway. Their documentation is confusing, inconsistent, and bloated, as typical for Microsoft. They use "client certificate", "client CA certificate", and "client CA certificate chain" in various places as if they were the same which they certainly are not. In https://docs.microsoft.com/en-us/azure/application-gateway/mutual-authentication-portal the "Before you begin" links back to its parent page https://docs.microsoft.com/en-us/azure/application-gateway/mutual-authentication-overview#certificates-supported-for-mutual-authentication which actually describes server certs not client, so is useless. However "Configure mutual authentication" step 5 (and the parent page also) says you should use https://docs.microsoft.com/en-us/azure/application-gateway/mutual-authentication-certificate-management which describes a way (only for Windows) to get the intermediate and root CA certs for the client cert, not including the client cert itself. This is consistent with the option described (at length) on related pages for them to check/require that a client cert is directly issued by a configured CA, e.g. "Verify client certificate issuer's DN" on the portal config page; that direct issuer will usually be an intermediate CA thus for this option to work they need the intermediate not just the root which would be enough for normal validation. (It's not clear if they actually need intermediates other than the first/lowest when multiple intermediates are used; the example doesn't show that case, and they don't really explain or precisely specify. They also don't show the direct-root case, which is rare, although I'd expect/hope submitting only the root works.) Although they give you the procedure only for Windows, the format they show is a sequence-of-PEM, a common standard you can easily create with other systems and programs.
(2) "the origin of a root public key" -- well, the origin is the root CA. But what matters is how you get it onto your system(s) in a way that is trustworthy, so that you are certain it is not tampered or faked.
For public CAs this is normally handled by the root-CA programs of various software suppliers: Microsoft (Windows) and Apple (MacOS and iOS) each has a program to provide (and update) trusted roots as part of their systems (which are secured overall to prevent lots of attacks not just SSL/TLS certs); Mozilla has a program created for and used by Firefox and Thunderbird, which many Linux distros and some other software (e.g. curl) also use; Oracle-formerly-Sun has one used by their builds of Java while other (OpenJDK, IBM, ?) builds can use something different depending on the builder. I don't know what dot-net does on non-Windows platforms. There are undoubtedly others that are less known.
For other CAs it may vary. If you work in a business or organization that has an internal CA they will usually have a process to get you the correct root; for domain-managed Windows systems they can do this automatically so you may not even be aware of it. If you 'join' http://cacert.org (not https!) you are expected to handle these details yourself.
(3) The verify logic described in the OpenSSL man page is basically standard, although it doesn't automatically fetch CRLs or use OCSP (or caIssuer) -- which are not strictly required but very useful and some other software does. The truststore format OpenSSL uses (a file and/or a directory using subject hashes in the names) is an implementation detail and typically (though not necessarily) the same for https servers (and others) that use OpenSSL, but often different on other software or middleware. E.g. Windows used locally has its own 'machine' store or may use/share the domain controller; since Azure is cloud we don't really know what it does internally, only what the input (or output) is like.