Skip to content

Instantly share code, notes, and snippets.

@whereisaaron
Last active March 5, 2024 18:13
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save whereisaaron/21e9caf02f97143bb338ec4f6f7f5aec to your computer and use it in GitHub Desktop.
Save whereisaaron/21e9caf02f97143bb338ec4f6f7f5aec to your computer and use it in GitHub Desktop.
Extract a crt file (PEM), key file, and chain bundle from a PFX file, prompts for password or use PFXPASSWORD environment variable
#!/bin/bash
#------------------
# Extract the key, certficiate, and chain in PEM format from a PFX format file
#
# Must supply the input pfx file
PFX_PATH="$1"
if [ "${PFX_PATH}" == "" ]; then
echo "Must supply pfx file path"
exit 1
fi
# Read password if not in environment variable
if [[ ! ${PFXPASSWORD+x} ]]; then
echo -n "Password: "
read -s PFXPASSWORD
echo
export PFXPASSWORD
fi
# Option supply a prefix for the output files
FILENAME=$(basename "$PFX_PATH")
if [ "$2" != "" ]; then
FILENAME_BASE=$2
else
FILENAME_BASE="${FILENAME%.*}"
fi
echo "Using '${FILENAME_BASE}' as base for output filenames"
#
# Extract key, certificate, and chain, going to extra steps to remove the 'Bag attributes'
# Note that openssl dumps the chain in the wrong order! (Anyone have fix?)
#
echo "Extracting ${FILENAME_BASE}.key"
openssl pkcs12 -in "$PFX_PATH" -nocerts -nodes -passin env:PFXPASSWORD \
| openssl rsa -out "${FILENAME_BASE}.key"
echo "Extracting ${FILENAME_BASE}.crt"
openssl pkcs12 -in "$PFX_PATH" -nokeys -clcerts -nodes -passin env:PFXPASSWORD \
| openssl x509 -out "${FILENAME_BASE}.crt"
echo "Extracting ${FILENAME_BASE}-ca-bundle.crt"
openssl pkcs12 -in "$PFX_PATH" -nokeys -cacerts -nodes -passin env:PFXPASSWORD \
| grep -v -e '^\s' | grep -v '^\(Bag\|subject\|issuer\)' > "${FILENAME_BASE}-ca-bundle.crt"
# Check if the bundle actually has any certificates
if [[ ! -s "${FILENAME_BASE}-ca-bundle.crt" && -f "${FILENAME_BASE}-ca-bundle.crt" ]]; then
echo "Bundle ${FILENAME_BASE}-ca-bundle.crt is empty, deleting"
rm "${FILENAME_BASE}-ca-bundle.crt"
fi
echo "Done."
@kyeotic
Copy link

kyeotic commented Mar 1, 2018

I owe you a beer

@cn137
Copy link

cn137 commented Aug 18, 2020

Nice and simple. Thank You !

@frennkie
Copy link

frennkie commented Oct 2, 2020

The *-ca-bundle.crt has blank lines at the top... only a cosmetic issue, but can be fixed by e.g. adding | strings:

echo "Extracting ${FILENAME_BASE}-ca-bundle.crt"
openssl pkcs12 -in "$PFX_PATH" -nokeys -cacerts -nodes -passin env:PFXPASSWORD \
  | strings | grep -v -e '^\s' | grep -v '^\(Bag\|subject\|issuer\)' > "${FILENAME_BASE}-ca-bundle.crt"

@loserratio
Copy link

Owing you a beer, too. Thanks for the great and simple script!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment