- #!/bin/bash
- # seckey2sshagent: this is a hack of a script to cope with the fact
- # that openpgp2ssh currently cannot support encrypted secret keys.
- # the basic operating principal is:
- # export the secret key in encrypted format to a new keyring
- # remove the passphrase in that keyring
- # use that keyring with openpgp2ssh
- # Authors: Daniel Kahn Gillmor <dkg@fifthhorseman.net>,
- # Jameson Rollins <jrollins@fifthhorseman.net>
- explanation() {
- cat <<EOF
- Usage: $0 [GPGID [FILE]]
- The basic strategy of seckey2sshagent is to dump your OpenPGP
- authentication key(s) into your agent or a file. With no arguments,
- it will add all secret keys in your keyring to the agent. With one
- argument, it adds only the specified key to the agent. With two
- arguments, it dumps the specified key to FILE, with the pub key in
- FILE.pub.
- This script is a gross hack at the moment. It is done by creating a
- new, temporary private keyring, letting the user remove the
- passphrases from the keys, and then exporting them. The temporary
- private keyring is purged from the system.
- When you use this command, you'll find yourself dropped into a GPG
- 'edit-key' dialog relevant *only* to the temporary private keyring.
- At that point, you should clear the password from your key, with:
- passwd
- <enter your current password>
- followed by the empty string for the new password. GPG will ask you
- if you're really sure. Answer yes, because this is only relevant to
- the temporary keyring. Then, do:
- save
- At this point, your key will be added to your running ssh-agent with
- the alias 'monkeysphere-key' and seckey2sshagent should terminate.
- You can check on it with:
- ssh-add -l
- EOF
- }
- cleanup() {
- echo -n "removing temp gpg home... " 1>&2
- rm -rf "$TMPPRIVATE"
- echo "done." 1>&2
- }
- export_sec_key() {
- gpg --export-secret-key "$GPGID" | GNUPGHOME="$TMPPRIVATE" gpg --import
-
- GNUPGHOME="$TMPPRIVATE" gpg --edit-key "$GPGID"
- # idea to script the password stuff. not working.
- # read -s -p "enter gpg password: " PASSWD; echo
- # cmd=$(cat <<EOF
- # passwd
- # $PASSWD
- # \n
- # \n
- # \n
- # yes
- # save
- # EOF
- # )
- # echo -e "$cmd" | GNUPGHOME="$TMPPRIVATE" gpg --command-fd 0 --edit-key $GPGID
- # export secret key to file
- GNUPGHOME="$TMPPRIVATE" gpg --export-secret-keys "$GPGID" | \
- openpgp2ssh "$GPGID"
- }
- # if no hex string is supplied, just print an explanation.
- # this covers seckey2sshagent --help, --usage, -h, etc...
- if [ "$(echo "$1" | tr -d '0-9a-fA-F')" ]; then
- explanation
- exit
- fi
- # set the file creation umask
- umask 077
- GPGIDS="$1"
- if [ "$2" -a ! -e "$2" ] ; then
- FILE="$2"
- fi
- if [ -z "$GPGIDS" ]; then
- # hack: we need to get the list of secret keys, because if you
- # --list-secret-keys with no arguments, GPG fails to print the
- # capability flags (i've just filed this as
- # https://bugs.g10code.com/gnupg/issue945)
- KEYIDS=$(gpg --with-colons --list-secret-keys | grep ^sec | cut -f5 -d:)
- # default to using all fingerprints of authentication-enabled keys
- GPGIDS=$(gpg --with-colons --fingerprint --fingerprint --list-secret-keys $KEYIDS | egrep -A1 '^(ssb|sec):.*:[^:]*a[^:]*:$' | grep ^fpr: | cut -d: -f10)
- fi
- trap cleanup EXIT
- for GPGID in $GPGIDS; do
- TMPPRIVATE=$(mktemp -d)
-
- # if specified, write key to fail and passprotect
- if [ "$FILE" ] ; then
- # export secret key to file
- export_sec_key > "$TMPPRIVATE/key"
- # passprotect file
- ssh-keygen -f "${TMPPRIVATE}/key" -p
- # move into place
- mv "${TMPPRIVATE}/key" "$FILE"
-
- # export public key
- gpg --export "$GPGID" | openpgp2ssh "$GPGID" > "${FILE}.pub"
- # otherwise add to agent
- else
- KEYNAME='MonkeySphere Key '$(echo "$GPGID" | tr -c -d '0-9a-fA-F')''
- # creating this alias so the key is named "monkeysphere-key" in the
- # comment stored by the agent, while never being written to disk in
- # SSH form:
- ln -s /dev/stdin "${TMPPRIVATE}/${KEYNAME}"
- # export secret key to agent
- export_sec_key | (cd "$TMPPRIVATE" && ssh-add -c "$KEYNAME")
- fi
- done
|