chiark / gitweb /
pubkeyop.in: New script for doing stuff with public keys.
[distorted-keys] / pubkeyop.in
diff --git a/pubkeyop.in b/pubkeyop.in
new file mode 100755 (executable)
index 0000000..5a37534
--- /dev/null
@@ -0,0 +1,133 @@
+#! /bin/sh
+###
+### Front-end for public-key operations
+###
+### (c) 2012 Mark Wooding
+###
+
+###----- Licensing notice ---------------------------------------------------
+###
+### This file is part of the distorted.org.uk key management suite.
+###
+### distorted-keys is free software; you can redistribute it and/or modify
+### it under the terms of the GNU General Public License as published by
+### the Free Software Foundation; either version 2 of the License, or
+### (at your option) any later version.
+###
+### distorted-keys is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+### GNU General Public License for more details.
+###
+### You should have received a copy of the GNU General Public License
+### along with distorted-keys; if not, write to the Free Software Foundation,
+### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+set -e
+: ${ETC=@pkgconfdir@}
+: ${KEYS=@pkgstatedir@}
+: ${KEYSLIB=@pkglibdir@}
+export ETC KEYS KEYSLIB
+
+. "$KEYSLIB"/keyfunc.sh
+
+usage="COMMAND [ARGUMENTS ...]"
+
+###--------------------------------------------------------------------------
+### Common utilities.
+
+unpack () {
+  key=$1
+  ## Unpack the KEY and set up to use it as a public key for future
+  ## operations.
+
+  mktmp
+  exec 3<"$key"
+
+  ## Read the properties.
+  endp=nil
+  while read line; do
+    case "$line" in ENDPROP) endp=t; break ;; esac
+    setprops "property" kprop_ "$line"
+  done <&3
+  case $endp in
+    nil) echo >&2 "$quis: invalid public key (no ENDPROP line)"; exit 1 ;;
+  esac
+  checkprops "property" kprop_ "$g_props"
+
+  ## Fetch the type-handling library.
+  if [ ! -f $KEYSLIB/ktype.$kprop_type ]; then
+    echo >&2 "$quis: unknown key type \`$kprop_type'"
+    exit 1
+  fi
+  . $KEYSLIB/ktype.$kprop_type
+  checkprops "property" kprop_ "$k_props"
+
+  ## Write the rest of the public key somewhere convenient.
+  mkdir $tmp/pubkey
+  cat <&3 >$tmp/pubkey/pub
+  k_import $tmp/pubkey
+  exec 3>&-
+}
+
+###--------------------------------------------------------------------------
+### Commands.
+
+defcmd encrypt [-o CIPHERTEXT] KEY [MESSAGE] <<EOF
+Encrypt the MESSAGE (default stdin) using the public key KEY.  Write the
+ciphertext to CIPHERTEXT (default stdout).
+EOF
+cmd_encrypt () {
+  unset out
+  while getopts "o:" opt; do
+    case $opt in
+      o) out=$OPTARG ;;
+      *) usage_err ;;
+    esac
+  done
+  shift $(( $OPTIND - 1 ))
+  case $# in
+    1) ;;
+    2) msg=$2; exec <"$msg" ;;
+    *) usage_err ;;
+  esac
+  key=$1
+  unpack "$key"
+  case ${out+t} in
+    t) c_encrypt $tmp/pubkey - >"$out.new"; mv "$out.new" "$out" ;;
+    *) c_encrypt $tmp/pubkey - ;;
+  esac
+}
+
+defcmd verify KEY SIGNATURE [MESSAGE] <<EOF
+Verify a SIGNATURE (literal, not a filename) against a MESSAGE (default
+stdin) using the public KEY.
+EOF
+cmd_verify () {
+  case $# in
+    2) ;;
+    3) msg=$3; exec <"$msg" ;;
+    *) usage_err ;;
+  esac
+  key=$1 sig=$2
+  unpack "$key"
+  c_verify $tmp/pubkey - "$sig"
+}
+
+###--------------------------------------------------------------------------
+### Main program.
+
+while getopts "hv" opt; do
+  case "$opt" in
+    h) do_help; exit ;;
+    v) version; exit ;;
+    *) usage_err ;;
+  esac
+done
+shift $(( $OPTIND - 1 ))
+
+case $# in 0) usage_err ;; esac
+
+dispatch "$@"
+
+###----- That's all, folks --------------------------------------------------