summaryrefslogtreecommitdiff
path: root/src/share/m/gen_subkey
blob: d926ad551116e57e6c3e4510b9923af5e7f23618 (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. log error "A valid authentication key already exists for primary key '$keyID'."
  82. if [ "$PROMPT" = "true" ] ; then
  83. read -p "Are you sure you would like to generate another one? (y/N) " OK; OK=${OK:N}
  84. if [ "${OK/y/Y}" != 'Y' ] ; then
  85. failure "aborting."
  86. fi
  87. break
  88. else
  89. failure "aborting."
  90. fi
  91. fi
  92. done
  93. # set subkey defaults
  94. # prompt about key expiration if not specified
  95. keyExpire=$(get_gpg_expiration "$keyExpire")
  96. # generate the list of commands that will be passed to edit-key
  97. editCommands=$(cat <<EOF
  98. addkey
  99. 7
  100. S
  101. E
  102. A
  103. Q
  104. $keyLength
  105. $keyExpire
  106. save
  107. EOF
  108. )
  109. log verbose "generating subkey..."
  110. fifoDir=$(msmktempdir)
  111. (umask 077 && mkfifo "$fifoDir/pass")
  112. echo "$editCommands" | gpg --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --edit-key "$keyID" &
  113. # FIXME: this needs to fail more gracefully if the passphrase is incorrect
  114. passphrase_prompt "Please enter your passphrase for $keyID: " "$fifoDir/pass"
  115. rm -rf "$fifoDir"
  116. wait
  117. log verbose "done."
  118. }