Signed commits with KIT-CA Certificate on Linux
User certificates issued by the KIT-CA can be used to sign git commits using gpgsm. However, the generated PKCS#12 files are not compatible with gpgsm - when trying to import the file into the keyring, it fails with an unhelpful error message:
gpgsm: data error at "data.objectidentifier", offset 67
gpgsm: error at "bag-sequence", offset 49
gpgsm: error parsing or decrypting the PKCS#12 file
gpgsm: total number processed: 0
This happens because the PKCS#12 file contains the CA certificates, i.e. the full chain. gpgsm does not like that, we need to remove them first. This is what this snippet is doing, additionally to setting up git correctly afterwards.
Note that you will have to provide the path to your p12 file as command line argument. You will be asked for passphrases multiple times, just always use the passphrase of your user certificate.
#!/bin/bash
set -e
P12_FILE_PATH="$1"
if ! [ -f "$P12_FILE_PATH" ]; then
echo "No valid file path given."
exit 1
fi
# Extract user certificate
echo "Extracting user certificate from p12..."
if ! openssl pkcs12 -in "$P12_FILE_PATH" -clcerts -nokeys -out user_cert.pem; then
echo "Extract failed, trying legacy crypto..."
openssl pkcs12 -in "$P12_FILE_PATH" -legacy -clcerts -nokeys -out user_cert.pem
fi
# Extract private key
echo "Extracting private key from p12..."
if ! openssl pkcs12 -in "$P12_FILE_PATH" -nocerts -out user_key.pem; then
echo "Extract failed, trying legacy crypto..."
openssl pkcs12 -in "$P12_FILE_PATH" -legacy -nocerts -out user_key.pem
fi
# Merge them back into a p12 file. Leave out the -legacy if you are still using OpenSSL 1.1.
echo "Exporting legacy crypto p12 for import into GPGSM..."
openssl pkcs12 -legacy -export -in user_cert.pem -inkey user_key.pem -out user_cert.p12
# Import into gpgsm
echo "Importing p12 into GPGSM..."
gpgsm --import user_cert.p12
# Set up git to sign commit with your x.509 certificate in every repo you use (global)
echo "Setting up global git config..."
git config --global commit.gpgsign true
git config --global gpg.program gpgsm
git config --global gpg.format x509
git config --global user.signingkey "$( gpgsm --list-secret-keys | grep -E '(key usage|ID)' | grep -B 1 digitalSignature | awk '/ID/ {print $2}' | head -n 1)"
# Clean up
echo "Cleanup..."
rm user_cert.pem user_key.pem user_cert.p12
echo "Success 🥳"