101

I have a certificate bundle .crt file.

doing openssl x509 -in bundle.crt -text -noout only shows the root certificate.

how do i see all the other certificates?

11 Answers 11

120

http://comments.gmane.org/gmane.comp.encryption.openssl.user/43587 suggests this one-liner:

openssl crl2pkcs7 -nocrl -certfile CHAINED.pem | openssl pkcs7 -print_certs -text -noout

It indeed worked for me, but I don't understand the details so can't say if there are any caveats.

  • 9
    This is the best answer - I won't even post my over-kill Python solution! Leave out the "-text" to just get subject/issuer info for each certificate. – Chris Wolf Mar 28 '16 at 23:03
  • Tried it on /etc/ssl/certs/ca-certificates.crt and got unable to load PKCS7 object – OrangeDog Jun 30 '17 at 13:48
  • 1
    Isn't this for pkcs7 format, whereas the question is about x509 format bundles? – Yetanotherjosh Feb 8 '18 at 2:16
  • 3
    It only uses pkcs7 as intermediate. Input is concatenated PEM. – Beni Cherniavsky-Paskin Feb 8 '18 at 7:00
  • You are super!!! – Jingguo Yao Aug 29 '18 at 6:14
21

Java's keytool does the trick:

keytool -printcert -v -file <certs.crt>

Annotation: Windows doubleclick does not work. Windows reads only the first certificate in the keystore and automatically extends the trustchain from its built in certificate store.

Results:

  1. All beyond the first certificate in the .crt file are not shown
  2. You may get a different trustchain displayed than you have in the .crt file. This may lead to wrong conclusions.
  • Thanks for clarifying the windows thing. This was really confusing the hell out of me – Nick.McDermaid Dec 8 '17 at 5:17
21

Following this FAQ led me to this perl script, which very strongly suggests to me that openssl has no native support for handling the nth certificate in a bundle, and that instead we must use some tool to slice-and-dice the input before feeding each certificate to openssl. This perl script, freely adapted from Nick Burch's script linked above, seems to do the job:

#!/usr/bin/perl
# script for splitting multi-cert input into individual certs
# Artistic Licence
#
# v0.0.1         Nick Burch <nick@tirian.magd.ox.ac.uk>
# v0.0.2         Tom Yates <tyates@gatekeeper.ltd.uk>
#

$filename = shift;
unless($filename) {
  die("You must specify a cert file.\n");
}
open INP, "<$filename" or die("Unable to load \"$filename\"\n");

$thisfile = "";

while(<INP>) {
   $thisfile .= $_;
   if($_ =~ /^\-+END(\s\w+)?\sCERTIFICATE\-+$/) {
      print "Found a complete certificate:\n";
      print `echo \'$thisfile\' | openssl x509 -noout -text`;
      $thisfile = "";
   }
}
close INP;
10

Oneliner that displays a summary of every certificate in the file.

openssl crl2pkcs7 -nocrl -certfile CHAINED.pem | openssl pkcs7 -print_certs -noout

(similar commando mentioned in other answer, but this gives shorter output, without the --text option).

example:

$ openssl crl2pkcs7 -nocrl -certfile bundled.crt | openssl pkcs7 -print_certs -noout

subject=/C=NL/postalCode=5705 CN/L=City/street=Example 20/O=Foobar B.V./OU=ICT/OU=Wildcard SSL/CN=*.example.com
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA

subject=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority

subject=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
issuer=/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Roo
  • This needs better explanations – Sven Apr 19 '18 at 9:09
3

This may not be pretty, or elegant, but it was quick and worked for me using bash on linux, and PEM formatted blocks in a ca-cert bundle file.

while read line
do
    if [ "${line//END}" != "$line" ]; then
        txt="$txt$line\n"
        printf -- "$txt" | openssl x509 -subject -issuer -noout
        txt=""
    else
        txt="$txt$line\n"
    fi
done < /path/to/bundle/file

You can put it all one line, and adjust the openssl options to suit. I really wish there were a more elegant solution for this, but in this case I think finding the more elegant solution would have taken more time than hacking out the inelegant one.

3

Since there is no awk based solution:

$ cat ca-bundle | awk '/BEGIN/ { i++; } /BEGIN/, /END/ { print > i ".extracted.crt" }'
$ ls *.extracted.crt | while read cert; do openssl x509 -in $cert -text -noout; done

The first command split bundle into certs by looking for BEGIN, and END lines. The second command loops through the extracted certs and shows them.

  • 1
    The print redirection feature in awk is available in gawk and nawk but not in basic awk. And so, this would work on Linux (gawk is linked as awk), but might not on OS X which has basic awk. – Raghu Dodda Nov 9 '15 at 1:34
1

In bash usually only one (long) line of code is needed :-)

tfile=$( mktemp -u ) && \
csplit -z -q -f "$tfile" bundle.crt  '/----BEGIN CERTIFICATE-----/' '{*}' && \
find "${tfile%/*}" -name "${tfile##*/}*" -exec openssl x509 -noout -subject -in "{}" \; -delete
0

