Skip to content

Instantly share code, notes, and snippets.

@brodygov
Created April 27, 2017 19:03
Show Gist options
  • Save brodygov/61aafaf9f487ba520c3626dd91fcda04 to your computer and use it in GitHub Desktop.
Save brodygov/61aafaf9f487ba520c3626dd91fcda04 to your computer and use it in GitHub Desktop.
Get the first PIV public key in SSH format in the same way that PuTTY-CAC does on Windows
#!/bin/bash
set -eu
# This script prints the first PIV certificate found from a smart card in SSH
# format in the same way that putty-cac does on windows. (yeah.)
# LICENSE
#
# As a work of the United States Government, this project is in the public
# domain within the United States.
#
# Additionally, we waive copyright and related rights in the work worldwide
# through the CC0 1.0 Universal public domain dedication.
run() {
echo >&2 "+ $*"
"$@"
}
get_piv_pubkey_mac() {
lastfirst_str="$(id -F)"
lastfirst_arr=( ${lastfirst_str//,/} )
fullname="${lastfirst_arr[*]:1} ${lastfirst_arr[0]}"
fullname_upper="$(echo "$fullname" | tr '[:lower:]' '[:upper:]')"
# Contractor format
fullname_upper_affiliate="$fullname_upper (affiliate)"
cert="$(run security find-certificate -p "PIV-$fullname_upper")" || true
if [ -z "$cert" ]; then
cert="$(run security find-certificate -p "PIV-$fullname_upper_affiliate")"
fi
print_pubkey_from_cert "$cert"
}
print_pubkey_from_cert() {
if [ $# -lt 1 ]; then
echo >&2 "usage: print_pubkey_from_cert X509_CERT_CONTENT"
return 1
fi
cert="$1"
pubkey="$(ssh-keygen -i -m pkcs8 -f <(
openssl x509 -noout -pubkey <<< "$cert"))"
sha1="$(openssl x509 -noout -fingerprint <<< "$cert" \
| cut -d'=' -f2 | tr -d ':')"
echo "$pubkey CAPI:User\\MY\\$sha1"
}
get_piv_pubkey_opensc() {
# we could use `--read-ssh-key 1` instead, but putty uses the SHA1
# fingerprint of the full X.509 certificate, not just the RSA public key
# use the first certificate found
cert="$(run pkcs15-tool --read-certificate 1)"
print_pubkey_from_cert "$cert"
}
trap 'echo ERROR' EXIT
# use opensc if it is installed
if which pkcs15-tool >/dev/null 2>&1; then
get_piv_pubkey_opensc
trap - EXIT
exit
fi
case "$OSTYPE" in
darwin*)
get_piv_pubkey_mac
;;
linux*)
get_piv_pubkey_opensc
;;
*)
trap - EXIT
echo >&2 "Not yet implemented for $OSTYPE. Sorry!"
exit 1
;;
esac
trap - EXIT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment