summaryrefslogtreecommitdiff
path: root/src/seckey2sshagent
blob: a516256e29d92bf5671e3097a2a3af1ee9453a63 (plain)
  1. #!/bin/bash
  2. # seckey2sshagent: this is a hack of a script to cope with the fact
  3. # that openpgp2ssh currently cannot support encrypted secret keys.
  4. # the basic operating principal is:
  5. # export the secret key in encrypted format to a new keyring
  6. # remove the passphrase in that keyring
  7. # use that keyring with openpgp2ssh
  8. # Authors: Daniel Kahn Gillmor <dkg@fifthhorseman.net>,
  9. # Jameson Rollins <jrollins@fifthhorseman.net>
  10. explanation() {
  11. cat <<EOF
  12. Usage: $0 [GPGID [FILE]]
  13. The basic strategy of seckey2sshagent is to dump your OpenPGP
  14. authentication key(s) into your agent or a file. With no arguments,
  15. it will add all secret keys in your keyring to the agent. With one
  16. argument, it adds only the specified key to the agent. With two
  17. arguments, it dumps the specified key to FILE, with the pub key in
  18. FILE.pub.
  19. This script is a gross hack at the moment. It is done by creating a
  20. new, temporary private keyring, letting the user remove the
  21. passphrases from the keys, and then exporting them. The temporary
  22. private keyring is purged from the system.
  23. When you use this command, you'll find yourself dropped into a GPG
  24. 'edit-key' dialog relevant *only* to the temporary private keyring.
  25. At that point, you should clear the password from your key, with:
  26. passwd
  27. <enter your current password>
  28. followed by the empty string for the new password. GPG will ask you
  29. if you're really sure. Answer yes, because this is only relevant to
  30. the temporary keyring. Then, do:
  31. save
  32. At this point, your key will be added to your running ssh-agent with
  33. the alias 'monkeysphere-key' and seckey2sshagent should terminate.
  34. You can check on it with:
  35. ssh-add -l
  36. EOF
  37. }
  38. cleanup() {
  39. echo -n "removing temp gpg home... " 1>&2
  40. rm -rf "$TMPPRIVATE"
  41. echo "done." 1>&2
  42. }
  43. export_sec_key() {
  44. gpg --export-secret-key "$GPGID" | GNUPGHOME="$TMPPRIVATE" gpg --import
  45. GNUPGHOME="$TMPPRIVATE" gpg --edit-key "$GPGID"
  46. # idea to script the password stuff. not working.
  47. # read -s -p "enter gpg password: " PASSWD; echo
  48. # cmd=$(cat <<EOF
  49. # passwd
  50. # $PASSWD
  51. # \n
  52. # \n
  53. # \n
  54. # yes
  55. # save
  56. # EOF
  57. # )
  58. # echo -e "$cmd" | GNUPGHOME="$TMPPRIVATE" gpg --command-fd 0 --edit-key $GPGID
  59. # export secret key to file
  60. GNUPGHOME="$TMPPRIVATE" gpg --export-secret-keys "$GPGID" | \
  61. openpgp2ssh "$GPGID"
  62. }
  63. # if no hex string is supplied, just print an explanation.
  64. # this covers seckey2sshagent --help, --usage, -h, etc...
  65. if [ "$(echo "$1" | tr -d '0-9a-fA-F')" ]; then
  66. explanation
  67. exit
  68. fi
  69. # set the file creation umask
  70. umask 077
  71. GPGIDS="$1"
  72. if [ "$2" -a ! -e "$2" ] ; then
  73. FILE="$2"
  74. fi
  75. if [ -z "$GPGIDS" ]; then
  76. # hack: we need to get the list of secret keys, because if you
  77. # --list-secret-keys with no arguments, GPG fails to print the
  78. # capability flags (i've just filed this as
  79. # https://bugs.g10code.com/gnupg/issue945)
  80. KEYIDS=$(gpg --with-colons --list-secret-keys | grep ^sec | cut -f5 -d:)
  81. # default to using all fingerprints of authentication-enabled keys
  82. GPGIDS=$(gpg --with-colons --fingerprint --fingerprint --list-secret-keys $KEYIDS | egrep -A1 '^(ssb|sec):.*:[^:]*a[^:]*:$' | grep ^fpr: | cut -d: -f10)
  83. fi
  84. trap cleanup EXIT
  85. for GPGID in $GPGIDS; do
  86. TMPPRIVATE=$(mktemp -d)
  87. # if specified, write key to fail and passprotect
  88. if [ "$FILE" ] ; then
  89. # export secret key to file
  90. export_sec_key > "$TMPPRIVATE/key"
  91. # passprotect file
  92. ssh-keygen -f "${TMPPRIVATE}/key" -p
  93. # move into place
  94. mv "${TMPPRIVATE}/key" "$FILE"
  95. # export public key
  96. gpg --export "$GPGID" | openpgp2ssh "$GPGID" > "${FILE}.pub"
  97. # otherwise add to agent
  98. else
  99. KEYNAME='MonkeySphere Key '$(echo "$GPGID" | tr -c -d '0-9a-fA-F')''
  100. # creating this alias so the key is named "monkeysphere-key" in the
  101. # comment stored by the agent, while never being written to disk in
  102. # SSH form:
  103. ln -s /dev/stdin "${TMPPRIVATE}/${KEYNAME}"
  104. # export secret key to agent
  105. export_sec_key | (cd "$TMPPRIVATE" && ssh-add -c "$KEYNAME")
  106. fi
  107. done