Small alteration to MadHatter's post to allow you to copy/paste straight to the CLI. I also included the MD5 hash, which is helpful when making sure the certs are correct. The stdin line returned is the md5 hash of the cert(s).

perl -e 'my $thisfile = "";
foreach (<>) {
   $thisfile .= $_;
   if($_ =~ /^\-+END(\s\w+)?\sCERTIFICATE\-+$/) {
      print "Found a complete certificate:\n";
      print `echo "$thisfile" | openssl x509 -noout -text`;
      print `echo "$thisfile" | openssl x509 -noout -modulus | openssl md5`;
      $thisfile = "";
   }
}' < my_id_cert_and_ca_bundle.crt

If you want to see a nice short concise output you use this version. Helpful if you are only checking that you have included all your cert, but not really checking usage/etc of the cert(s).

perl -e 'my $thisfile = "";
foreach (<>) {
   $thisfile .= $_;
   if($_ =~ /^\-+END(\s\w+)?\sCERTIFICATE\-+$/) {
      print "Found a complete certificate:\n";
      print `echo "$thisfile" | openssl x509 -noout -serial -subject -dates -alias -issuer`;
      print `echo "$thisfile" | openssl x509 -noout -modulus | openssl md5` . "\n";
      $thisfile = "";
   }
}' < my_id_cert_and_ca_bundle.crt

Just in case your openssl version doesn't support all those flags here is some egrep you can use. Same thing as the first one but just pipe to egrep.

perl -e '.....
' < my_id_cert_and_ca_bundle.crt | egrep "Serial|Subject:|Not |Public-Key|^Cert|stdin|ssuer"

To check the MD5 hash of the private key you can do the following.

openssl rsa -noout -modulus -in privateKey.key | openssl md5

Reference: SSL Shopper - Certificate Key Matcher

0

Here's an awk based solution that doesn't rely on intermediate files.

cat bundle.crt | awk '{
  if ($0 == "-----BEGIN CERTIFICATE-----") cert=""
  else if ($0 == "-----END CERTIFICATE-----") print cert
  else cert=cert$0
}' | while read CERT; do
  echo "$CERT" | base64 -d | openssl x509 -inform DER -text -noout
done

It works by reading PEM blocks from stdin and concatenating each block to single base64 encoded line. Lines are then read, decoded and passed to openssl as DER encoded certificates.

  • 2
    Just for fun: cat bundle.crt | awk -v cmd="openssl x509 -subject -noout" '/-----BEGIN/ { c = $0; next } c { c = c "\n" $0 } /-----END/ { print c|cmd; close(cmd); c = 0 }'. – Manav May 30 '16 at 14:11
0

I'd like to throw in the idiomatic perl commandline here:

  perl -ne "\$n++ if /BEGIN/; print if \$n == 1;" mysite.pem

If there's text then a slightly more robust tweak:

 perl -ne "\$n++ if /^-----BEGIN CERTIFICATE-----\$/; print if \$n == 3 && /^-----BEGIN CERTIFICATE-----\$/.../^-----END CERTIFICATE-----\$/;" mysite.pem

Just change the value of what n should be in the second statement to get the nth certificate.

-2

Windows Method

One way you can see the whole chain is (in Windows of course) to double click the crt and then look on the Certification Path tab. It will show the whole chain even if there is only an Intermediate, or Root Cert. See screenshot below for details. If you're not on Windows I apologize for my lack of knowledge with Unix/Linux variants.

Note: this can cause false results if the intermediate certificate is in your local keystore Windows will add it automatically and not show only what was in the bundle.

                                      enter image description here

Linux (Ubuntu Method)

I overlooked your initial command and you have one thing out of place. Your command should look like this:

openssl x509 -in bundle.crt -noout -text

Source: http://manpages.ubuntu.com/manpages/hardy/man1/x509.1ssl.html

  • Really? I know it's sublte but you really can't tell? My is openssl x509 -in bundle.crt -noout -text, whereas yours has -text -noout ... hence why you are probably getting a syntax error. – Brad Bouchard Apr 25 '14 at 3:43
  • 20
    Hold your horses, Brad. Firstly, the OP didn't complain that his openssl invocation gave a syntax error, but that it only listed the first certificate in the bundle. Secondly, the two invocations are functionally identical. Thirdly, and probably most importantly, yours doesn't work, either, at least for me; it, too, lists only the first certificate in the bundle. – MadHatter Apr 25 '14 at 5:57
  • Yeah, I'm not as up on the Ubuntu side of things for issues like this and thought he was on Windows until he told me otherwise. So I didn't want to leave the OP hanging and after I did a little searching found that a reference site for these types of commands listed the command I gave him (the one with the slightly different syntax) and wanted to see if it could help. Your points are taken, but please do it with more grace next time. – Brad Bouchard Apr 25 '14 at 6:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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