0

I am trying to ensure that all certificates in a chain for a host have a key length of 2048 bits. Using openssl s_client, only the key length for that host's cert is given, is there a simple way to list the key length for all from the command-line, or is it necessary to download all the certs and check manually?

closed as off-topic by Adi, TildalWave, Gilles, Ayrx, Xander Nov 29 '13 at 18:55

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions about general computing hardware and software are off-topic here, but can be asked on Super User." – Adi, TildalWave, Ayrx, Xander
If this question can be reworded to fit the rules in the help center, please edit the question.

0

If you have a public-accessible server, use https://www.ssllabs.com/ssltest/analyze.html. Otherwise, see below for a script.

I am not aware of a s_client option that lists the key size for all certificates in a chain. You could use the -showcerts option to get all certificates provided by the server and check each of the provided certificates and assume that certificates in your trust store do not use small keys.

Note that some servers might be misconfigured to supply certificates in the chain that are not used (and incorrect). I remember seeing a site that would connect fine in Firefox, but fail in Java. It turned out that an old, expired CA was included in the chain along with the other certificates. Firefox would in this case just ignore that certificate as it found a valid certificate chain. openssl s_client -showcerts prints all certificates, even the ones that is unused (I have just verified that by appending a fake 1024-bit certificate to the chain).

The following script parses openssl s_client -showcerts output:

#!/usr/bin/awk -f
# Match all certificates
/^-----BEGIN CERTIFICATE-----$/ { in_cert=1; }
in_cert { cert = cert $0 "\n"; }
/^-----END CERTIFICATE-----$/ { in_cert = 0; }
!in_cert && cert {
    infocmd="openssl x509 -text -noout | grep -E 'Public-Key:|Subject:'";
    print cert | infocmd;
    close(infocmd);
    cert="";
}
# Print the verification result
/Verify return code/

Then use the above bits.awk with:

echo | openssl s_client -CApath /etc/ssl/certs \
    -connect example.com:443 -showcerts 2>/dev/null | ./bits.awk

The output looks like:

        Subject: CN=example.com
                Public-Key: (2048 bit)
        Subject: O=Trusted Certs Ltd., CN=Trusted CA
                Public-Key: (2048 bit)
        Subject: CN=Insecure
                Public-Key: (1024 bit)
    Verify return code: 0 (ok)

The first two lines are actually used for the chain verification, the last one isn't, but the script does not know that.

Not the answer you're looking for? Browse other questions tagged or ask your own question.