7

EDIT: I'm really sorry to have to say that the problem has magically fixed itself and I have no idea why. In response to one of the answers, I removed all EKU from the CA chain and it didn't work. After coming back from vacation, I created the cert chain 1 at a time, ie. RootCA->VPN then RootCA->IntermediateCA->VPN and, finally, RootCA->IntermediateCA->ServerCA->VPN and it still worked! I have no idea why it was working but I was thrilled. Just to make absolutely sure that it was the removal of the EKU that solved it, I went back and added random EKU to CAs in the chain and, lo and behold, it still works.... This is absolutely infuriating and I apologize to all the people who tried to help. I swear, absolutely nothing else has changed and no one touched anything in my absence. END EDIT

When trying to connect an OpenVPN client (Android or Windows 7/10) to my test server, I receive the following error:

VERIFY ERROR: depth=1, error=unsupported certificate purpose: C=CA, ST=QC, L=Montreal, O=Company Inc, OU=PKI, CN=Server Certificate Authority

I am running OpenVPN 2.3.7 on OpenBSD. I am using the following PKI CA hierarchy created using XCA:

RootCA -> IntermediateCA -> ServerCA

I created a certificate for my VPN server that is signed by my ServerCA. Please note the depth=1. This doesn't seem to be an issue with the final VPN Server certificate. OpenVPN is complaining about the issuer of the VPN server certificate. Even the CN in the error message is that of ServerCA NOT of the vpn server.

As far as I have been able to determine, there is no requirement for a CA in the chain to have any other purpose than signing certificates.

Here is the VPN server's certificate's configuration. Note that the old Netscape server extension is there, as required by OpenVPN:

nsCertType=server, email
extendedKeyUsage=serverAuth, nsSGC, ipsecEndSystem, iKEIntermediate
keyUsage=digitalSignature, keyEncipherment, dataEncipherment, keyAgreement
authorityKeyIdentifier=keyid, issuer
subjectKeyIdentifier=hash
basicConstraints=CA:FALSE

Here is the issuing CA's certificate's configuration:

crlDistributionPoints=crlDistributionPoint0_sect
extendedKeyUsage=critical,OCSPSigning
keyUsage=critical,keyCertSign, cRLSign
authorityKeyIdentifier=keyid, issuer
subjectKeyIdentifier=hash
basicConstraints=critical,CA:TRUE,pathlen:0

[crlDistributionPoint0_sect]
fullname=URI:http://pki.company.ca/server.crl

I tried adding nsCertType=server to the ServerCA but there was no change.

I have also seen endless forum posts where people forgot to add the nsCertType extension and received an error similar to mine but with depth=0 instead. In my case, the server's certificate seems to be fine.

Can anyone tell me why OpenVPN cares what a CA up the chain is permitted to do (other than signing certs, obviously)? How can I see what "certificate purpose" the client was expecting? How can I get OpenVPN to accept the certificate chain?

As requested, here is the VPN Server's certificate:

$ openssl x509 -noout -text -in vpn-server.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 4 (0x4)
    Signature Algorithm: sha512WithRSAEncryption
        Issuer: C=CA, ST=QC, L=Montreal, O=Company Inc, OU=PKI, CN=Server Certificate Authority
        Validity
            Not Before: Jun 21 17:58:00 2016 GMT
            Not After : Jun 21 17:58:00 2021 GMT
        Subject: C=CA, ST=QC, L=Montreal, O=Company Inc, OU=VPN, CN=vpn.company.ca
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                **:**:**:**:**:**:**:**
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Subject Key Identifier:
                A9:EF:EB:8B:68:E2:5F:0A:5D:FC:8A:39:7D:59:BE:21:75:2A:CB:8E
            X509v3 Authority Key Identifier:
                keyid:60:F3:33:2C:F7:13:09:F8:5C:3C:B2:D1:0B:9D:7D:9E:86:6A:24:41
                DirName:/C=CA/ST=QC/L=Montreal/O=Company Inc/OU=PKI/CN=Intermediate Certificate Authority
                serial:03

            X509v3 Key Usage:
                Digital Signature, Key Encipherment, Data Encipherment, Key Agreement
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, Netscape Server Gated Crypto, IPSec End System, 1.3.6.1.5.5.8.2.2
            Netscape Cert Type:
                SSL Server, S/MIME
    Signature Algorithm: sha512WithRSAEncryption
        **:**:**:**:**:**:**:**

And here is the issuer's certificate:

