How to check if a server will accept your client certificate
Tags: tutorial, security, crypthography, certificate
Published: 2021-08-15 20:54:02

---
title: How to check if a server will accept your client certificate
published: true
description: 
tags: tutorial, security, crypthography, certificate
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/1tsiv9mejtyu00m2qmly.png
---
A currently fading but still very common way to authenticate client applications to serving applications is to use TLS/SSL client certificates. That way you can take advantage of the existing HTTPS infrastructure and just check the client serial number against a known list of authorized applications.

This is very commonly done in an enterprise setting where the certificate issuing process can be delegated to a third party. But this also means that the internal Certificate Authority may not be readily trusted by the server application infrastructure.

When that happens, the client may not be 100% sure that the server will trust its certificate. When it comes time to renew client certificates &mdash; and maybe even authorities &mdash; anxiety invariably kicks in!

# Here's what you'll need

OpenSSL got you covered, of course. But OpenSSL is no easy beast to deal with.

The command you're looking for is `openssl verify`. It takes as input a certificate authority list, which comes from the server application team, and a client certificate, which comes from the client application team.

![Diagram of two teams, one named server team and the other named client team, providing an authority file and a certificate file respectively to the openssl verify command that spits a green check mark](https://dev-to-uploads.s3.amazonaws.com/i/y6r8tyo4f761fvnw8d9h.png)

With both of those files in hand, here is what you'll need to say in your trusty shell:

```
$ openssl verify \
    -no-CApath \
    -CAfile certificate_authority_list.pem \
    client_certificate.pem
```

Do not forget to include the `-noCApath` flag or else OpenSSL will use your computer's trust store _in addition_ to the given certificate authority list. You will not get an accurate picture that way. Especially if the certificate was signed by a publically trusted authority.

> **Sidenote about file formats:** We're assuming all the time that files are in PEM format. PEM files are those that include `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`

In opensslish a green mark looks like this:

```
client_certificate.pem: OK
```

If you get anything like that, you're good to go!

# What if my client certificate fails the test?

When running `openssl verify`, you may get an error output:

```
C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
error 2 at 1 depth lookup: unable to get issuer certificate
error client_certificate.pem: verification failed
```

Assuming that you've got a good certificate file, any error means problems in the certificate authority file. This one shown here means that the first-level certificate authority (CA) is trusted, but the second one is not. OpenSSL starts counting at zero, "error X at 1 depth lookup" means that the 0 depth lookup was successful and there was an error at the next lookup.

You'll need a clean path to a root CA from the client certificate. In other words, the client certificate needs to be signed by a trusted authority and that authority's certificate _also_ needs to be signed by a trusted authority. And so on until you get to a certificate that is signed by itself. Those are called root CAs.

In order to check what CA signs your certificate, you can use another OpenSSL command:

```
$ openssl x509 -in client_certificate.pem -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ...
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
        ...
        X509v3 extensions:
            Authority Information Access: 
                CA Issuers - URI:http://secure.globalsign.com/cacert/gsrsaovsslca2018.crt
                OCSP - URI:http://ocsp.globalsign.com/gsrsaovsslca2018
            X509v3 Authority Key Identifier: 
                keyid:F8:EF:7F:F2:CD:78:67:A8:DE:6F:8F:24:8D:88:F1:87:03:02:B3:EB
            ...
```

And then again with the CA certificate:

```
$ openssl x509 -in gsrsaovsslca2018.pem -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            01:ee:5f:22:1d:fc:62:3b:d4:33:3a:85:57
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: OU = GlobalSign Root CA - R3, O = GlobalSign, CN = GlobalSign
        Subject: C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
        ...
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                F8:EF:7F:F2:CD:78:67:A8:DE:6F:8F:24:8D:88:F1:87:03:02:B3:EB
            X509v3 Authority Key Identifier: 
                keyid:8F:F0:4B:7F:A8:2E:45:24:AE:4D:50:FA:63:9A:8B:DE:E2:DD:1B:BC
            ...
```

Fortunately, this is a two-CA chain. And we just need one other check:

```
$ openssl x509 -in Root-R3.pem -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            04:00:00:00:00:01:21:58:53:08:a2
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: OU = GlobalSign Root CA - R3, O = GlobalSign, CN = GlobalSign
        Subject: OU = GlobalSign Root CA - R3, O = GlobalSign, CN = GlobalSign
        ...
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                8F:F0:4B:7F:A8:2E:45:24:AE:4D:50:FA:63:9A:8B:DE:E2:DD:1B:BC
        ...
```
See how the `X509v3 Authority Key Identifier` field in one certificate corresponds to the `X509v3 Subject Key Identifier` in the next? And that the `Issuer` and `Subject` in the last one are the same? This means that our certificate chain is whole.

If you're lucky, the CA will provide a certificate chain file. This file includes all the CA certificates down to the root. If you're not, you may need to stitch CA files together:

```
$ cat gsrsaovsslca2018.pem Root-R3.pem > new_certificate_authority_list.pem
```

Test it again using `openssl verify` (just in case), ask the server team to update their file and happy SSLing!