# -*-shell-script-*-
# This should be sourced by bash (though we welcome changes to make it POSIX sh compliant)

# Monkeysphere gen-subkey subcommand
#
# The monkeysphere scripts are written by:
# Jameson Rollins <jrollins@finestructure.net>
# Jamie McClelland <jm@mayfirst.org>
# Daniel Kahn Gillmor <dkg@fifthhorseman.net>
#
# They are Copyright 2008-2009, and are all released under the GPL,
# version 3 or later.

# generate a subkey with the 'a' usage flags set

gen_subkey(){
    local keyLength
    local keyExpire
    local keyID
    local gpgOut
    local userID

    # get options
    while true ; do
	case "$1" in
	    -l|--length)
		keyLength="$2"
		shift 2
		;;
	    -e|--expire)
		keyExpire="$2"
		shift 2
		;;
	    *)
		if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
		    failure "Unknown option '$1'.
Type '$PGRM help' for usage."
		fi
		break
		;;
	esac
    done

    case "$#" in
	0)
	    gpgSecOut=$(gpg --quiet --fixed-list-mode --list-secret-keys --with-colons 2>/dev/null | egrep '^sec:')
	    ;;
	1)
	    gpgSecOut=$(gpg --quiet --fixed-list-mode --list-secret-keys --with-colons "$1" | egrep '^sec:') || failure
	    ;;
	*)
	    failure "You must specify only a single primary key ID."
	    ;;
    esac

    # check that only a single secret key was found
    case $(echo "$gpgSecOut" | grep -c '^sec:') in
	0)
	    failure "No secret keys found.  Create an OpenPGP key with the following command:
 gpg --gen-key"
	    ;;
	1)
	    keyID=$(echo "$gpgSecOut" | cut -d: -f5)
	    ;;
	*)
	    echo "Multiple primary secret keys found:"
	    echo "$gpgSecOut" | cut -d: -f5
	    failure "Please specify which primary key to use."
	    ;;
    esac

    # check that a valid authentication key does not already exist
    IFS=$'\n'
    for line in $(gpg --quiet --fixed-list-mode --list-keys --with-colons "$keyID") ; do
	type=$(echo "$line" | cut -d: -f1)
	validity=$(echo "$line" | cut -d: -f2)
	usage=$(echo "$line" | cut -d: -f12)

	# look at keys only
	if [ "$type" != 'pub' -a "$type" != 'sub' ] ; then
	    continue
	fi
	# check for authentication capability
	if ! check_capability "$usage" 'a' ; then
	    continue
	fi
	# if authentication key is valid, prompt to continue
	if [ "$validity" = 'u' ] ; then
	    log error "A valid authentication key already exists for primary key '$keyID'."
	    if [ "$PROMPT" = "true" ] ; then
		read -p "Are you sure you would like to generate another one? (y/N) " OK; OK=${OK:N}
		if [ "${OK/y/Y}" != 'Y' ] ; then
		    failure "aborting."
		fi
		break
	    else
		failure "aborting."
	    fi
	fi
    done

    # set subkey defaults
    # prompt about key expiration if not specified
    keyExpire=$(get_gpg_expiration "$keyExpire")

    # generate the list of commands that will be passed to edit-key
    editCommands=$(cat <<EOF
addkey
7
S
E
A
Q
$keyLength
$keyExpire
save
EOF
)

    log verbose "generating subkey..."
    fifoDir=$(msmktempdir)
    (umask 077 && mkfifo "$fifoDir/pass")
    echo "$editCommands" | gpg --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --edit-key "$keyID" &

    # FIXME: this needs to fail more gracefully if the passphrase is incorrect
    passphrase_prompt  "Please enter your passphrase for $keyID: " "$fifoDir/pass"

    rm -rf "$fifoDir"
    wait
    log verbose "done."
}