$ openssl x509 -noout -text -in server-ca.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 3 (0x3)
    Signature Algorithm: sha512WithRSAEncryption
        Issuer: C=CA, ST=QC, L=Montreal, O=Company Inc, OU=PKI, CN= Intermediate Certificate Authority
        Validity
            Not Before: Jun 21 17:57:00 2016 GMT
            Not After : Jun 21 17:57:00 2026 GMT
        Subject: C=CA, ST=QC, L=Montreal, O=Company Inc, OU=PKI, CN= Server Certificate Authority
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    **:**:**:**:**:**:**:**
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:0
            X509v3 Subject Key Identifier:
                60:F3:33:2C:F7:13:09:F8:5C:3C:B2:D1:0B:9D:7D:9E:86:6A:24:41
            X509v3 Authority Key Identifier:
                keyid:09:26:2E:AB:F4:C1:53:E1:10:11:DE:25:2D:20:D5:76:27:A9:FF:23
                DirName:/C=CA/ST=QC/L=Montreal/O=Company Inc/OU=PKI/CN=Root Certificate Authority
                serial:02

            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
            X509v3 Extended Key Usage: critical
                OCSP Signing
            X509v3 CRL Distribution Points:

                Full Name:
                  URI:http://pki.company.ca/server.crl

    Signature Algorithm: sha512WithRSAEncryption
         **:**:**:**:**:**:**:**
succulent_headcrab
  • 387
  • 2
  • 6
  • 12

4 Answers4

5

Hmm, OpenVPN's easyrsa creates certificates like this:

CA1:

X509v3 Subject Key Identifier:
87:13:73:D4:7C:9A:E1:EA:9A:F8:90:48:93:18:5A:B0:AF:B9:B6:25
X509v3 Authority Key Identifier:
keyid:87:13:73:D4:7C:9A:E1:EA:9A:F8:90:48:93:18:5A:B0:AF:B9:B6:25
DirName:/CN=Easy-RSA CA
serial:8B:E0:6F:16:C0:46:46:FC

X509v3 Basic Constraints:
CA:TRUE
X509v3 Key Usage:
Certificate Sign, CRL Sign

CA2:

X509v3 Basic Constraints:
CA:TRUE
X509v3 Subject Key Identifier:
D6:60:98:E7:6E:7C:73:9A:38:62:09:EC:C7:5D:62:15:89:AA:B2:8E
X509v3 Authority Key Identifier:
keyid:87:13:73:D4:7C:9A:E1:EA:9A:F8:90:48:93:18:5A:B0:AF:B9:B6:25
DirName:/CN=Easy-RSA CA
serial:8B:E0:6F:16:C0:46:46:FC

X509v3 Key Usage:
Certificate Sign, CRL Sign

Server:

X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
53:BA:B4:3B:87:AC:89:41:14:28:8F:C9:A2:F3:38:D4:43:90:EF:A6
X509v3 Authority Key Identifier:
keyid:D6:60:98:E7:6E:7C:73:9A:38:62:09:EC:C7:5D:62:15:89:AA:B2:8E
DirName:/CN=Easy-RSA CA
serial:CB:8A:25:7F:5A:8A:A9:BD:63:D2:BE:B7:6C:5E:3E:75

X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication

Client:

X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
F5:34:3A:39:C6:90:E0:2F:E3:92:A7:D2:0D:18:C7:48:E6:48:9F:DA
X509v3 Authority Key Identifier:
keyid:D6:60:98:E7:6E:7C:73:9A:38:62:09:EC:C7:5D:62:15:89:AA:B2:8E
DirName:/CN=Easy-RSA CA
serial:CB:8A:25:7F:5A:8A:A9:BD:63:D2:BE:B7:6C:5E:3E:75

X509v3 Key Usage:
Digital Signature
X509v3 Extended Key Usage:
TLS Web Client Authentication

But you have these Key Usage values too, so your config should be working... But there is not intermediate CA...

Have you tries to set --ca to the root CA cert and set --extra-certs to the intermediate CA and --cert to the server cert to form a complete chain? And don't forget --key too.

Actually i've got it working:

Server:

Tue Jun 21 04:39:49 2016 VERIFY OK: depth=2, CN=Easy-RSA CA
Tue Jun 21 04:39:49 2016 VERIFY OK: depth=1, O=Easy-RSA CA2, CN=Easy-RSA CA2
Tue Jun 21 04:39:49 2016 VERIFY OK: depth=0, O=client, CN=client

Client:

Tue Jun 21 04:39:49 2016 VERIFY OK: depth=2, CN=Easy-RSA CA
Tue Jun 21 04:39:49 2016 VERIFY OK: depth=1, O=Easy-RSA CA2, CN=Easy-RSA CA2
Tue Jun 21 04:39:49 2016 VERIFY OK: depth=0, O=server, CN=server

Server conf:

port 1194
proto tcp-server
dev tun
ca ca1.crt
extra-certs ca2.crt
cert server.crt
key server-key.pem
dh dh.pem
tls-server
tls-auth ta.key 0

Client conf:

client
remote localhost 1194
port 1194
proto tcp-client
dev tun
ca ca1.crt
extra-certs ca2.crt
cert client.crt
key client-key.pem
dh dh.pem
tls-client
tls-auth ta.key 1

XCA

