In my job we use our internal CA, which runs on a Windows server. When I want to use its CRL on a Linux machine I have to do these steps:

  1. download root CA and intermediate CAs
  2. covert them to x509
  3. merge into one file (CRL.pem)

For this I wrote the small script below, which I run automatically by timer unit (cron on systems without systemd) once a day.

#!/usr/bin/env bash

crls=(RootCA IntermediateCA IntermediateCA2)
crl_temp=$(mktemp -q -d /tmp/pullcrl.XXXXX)

for crl in ${crls[@]}; do
  if curl -s http://url_of_crls/${crl}.crl -o ${crl_temp}/${crl}.crl; then
    openssl crl -in ${crl_temp}/${crl}.crl -inform DER -out ${crl_temp}/${crl}.pem
    echo "Download a crl file failed!"
    exit 1

cat ${crl_temp}/*.pem > ${crl_temp}/${new_crl}

mv ${crl_temp}/${new_crl} ${crl_dir}/${new_crl}

Could I do something better?

for crl in ${crls[@]}; do

It's a good habit to always double-quote array expansions.

Cleaning up the temp directory after a successful run would be a nice touch (or do away with it altogether; see below).

cat ${crl_temp}/*.pem > ${crl_temp}/${new_crl}
mv ${crl_temp}/${new_crl} ${crl_dir}/${new_crl}

I assume you're doing this to get atomic replacement? It only works if /tmp and /etc are on the same filesystem. If they're not, you could get an empty destination file when (for example) the target is full. Consider creating a working directory under /etc to be certain.

You could be more concise using cd and brace expansion and bash's own error handling (via set -euxo pipefail):

set -euxo pipefail

cd /etc/pki/tls/misc
temp=$( mktemp -p . )

for url in http://…blahblah…/{RootCA,IntermediateCA,IntermediateCA2}.crl ; do 
    curl $url | openssl crl -in - -inform DER
done > $temp
mv $temp newcrl.pem
  • \$\begingroup\$ Hi, thanks a lot for the hints. Im using the rm cleaning at the end, just copy and paste issue. I thought about set -e, but I need to tell an other script, started on different time, that the result was failure - my mistake, I should have done the note about that in code. (I expect to that by writing a note into a file.). The other things looks really tasty :) Thanks again. \$\endgroup\$ – David Mosler Sep 16 '19 at 17:29
  • \$\begingroup\$ I like the part with curl and the pipe. It works fine in GNU bash, version 4.4.19(1)-release but in GNU bash, version 4.2.46(2)-release I got this error (23) Failed writing body. \$\endgroup\$ – David Mosler Sep 17 '19 at 8:56
  • \$\begingroup\$ that's not bash causing the failure. It's a different curl, or a different openssl, or a .curlrc exists that changes how curl works, or one of the two commands is aliased to have different behaviour. \$\endgroup\$ – Oh My Goodness Sep 17 '19 at 15:56
  • \$\begingroup\$ You are right, I found out it already. But due to that, isn't much more safely, just download all CLRs files and then convert them in separate way? Your example is pretty good, but I don't want to tune system by system that works. \$\endgroup\$ – David Mosler Sep 17 '19 at 16:06
  • 2
    \$\begingroup\$ Note that unchecked cd (without set -e) is a common dangerous anti-pattern. It's clear that you understand the importance, but might be worth pointing that up for passing readers! \$\endgroup\$ – Toby Speight Sep 18 '19 at 14:45

I merge my previous code with hints provided by @Oh My Goodness.

  • I excluded the variable clr_dir. The code thanks to is much more readable.
  • And I moved temp dir to the same filesystem as is final destination of new CRL.
#!/usr/bin/env bash

set -euo pipefail
cd /etc/pki/tls/misc

crls=(RootCA IntermediateCA IntermediateCA2)
crl_temp=$(mktemp -p .)

for crl in "${crls[@]}"; do
  curl -s http://url_of_crls/crl/"${crl}".crl -o "${crl}".crl
  openssl crl -in "${crl}".crl -inform DER
  rm -rf "${crl}".crl
done > "$crl_temp"

mv "$crl_temp" CRL.pem

I omitted the pipe for curl due to problems which it caused on systems with curl version 7.29.0. (It works fine on version 7.58.0.)


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.