Centos – version 0.9.7a of openssl reports “certificate signature failed”, but version 0.9.8e is happy

centoscertificateopensslssl-certificate

I am trying to construct an openssl certificate chain that will work with a standard CentOS 4 install as client. (I know it's very old, but it's what our client is using so we need to support it).

The first problem is that the CentOS 4 openssl CA bundle doesn't contain all the modern certificates, in particular the GoDaddy root certificate

/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority

So I've dug around and found a Valicert certificate for the above certificate and put it in the chain. Running openssl s_client on CentOS 5 (which is openssl 0.9.8e) this chain verifies, but on CentOS 4 (which is openssl 0.9.7a) it doesn't verify.

CentOS 5 output:

$ openssl s_client -CAfile /etc/pki/tls/certs/ca-bundle.crt -connect svn.example.org:443
CONNECTED(00000003)
depth=4 /L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com
verify return:1
depth=3 /C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
verify return:1
depth=2 /C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
verify return:1
depth=1 /C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
verify return:1
depth=0 /OU=Domain Control Validated/CN=*.example.org
verify return:1
---
Certificate chain
 0 s:/OU=Domain Control Validated/CN=*.example.org
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
 2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
   i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
 3 s:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
   i:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com
---
Server certificate
-----BEGIN CERTIFICATE-----
[ SNIP ]
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.example.org
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
---
SSL handshake has read 5697 bytes and written 319 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: [ SNIP ]
    Session-ID-ctx:
    Master-Key: [ SNIP ]
    Key-Arg   : None
    Krb5 Principal: None
    Start Time: 1394712184
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
DONE

While on CentOS 4:

$ openssl s_client -CAfile /usr/share/ssl/certs/ca-bundle.crt -connect svn.example.org:443
CONNECTED(00000003)
depth=4 /L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com
verify return:1
depth=3 /C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
verify return:1
depth=2 /C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
verify error:num=7:certificate signature failure
verify return:0
---
Certificate chain
 0 s:/OU=Domain Control Validated/CN=*.example.org
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
 2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
   i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
 3 s:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
   i:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com
---
Server certificate
-----BEGIN CERTIFICATE-----
[ SNIP ]
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.example.org
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
---
SSL handshake has read 5697 bytes and written 343 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: [ SNIP ]
    Session-ID-ctx:
    Master-Key: [ SNIP ]
    Key-Arg   : None
    Krb5 Principal: None
    Start Time: 1394712595
    Timeout   : 300 (sec)
    Verify return code: 7 (certificate signature failure)
---
DONE

Bit flummoxed at this point, any ideas appreciated.

Best Answer

Assuming cert #3 in your chain is the one at https://certs.godaddy.com/anonymous/repository.pki gdroot-g2_cross.crt with SHA1 fingerprint 84 1D 4A 9F C9 D3 B2 F0 CA 5F AB 95 52 5A B2 06 6A CF 83 22, that is signed using SHA256WithRSA. So is the actual root for Go Daddy Root Certification Authority - G2 which is gdroot-g2.crt 47 BE AB C9 22 EA E8 0E 78 78 34 62 A7 9F 45 C2 54 FD E6 8B, not the one you identify Go Daddy Secure Certificate Authority - G2 which is clearly intermediate, apparently gdig2.crt 27 AC 93 69 FA F2 52 07 BB 26 27 CE FA CC BE 4E F9 C3 19 B8.

The (one) OpenSSL 0.9.7 I have still on one of my systems, 0.9.7d, does not support SHA-2. It is dated 2004, base 0.9.7 apparently was Dec. 2002, and FIPS 180-2 was published Aug. 2002.

I suggest you check your entity cert; it may also be signed with SHA256. Your #1 apparently is gdig2.crt which definitely is. If so these won't ever work in 0.9.7; you didn't see an error there because it had already failed further up the chain.

I'm not sure you can find a commercial CA that will issue you a SHA1-signed cert (and chain) after the NIST deadline took effect at the beginning of 2014; if so it probably won't remain valid very long and then you'll face the same problem again. If the client is willing to change their truststore (either the system one, without changing the code) or a user store used by whatever client app(s) you care about, you could just create a selfsigned-with-SHA1 cert for your server key using openssl and have the client(s?) trust that. Depending on your server if you can partition the requests from lame clients to a different port or address, you might be able to use your homemade SHA1 cert only for them and your commercial SHA256 cert for everybody else.