Dmitry Ilyin
  • 573
  • 2
  • 5
  • This is pretty much my setup as well. I made sure that I could verify my certificate chain using `openssl verify` so I had never used the "extra-certs" parameter. I tried it with the intermediate certificate but it made no difference. I still received the same error message. – succulent_headcrab Jun 22 '16 at 20:38
  • Could you try to generate certificates again using easyrsa? Maybe you have accedently messed something. – Dmitry Ilyin Jun 23 '16 at 10:33
5

It's the EKU (ExtendedKeyUsage extension)

rfc 5280 4.2.1.12 extKeyUsage says

In general, this extension will appear only in end entity certificates.

CABforum Baseline Requirements (v1.3.4) 7.2.2 g affirms this, but along with 7.1.5 allows one case:

For a Subordinate CA Certificate to be considered Technically Constrained, the certificate MUST include an Extended Key Usage (EKU) extension specifying all extended key usages that the Subordinate CA Certificate is authorized to issue certificates for. The anyExtendedKeyUsage KeyPurposeId MUST NOT appear within this extension.

EKU thus is not a restriction on the CA's use of its own key, but on EE use of keys with certificates under the CA. This is similar to the way Policies (mostly) and NameConstraints propagate downward, and unlike KeyUsage which does apply to the CA itself.

And this is what OpenSSL implements and therefore OpenVPN using OpenSSL does. On each CA cert in a server chain, if EKU is present it must include serverAuth or SGC. Similarly each CA cert in a client chain with EKU must include clientAuth.

Your intermediate CA above your server has EKU with OCSPSign but not serverAuth, so it is rejected.

Reference: crypto/x509/x509_vfy.c and crypto/x509v3/v3_purp.c in openssl-1.0.2h

dave_thompson_085
  • 3,262
  • 1
  • 16
  • 16
  • But in my case intermediate CA has only keyUsage=keyCertSign, cRLSign and it's working – Dmitry Ilyin Jun 23 '16 at 20:36
  • @dilyin your posted data is inconsistent and doesn't appear to show this intermediate, but even if an intermediate has that KeyUsage (which can be correct for either root or intermediate CA), the problem described in my answer is about **ExtendedKeyUsage not KeyUsage**. – dave_thompson_085 Jun 24 '16 at 14:01
  • Yes, perhaps, you're right. You said that "if EKU is present" but in my case EKU is not present on CA certs only on the client and server. – Dmitry Ilyin Jun 24 '16 at 14:04
  • @dave_thompson_085 2 weeks ago, I tried no EKU anywhere in the cert chain and got the same error. Today, I created my certs one at a time, ie having the RootCA sign the VPN, then added the intermediate and finally the ServerCA. It worked at every step! I was on vacation and no changes were made anywhere. – succulent_headcrab Jul 07 '16 at 21:05
  • @dave_thompson_085 I was going to accept your answer, assuming I missed something last time, but then I added some random EKU to the CA chain and, lo and behold, it still worked! I am completely at a loss but it seems that the EKU was not causing my problem and, in fact, seems to work as the RFC5280 described it and not the CABforum (It seemed to me that this site was aimed more at "real" commercial CAs on the internet) – succulent_headcrab Jul 07 '16 at 21:06
1

I had a similar problem with stunnel and openssl on linux

I found that the server side expected all client and CA certs to include: Extended Key Usage: TLS Web Client Authentication

And, found that the client side expected all server and CA certs to include: X509v3 Extended Key Usage: TLS Web Server Authentication

Since I was using the same CA's to sign both the client and server certs I tested by setting the CA, CA1 and CA2 certs to include both clientAuth and serverAuth and it fixed the issue.

CA, CA1 and CA2: X509v3 Extended Key Usage: TLS Web Client Authentication, TLS Web Server Authentication

client cert: X509v3 Extended Key Usage: TLS Web Client Authentication

server cert: X509v3 Extended Key Usage: TLS Web Server Authentication

kevinM
  • 11
  • 2
0
  1. In my case I got this error message when the time on the client and server had drifted too far apart. I fixed it by running ntpdate on both servers:

    ntpdate 0.ubuntu.pool.ntp.org

    24 Apr 09:40:32 ntpdate[6085]: step time server 178.79.145.244 offset 628.631158 sec

It seems that at least 628s = 10min time drift is too much for openvpn (or openssl).

  1. Then I got the second problem, which was that actually my ca.crt had expired after 10 years:

    Validity
             Not Before: Apr 27 04:30:10 2011 GMT
             Not After : Apr 24 04:30:10 2021 GMT
    

Solution:

Regenerate the ca.crt and reissue all certificates.

  1. Third I was still getting the same error, but this time it was that I had two client certificates trying to connect to each other. Next I generated a server certificate separately, see http://gozer.ectoplasm.org/blog/archive/2007/07/openvpn_verify.html
PHZ.fi-Pharazon
  • 261
  • 1
  • 10
  • My error was to sign my client certificate with `easyrsa sign-req server clientname` instead of `easyrsa sign-req client clientname`. – noraj Jul 23 '23 at 18:07