Created
April 27, 2017 19:03
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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