summaryrefslogtreecommitdiff
path: root/src/subcommands/m/gen_subkey
blob: cbefaa3ecbf518e34a44d3c04ab5c3b9f7bf7cf2 (plain)
  1. # -*-shell-script-*-
  2. # This should be sourced by bash (though we welcome changes to make it POSIX sh compliant)
  3. # Monkeysphere gen-subkey subcommand
  4. #
  5. # The monkeysphere scripts are written by:
  6. # Jameson Rollins <jrollins@finestructure.net>
  7. # Jamie McClelland <jm@mayfirst.org>
  8. # Daniel Kahn Gillmor <dkg@fifthhorseman.net>
  9. #
  10. # They are Copyright 2008-2009, and are all released under the GPL,
  11. # version 3 or later.
  12. # generate a subkey with the 'a' usage flags set
  13. gen_subkey(){
  14. local keyLength
  15. local keyExpire
  16. local keyID
  17. local gpgOut
  18. local userID
  19. # get options
  20. while true ; do
  21. case "$1" in
  22. -l|--length)
  23. keyLength="$2"
  24. shift 2
  25. ;;
  26. -e|--expire)
  27. keyExpire="$2"
  28. shift 2
  29. ;;
  30. *)
  31. if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
  32. failure "Unknown option '$1'.
  33. Type '$PGRM help' for usage."
  34. fi
  35. break
  36. ;;
  37. esac
  38. done
  39. case "$#" in
  40. 0)
  41. gpgSecOut=$(gpg --quiet --fixed-list-mode --list-secret-keys --with-colons 2>/dev/null | egrep '^sec:')
  42. ;;
  43. 1)
  44. gpgSecOut=$(gpg --quiet --fixed-list-mode --list-secret-keys --with-colons "$1" | egrep '^sec:') || failure
  45. ;;
  46. *)
  47. failure "You must specify only a single primary key ID."
  48. ;;
  49. esac
  50. # check that only a single secret key was found
  51. case $(echo "$gpgSecOut" | grep -c '^sec:') in
  52. 0)
  53. failure "No secret keys found. Create an OpenPGP key with the following command:
  54. gpg --gen-key"
  55. ;;
  56. 1)
  57. keyID=$(echo "$gpgSecOut" | cut -d: -f5)
  58. ;;
  59. *)
  60. echo "Multiple primary secret keys found:"
  61. echo "$gpgSecOut" | cut -d: -f5
  62. failure "Please specify which primary key to use."
  63. ;;
  64. esac
  65. # check that a valid authentication key does not already exist
  66. IFS=$'\n'
  67. for line in $(gpg --quiet --fixed-list-mode --list-keys --with-colons "$keyID") ; do
  68. type=$(echo "$line" | cut -d: -f1)
  69. validity=$(echo "$line" | cut -d: -f2)
  70. usage=$(echo "$line" | cut -d: -f12)
  71. # look at keys only
  72. if [ "$type" != 'pub' -a "$type" != 'sub' ] ; then
  73. continue
  74. fi
  75. # check for authentication capability
  76. if ! check_capability "$usage" 'a' ; then
  77. continue
  78. fi
  79. # if authentication key is valid, prompt to continue
  80. if [ "$validity" = 'u' ] ; then
  81. echo "A valid authentication key already exists for primary key '$keyID'."
  82. read -p "Are you sure you would like to generate another one? (y/N) " OK; OK=${OK:N}
  83. if [ "${OK/y/Y}" != 'Y' ] ; then
  84. failure "aborting."
  85. fi
  86. break
  87. fi
  88. done
  89. # set subkey defaults
  90. # prompt about key expiration if not specified
  91. keyExpire=$(get_gpg_expiration "$keyExpire")
  92. # generate the list of commands that will be passed to edit-key
  93. editCommands=$(cat <<EOF
  94. addkey
  95. 7
  96. S
  97. E
  98. A
  99. Q
  100. $keyLength
  101. $keyExpire
  102. save
  103. EOF
  104. )
  105. log verbose "generating subkey..."
  106. fifoDir=$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXXXX)
  107. (umask 077 && mkfifo "$fifoDir/pass")
  108. echo "$editCommands" | gpg --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --edit-key "$keyID" &
  109. # FIXME: this needs to fail more gracefully if the passphrase is incorrect
  110. passphrase_prompt "Please enter your passphrase for $keyID: " "$fifoDir/pass"
  111. rm -rf "$fifoDir"
  112. wait
  113. log verbose "done."
  114. }