Openvpn – Why does OpenVPN give the error: “unsupported certificate purpose” for an intermediate certificate

openvpnpkissl-certificate

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
         **:**:**:**:**:**:**:**

Best Answer

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