diff --git a/ChangeLog b/ChangeLog
index 683c8534105e9f0d3292b00b4d15a9e37b7a5d68..2462e454deb05b88722d79e2fcaa81d3873692ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2015-03-30 - 0.3.8 - Silvio Rhatto <rhatto@riseup.net>
+
+	Eliminates hardcoded bash path, reported and fixed by
+	polynomial (closes https://github.com/rhatto/keyringer/pull/1).
+
+	Rename genpair action and option (#69)
+
+	Ensure destination folder exists at 'cp' action
+
 2014-08-21 - 0.3.7 - Silvio Rhatto <rhatto@riseup.net>
 
 	Init: just set git user/mail if needed
diff --git a/contrib/pass b/contrib/pass
index b4d59548ccdcd3cfff2ab4d985956695acc66896..80eb7441281c5c806ca779d788b089a42a9ea8f2 100755
--- a/contrib/pass
+++ b/contrib/pass
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 
 # Sample wrapper program for simplying the use of keyringer.
 # This wrapper assumes you are using one key file with many
diff --git a/development.mdwn b/development.mdwn
index bbc688d95c3aea940063514cadb340a19df7f5c3..db67119e39e949d3f215a17269faf1b1dbb6ba8d 100644
--- a/development.mdwn
+++ b/development.mdwn
@@ -5,44 +5,11 @@ Index
 
 [[!toc levels=4]]
 
-Development environment
------------------------
-
-The following steps needs to be run just once for each arch and distro version.
-
-### Create the `debian/` structure
-
-    if [ ! -d "debian" ]; then
-      dh_make -p keyringer_0.1 --createorig
-    fi
-
-### Setup a sid pbuilder chroot
-
-    DIST=sid git-pbuilder create
-
-### Setup a sid cowbuilder chroot
-
-    DIST=sid sudo cowbuilder --create
-
-Environment maintenance
------------------------
-
-These steps should be run once in a while to ensure we have an up to date packaging environment.
-
-### Pbuilder
-
-    DIST=sid git-pbuilder update
-
-### Cowbuilder
-
-    DIST=sid sudo cowbuilder --update
-
 Coding standards
 ----------------
 
-  - Respect the existing coding style.
-
-  - Be clear: easy audability must be one of keyringer's requirements.
+* Respect the existing coding style.
+* Be clear: easy audability must be one of keyringer's requirements.
 
 Development workflow
 --------------------
@@ -86,7 +53,12 @@ Run lintian (or [add it to your pbuilder hooks](http://askubuntu.com/questions/1
 Notes:
 
 * `git-import-orig` takes care of running `pristine-tar commit`, of merging of the tag and orig tarball into the upstream branch, and then it merges the result into the debian branch. With the above configuration, it also runs git-dch to do the bulk of the work in `debian/changelog`.
-* To build a development package, checkout the debian branch, merge master, run `git-dch --auto --snapshot` and build. 
+* To build a development package, checkout the debian branch, merge master, run `git-dch --auto --snapshot` and build.
+
+Packaging workflow
+------------------
+
+We recommend [this packaging workflow](https://git.sarava.org/?p=debian.git;a=blob;f=README.md;hb=HEAD).
 
 Adding or changing a subcommand
 -------------------------------
diff --git a/keyringer b/keyringer
index 059b1576f94f7176e8f06db1231e52c225cdde36..956bb7327264c581d641ba7201d7db0b30c22121 100755
--- a/keyringer
+++ b/keyringer
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Keyringer key management system.
 #
@@ -140,7 +140,7 @@ function keyringer_dispatch {
 
 # Config
 NAME="keyringer"
-KEYRINGER_VERSION="0.3.7"
+KEYRINGER_VERSION="0.3.8"
 CONFIG_VERSION="0.1"
 CONFIG_BASE="$HOME/.$NAME"
 CONFIG="$CONFIG_BASE/config"
diff --git a/lib/keyringer/actions/append b/lib/keyringer/actions/append
index fbb6c1c57c3367435a76c7849d3428f9316a5b39..df21e03ed845124f6b26c769f753f4a28e6ce91e 100755
--- a/lib/keyringer/actions/append
+++ b/lib/keyringer/actions/append
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Append information into encrypted files.
 #
diff --git a/lib/keyringer/actions/check b/lib/keyringer/actions/check
index c80fa8f6ea7c50487cf2d75e54443cb42bd6c274..a647e95e4a0f2e20e9a4217912589a0b32e3b9d3 100755
--- a/lib/keyringer/actions/check
+++ b/lib/keyringer/actions/check
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Check a keyring.
 #
diff --git a/lib/keyringer/actions/commands b/lib/keyringer/actions/commands
index cb49c02424d9ac3abed029f422c7f3591e78a9c8..488831786e55d20dc2818c855cb3811aa436a265 100755
--- a/lib/keyringer/actions/commands
+++ b/lib/keyringer/actions/commands
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Show available commands
 #
diff --git a/lib/keyringer/actions/commit b/lib/keyringer/actions/commit
index b1249275cfe04a1ddbf0120e90cd93846b873e32..84ead14f7ab77743fff5f6d1384746ed7a908af5 100755
--- a/lib/keyringer/actions/commit
+++ b/lib/keyringer/actions/commit
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Git commit wrapper.
 #
diff --git a/lib/keyringer/actions/cp b/lib/keyringer/actions/cp
index 0629b613978db238f83f7a80cc93180c9545dfb4..1f4cceefdf45d097e5b250ee5ba74ceba3bcc0c4 100755
--- a/lib/keyringer/actions/cp
+++ b/lib/keyringer/actions/cp
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Copy secrets.
 #
@@ -27,7 +27,10 @@ if ! echo "$ORIG" | grep -q '*' && [ ! -e "$KEYDIR/$RELATIVE_PATH/$ORIG" ]; then
   exit 1
 fi
 
-# Run move command
+# Ensure destination folder exists
+mkdir -p `dirname "$KEYDIR/$FILE"`
+
+# Run copy command
 cd "$KEYDIR" && cp -a "./$RELATIVE_PATH/$ORIG" "./$FILE"
 keyringer_exec git "$BASEDIR" add "keys/$FILE"
 cd "$CWD"
diff --git a/lib/keyringer/actions/decrypt b/lib/keyringer/actions/decrypt
index b63b74e936f588a67f596a79623e2516eaf750c9..c6510eea62ca38a57d2ba8b1d0e5fff461c409ba 100755
--- a/lib/keyringer/actions/decrypt
+++ b/lib/keyringer/actions/decrypt
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Decrypt files.
 #
diff --git a/lib/keyringer/actions/del b/lib/keyringer/actions/del
index d160ac4d1972bc7273610a75cc6a0a1cbaeb3fbc..2abc4145e1ba578453daee197e955ba0795fdb79 100755
--- a/lib/keyringer/actions/del
+++ b/lib/keyringer/actions/del
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Remove files.
 #
diff --git a/lib/keyringer/actions/edit b/lib/keyringer/actions/edit
index c9f3f1268913c454227277680ce83f8647106bff..4338518475b8b340debbeb577be3b9c8e5aef845 100755
--- a/lib/keyringer/actions/edit
+++ b/lib/keyringer/actions/edit
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Edit keys.
 #
diff --git a/lib/keyringer/actions/encrypt b/lib/keyringer/actions/encrypt
index 7415267dc7f3a27ea3741faf2cd499bec07fccec..3818fa35e5100020c855c6f4aec201297d7944aa 100755
--- a/lib/keyringer/actions/encrypt
+++ b/lib/keyringer/actions/encrypt
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Encrypt files to multiple recipients.
 #
diff --git a/lib/keyringer/actions/find b/lib/keyringer/actions/find
index 9b18d66891ab7190054dda76ee6925b10eb30bb8..dc9d6d12ab6fe4cb727e4a8db546f38dbd7a2a1a 100755
--- a/lib/keyringer/actions/find
+++ b/lib/keyringer/actions/find
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Find secrets.
 #
diff --git a/lib/keyringer/actions/genkeys b/lib/keyringer/actions/genkeys
new file mode 100755
index 0000000000000000000000000000000000000000..f49d6d050a038578023c058b0f355a50134639a7
--- /dev/null
+++ b/lib/keyringer/actions/genkeys
@@ -0,0 +1,227 @@
+#!/usr/bin/env bash
+#
+# Generate keypairs.
+#
+# This script is just a wrapper to easily generate keys for
+# automated systems.
+#
+
+# Generate a keypair, ssh version
+function genkeys_ssh {
+  echo "Make sure that $KEYDIR is atop of an encrypted volume."
+  read -p "Hit ENTER to continue." prompt
+
+  # We're using empty passphrases
+  ssh-keygen -t rsa -b 4096 -P '' -f "$TMPWORK/id_rsa" -C "root@$NODE"
+
+  # Encrypt the result
+  echo "Encrypting secret key into keyringer..."
+  cat "$TMPWORK/id_rsa"     | keyringer_exec encrypt "$BASEDIR" "$FILE"
+  echo "Encrypting public key into keyringer..."
+  cat "$TMPWORK/id_rsa.pub" | keyringer_exec encrypt "$BASEDIR" "$FILE.pub"
+
+  if [ ! -z "$OUTFILE" ]; then
+    mkdir -p `dirname $OUTFILE`
+    printf "Saving copies at %s and %s.pub\n" "$OUTFILE" "$OUTFILE"
+    cat "$TMPWORK/id_rsa"     > "$OUTFILE"
+    cat "$TMPWORK/id_rsa.pub" > "$OUTFILE.pub"
+  fi
+
+  echo "Done"
+}
+
+# Generate a keypair, gpg version
+function genkeys_gpg {
+  echo "Make sure that $KEYDIR is atop of an encrypted volume."
+
+  passphrase="no"
+  passphrase_confirm="confirm"
+
+  while [ "$passphrase" != "$passphrase_confirm" ]; do
+    read -s -p "Enter password for the private key: " passphrase
+    printf "\n"
+    read -s -p "Enter password again: " passphrase_confirm
+    printf "\n"
+
+    if [ "$passphrase" != "$passphrase_confirm" ]; then
+      echo "Password don't match."
+    fi
+  done
+
+  # TODO: insert random bytes
+  # TODO: custom Name-Comment and Name-Email
+  # TODO: allow for empty passphrases
+  $GPG --homedir "$TMPWORK" --gen-key --batch <<EOF
+    Key-Type: RSA
+    Key-Length: 4096
+    Subkey-Type: ELG-E
+    Subkey-Length: 4096
+    Name-Real: $NODE
+    Name-Email: root@$NODE
+    Expire-Date: 0
+    Passphrase: $passphrase
+    %commit
+EOF
+
+  # Encrypt the result
+  echo "Encrypting secret key into keyringer..."
+  $GPG --armor --homedir "$TMPWORK" --export-secret-keys | keyringer_exec encrypt "$BASEDIR" "$FILE"
+  echo "Encrypting public key into keyringer..."
+  $GPG --armor --homedir "$TMPWORK" --export             | keyringer_exec encrypt "$BASEDIR" "$FILE.pub"
+  echo "Encrypting passphrase into keyringer..."
+  echo "Passphrase for $FILE: $passphrase"               | keyringer_exec encrypt "$BASEDIR" "$FILE.passwd"
+
+  if [ ! -z "$OUTFILE" ]; then
+    mkdir -p `dirname $OUTFILE`
+    printf "Saving copies at %s and %s.pub\n" "$OUTFILE" "$OUTFILE"
+    $GPG --armor --homedir "$TMPWORK" --export-secret-keys > "$OUTFILE"
+    $GPG --armor --homedir "$TMPWORK" --export             > "$OUTFILE.pub"
+  fi
+
+  echo "Done"
+}
+
+# Alias
+function genkeys_ssl {
+  genkeys_x509 $*
+}
+
+# Generate a keypair, ssl version
+function genkeys_x509 {
+  echo "Make sure that $KEYDIR is atop of an encrypted volume."
+  read -p "Hit ENTER to continue." prompt
+
+  # Check for wildcard certs
+  if [ "`echo $NODE | cut -d . -f 1`" == "*" ]; then
+    WILDCARD="yes"
+    CNAME="$NODE"
+    NODE="`echo $NODE | sed -e 's/^\*\.//'`"
+  else
+    CNAME="${NODE}"
+  fi
+
+  # Setup
+  cd "$TMPWORK"
+
+  # Generate certificate
+cat <<EOF >> openssl.conf
+[ req ]
+default_keyfile         = ${NODE}_privatekey.pem
+distinguished_name      = req_distinguished_name
+encrypt_key             = no
+req_extensions          = v3_req # Extensions to add to certificate request
+string_mask             = nombstr
+
+[ req_distinguished_name ]
+commonName_default              = ${CNAME}
+organizationName                = Organization Name
+organizationalUnitName          = Organizational Unit Name
+emailAddress                    = Email Address
+localityName                    = Locality
+stateOrProvinceName             = State
+countryName                     = Country Name
+commonName                      = Common Name
+
+[ v3_req ]
+extendedKeyUsage=serverAuth,clientAuth
+EOF
+
+  # Add SubjectAltNames so wildcard certs can work correctly.
+  if [ "$WILDCARD" == "yes" ]; then
+cat <<EOF >> openssl.conf
+subjectAltName=DNS:${NODE}, DNS:${CNAME}
+EOF
+  fi
+
+  echo "Please review your OpenSSL configuration:"
+  cat openssl.conf
+  read -p "Hit ENTER to continue." prompt
+
+  openssl req -batch -nodes -config openssl.conf -newkey rsa:4096 -sha256 \
+          -keyout ${NODE}_privatekey.pem -out ${NODE}_csr.pem
+
+  openssl req -noout -text -in ${NODE}_csr.pem
+
+  # Self-sign
+  if [ "$KEYTYPE" == "ssl-self" ]; then
+    openssl x509 -in "${NODE}_csr.pem" -out "$NODE.crt" -req -signkey "${NODE}_privatekey.pem" -days 365
+    chmod 600 "${NODE}_privatekey.pem"
+  fi
+
+  # Encrypt the result
+  echo "Encrypting private key into keyringer..."
+  cat "${NODE}_privatekey.pem" | keyringer_exec encrypt "$BASEDIR" "$FILE.pem"
+  echo "Encrypting certificate request into keyringer..."
+  cat "${NODE}_csr.pem"        | keyringer_exec encrypt "$BASEDIR" "$FILE.csr"
+
+  if [ "$KEYTYPE" == "ssl-self" ]; then
+    echo "Encrypting certificate into keyringer..."
+    cat "${NODE}.crt" | keyringer_exec encrypt "$BASEDIR" "$FILE.crt"
+  elif [ -f "$BASEDIR/keys/$FILE.crt.asc" ]; then
+    # Remove any existing crt
+    keyringer_exec del "$BASEDIR" "$FILE.crt"
+  fi
+
+  cd "$CWD"
+
+  if [ ! -z "$OUTFILE" ]; then
+    mkdir -p `dirname $OUTFILE`
+    printf "Saving copies at %s\n" "`dirname $OUTFILE`"
+    cat "$TMPWORK/${NODE}_privatekey.pem" > "$OUTFILE.pem"
+    cat "$TMPWORK/${NODE}_csr.pem"        > "$OUTFILE.csr"
+
+    if [ -f "$TMPWORK/${NODE}.crt" ]; then
+      cat "$TMPWORK/${NODE}.crt" > "$OUTFILE.crt"
+    fi
+  fi
+
+  # Show cert fingerprint
+  if [ "$KEYTYPE" == "ssl-self" ]; then
+    openssl x509 -noout -in "$TMPWORK/${NODE}.crt" -fingerprint
+  fi
+
+  echo "Done"
+}
+
+# Load functions
+LIB="`dirname $0`/../functions"
+source "$LIB" || exit 1
+
+# Aditional parameters
+KEYTYPE="$2"
+FILE="$RELATIVE_PATH/$3"
+NODE="$4"
+OUTFILE="$5"
+CWD="`pwd`"
+
+# Verify
+if [ -z "$NODE" ]; then
+  echo -e "Usage: keyringer <keyring> $BASENAME <gpg|ssh|x509|x509-self|ssl|ssl-self> <file> <hostname> [outfile]"
+  echo -e "Options:"
+  echo -e "\t gpg|ssh|x509[-self]|ssl|ssl[-self]: key type."
+  echo -e "\t file                              : base file name for encrypted output (relative to keys folder),"
+  echo -e "\t                                     without spaces"
+  echo -e "\t hostname                          : host for the key pair"
+  echo -e "\t outfile                           : optional unencrypted output file, useful for deployment,"
+  echo -e "\t                                     without spaces"
+  exit 1
+elif [ ! -e "$KEYDIR" ]; then
+  echo "Folder not found: $KEYDIR, leaving"
+  exit 1
+fi
+
+# Set a tmp file
+keyringer_set_tmpfile genpair -d
+
+# Dispatch
+echo "Generating $KEYTYPE key for $NODE..."
+if [ "$KEYTYPE" == "ssl-self" ] || [ "$KEYTYPE" == "x509-self" ]; then
+  genkeys_x509
+else
+  genkeys_"$KEYTYPE"
+fi
+
+# Cleanup
+cd "$CWD"
+rm -rf "$TMPWORK"
+trap - EXIT
diff --git a/lib/keyringer/actions/genpair b/lib/keyringer/actions/genpair
deleted file mode 100755
index 6fc6dcd834fa8ddf8a6c6c97bdd7cb61295d2012..0000000000000000000000000000000000000000
--- a/lib/keyringer/actions/genpair
+++ /dev/null
@@ -1,222 +0,0 @@
-#!/bin/bash
-#
-# Generate keypairs.
-#
-# This script is just a wrapper to easily generate keys for
-# automated systems.
-# 
-
-# Generate a keypair, ssh version
-function genpair_ssh {
-  echo "Make sure that $KEYDIR is atop of an encrypted volume."
-  read -p "Hit ENTER to continue." prompt
-
-  # We're using empty passphrases
-  ssh-keygen -t rsa -b 4096 -P '' -f "$TMPWORK/id_rsa" -C "root@$NODE"
-
-  # Encrypt the result
-  echo "Encrypting secret key into keyringer..."
-  cat "$TMPWORK/id_rsa"     | keyringer_exec encrypt "$BASEDIR" "$FILE"
-  echo "Encrypting public key into keyringer..."
-  cat "$TMPWORK/id_rsa.pub" | keyringer_exec encrypt "$BASEDIR" "$FILE.pub"
-
-  if [ ! -z "$OUTFILE" ]; then
-    mkdir -p `dirname $OUTFILE`
-    printf "Saving copies at %s and %s.pub\n" "$OUTFILE" "$OUTFILE"
-    cat "$TMPWORK/id_rsa"     > "$OUTFILE"
-    cat "$TMPWORK/id_rsa.pub" > "$OUTFILE.pub"
-  fi
-
-  echo "Done"  
-}
-
-# Generate a keypair, gpg version
-function genpair_gpg {
-  echo "Make sure that $KEYDIR is atop of an encrypted volume."
-
-  passphrase="no"
-  passphrase_confirm="confirm"
-
-  while [ "$passphrase" != "$passphrase_confirm" ]; do
-    read -s -p "Enter password for the private key: " passphrase
-    printf "\n"
-    read -s -p "Enter password again: " passphrase_confirm
-    printf "\n"
-
-    if [ "$passphrase" != "$passphrase_confirm" ]; then
-      echo "Password don't match."
-    fi
-  done
-  
-  # TODO: insert random bytes
-  # TODO: custom Name-Comment and Name-Email
-  # TODO: allow for empty passphrases
-  $GPG --homedir "$TMPWORK" --gen-key --batch <<EOF
-    Key-Type: RSA
-    Key-Length: 4096
-    Subkey-Type: ELG-E
-    Subkey-Length: 4096
-    Name-Real: $NODE
-    Name-Email: root@$NODE
-    Expire-Date: 0
-    Passphrase: $passphrase
-    %commit
-EOF
-
-  # Encrypt the result
-  echo "Encrypting secret key into keyringer..."
-  $GPG --armor --homedir "$TMPWORK" --export-secret-keys | keyringer_exec encrypt "$BASEDIR" "$FILE"
-  echo "Encrypting public key into keyringer..."
-  $GPG --armor --homedir "$TMPWORK" --export             | keyringer_exec encrypt "$BASEDIR" "$FILE.pub"
-  echo "Encrypting passphrase into keyringer..."
-  echo "Passphrase for $FILE: $passphrase"               | keyringer_exec encrypt "$BASEDIR" "$FILE.passwd"
-
-  if [ ! -z "$OUTFILE" ]; then
-    mkdir -p `dirname $OUTFILE`
-    printf "Saving copies at %s and %s.pub\n" "$OUTFILE" "$OUTFILE"
-    $GPG --armor --homedir "$TMPWORK" --export-secret-keys > "$OUTFILE"
-    $GPG --armor --homedir "$TMPWORK" --export             > "$OUTFILE.pub"
-  fi
-
-  echo "Done"  
-}
-
-# Generate a keypair, ssl version
-function genpair_ssl {
-  echo "Make sure that $KEYDIR is atop of an encrypted volume."
-  read -p "Hit ENTER to continue." prompt
-
-  # Check for wildcard certs
-  if [ "`echo $NODE | cut -d . -f 1`" == "*" ]; then
-    WILDCARD="yes"
-    CNAME="$NODE"
-    NODE="`echo $NODE | sed -e 's/^\*\.//'`"
-  else
-    CNAME="${NODE}"
-  fi
-
-  # Setup
-  cd "$TMPWORK"
-
-  # Generate certificate
-cat <<EOF >> openssl.conf
-[ req ]
-default_keyfile         = ${NODE}_privatekey.pem
-distinguished_name      = req_distinguished_name
-encrypt_key             = no
-req_extensions          = v3_req # Extensions to add to certificate request
-string_mask             = nombstr
-
-[ req_distinguished_name ]
-commonName_default              = ${CNAME}
-organizationName                = Organization Name
-organizationalUnitName          = Organizational Unit Name
-emailAddress                    = Email Address
-localityName                    = Locality
-stateOrProvinceName             = State
-countryName                     = Country Name
-commonName                      = Common Name
-
-[ v3_req ]
-extendedKeyUsage=serverAuth,clientAuth
-EOF
-
-  # Add SubjectAltNames so wildcard certs can work correctly.
-  if [ "$WILDCARD" == "yes" ]; then
-cat <<EOF >> openssl.conf
-subjectAltName=DNS:${NODE}, DNS:${CNAME}
-EOF
-  fi
-
-  echo "Please review your OpenSSL configuration:"
-  cat openssl.conf
-  read -p "Hit ENTER to continue." prompt
-
-  openssl req -batch -nodes -config openssl.conf -newkey rsa:4096 -sha256 \
-          -keyout ${NODE}_privatekey.pem -out ${NODE}_csr.pem
-
-  openssl req -noout -text -in ${NODE}_csr.pem
-
-  # Self-sign
-  if [ "$KEYTYPE" == "ssl-self" ]; then
-    openssl x509 -in "${NODE}_csr.pem" -out "$NODE.crt" -req -signkey "${NODE}_privatekey.pem" -days 365
-    chmod 600 "${NODE}_privatekey.pem"
-  fi
-
-  # Encrypt the result
-  echo "Encrypting private key into keyringer..."
-  cat "${NODE}_privatekey.pem" | keyringer_exec encrypt "$BASEDIR" "$FILE.pem"
-  echo "Encrypting certificate request into keyringer..."
-  cat "${NODE}_csr.pem"        | keyringer_exec encrypt "$BASEDIR" "$FILE.csr"
-  
-  if [ "$KEYTYPE" == "ssl-self" ]; then
-    echo "Encrypting certificate into keyringer..."
-    cat "${NODE}.crt" | keyringer_exec encrypt "$BASEDIR" "$FILE.crt"
-  elif [ -f "$BASEDIR/keys/$FILE.crt.asc" ]; then
-    # Remove any existing crt
-    keyringer_exec del "$BASEDIR" "$FILE.crt"
-  fi
-
-  cd "$CWD"
-
-  if [ ! -z "$OUTFILE" ]; then
-    mkdir -p `dirname $OUTFILE`
-    printf "Saving copies at %s\n" "`dirname $OUTFILE`"
-    cat "$TMPWORK/${NODE}_privatekey.pem" > "$OUTFILE.pem"
-    cat "$TMPWORK/${NODE}_csr.pem"        > "$OUTFILE.csr"
-
-    if [ -f "$TMPWORK/${NODE}.crt" ]; then
-      cat "$TMPWORK/${NODE}.crt" > "$OUTFILE.crt"
-    fi
-  fi
-
-  # Show cert fingerprint
-  if [ "$KEYTYPE" == "ssl-self" ]; then
-    openssl x509 -noout -in "$TMPWORK/${NODE}.crt" -fingerprint
-  fi
-
-  echo "Done"
-}
-
-# Load functions
-LIB="`dirname $0`/../functions"
-source "$LIB" || exit 1
-
-# Aditional parameters
-KEYTYPE="$2"
-FILE="$RELATIVE_PATH/$3"
-NODE="$4"
-OUTFILE="$5"
-CWD="`pwd`"
-
-# Verify
-if [ -z "$NODE" ]; then
-  echo -e "Usage: keyringer <keyring> $BASENAME <gpg|ssh|ssl|ssl-self> <file> <hostname> [outfile]"
-  echo -e "Options:"
-  echo -e "\t gpg|ssh|ssl[-self]: key type."
-  echo -e "\t file                      : base file name for encrypted output (relative to keys folder),"
-  echo -e "\t                             without spaces"
-  echo -e "\t hostname                  : host for the key pair"
-  echo -e "\t outfile                   : optional unencrypted output file, useful for deployment,"
-  echo -e "\t                             without spaces"
-  exit 1
-elif [ ! -e "$KEYDIR" ]; then
-  echo "Folder not found: $KEYDIR, leaving"
-  exit 1
-fi
-
-# Set a tmp file
-keyringer_set_tmpfile genpair -d
-
-# Dispatch
-echo "Generating $KEYTYPE key for $NODE..."
-if [ "$KEYTYPE" == "ssl-self" ]; then
-  genpair_ssl
-else
-  genpair_"$KEYTYPE"
-fi
-
-# Cleanup
-cd "$CWD"
-rm -rf "$TMPWORK"
-trap - EXIT
diff --git a/lib/keyringer/actions/genpair b/lib/keyringer/actions/genpair
new file mode 120000
index 0000000000000000000000000000000000000000..d936499c2e80b338437644f27ab47275aa3d6698
--- /dev/null
+++ b/lib/keyringer/actions/genpair
@@ -0,0 +1 @@
+genkeys
\ No newline at end of file
diff --git a/lib/keyringer/actions/git b/lib/keyringer/actions/git
index 059b20e14a53a4d4fa59c453b58db0a1a130bb51..218273f729a71eb6830242484650f121ee33f27d 100755
--- a/lib/keyringer/actions/git
+++ b/lib/keyringer/actions/git
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Git wrapper.
 #
diff --git a/lib/keyringer/actions/ls b/lib/keyringer/actions/ls
index 93f5f7541195de8bad73274b7c0dc4c628d7ed6c..b992ad4be620344ef07c9d1757d7c0ddc4570a50 100755
--- a/lib/keyringer/actions/ls
+++ b/lib/keyringer/actions/ls
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # List keys.
 #
diff --git a/lib/keyringer/actions/mkdir b/lib/keyringer/actions/mkdir
index b31eb0b9fee37546ee5d5f6ce75084ff18e466b6..63442a482eb7f300ba22e7860b639c34ef5e7716 100755
--- a/lib/keyringer/actions/mkdir
+++ b/lib/keyringer/actions/mkdir
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Create folders.
 #
diff --git a/lib/keyringer/actions/mv b/lib/keyringer/actions/mv
index daac7b011fbc49aa214c0e963f9d1e52c563d9a5..2324145e6dabeb133ae9f7056e1a49f464248866 100755
--- a/lib/keyringer/actions/mv
+++ b/lib/keyringer/actions/mv
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Move secrets.
 #
diff --git a/lib/keyringer/actions/options b/lib/keyringer/actions/options
index b210e1a811a8aa38d89b593c3f155364a35ee204..eea73e812c4f0f5a97eff719c4c7258695b5a3dd 100755
--- a/lib/keyringer/actions/options
+++ b/lib/keyringer/actions/options
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Repository options management.
 #
diff --git a/lib/keyringer/actions/preferences b/lib/keyringer/actions/preferences
index 114f9ac646e1c22857bca8a318bc7b80ebad1913..6e36ef4e093c9d6f7a89801d795db8d8274327da 100755
--- a/lib/keyringer/actions/preferences
+++ b/lib/keyringer/actions/preferences
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Manipulate user preferences.
 #
diff --git a/lib/keyringer/actions/recipients b/lib/keyringer/actions/recipients
index 414978652f249c22da31e38d139bd7ab112836ef..29f9d3836e15d3b414e762461cdaec03ca3ecf17 100755
--- a/lib/keyringer/actions/recipients
+++ b/lib/keyringer/actions/recipients
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Recipient management.
 #
diff --git a/lib/keyringer/actions/recrypt b/lib/keyringer/actions/recrypt
index 30c925493dc758495cc17d156b36ad6c82cc3798..5dce1ba3e197bfcb53f698e34982a6574422f20f 100755
--- a/lib/keyringer/actions/recrypt
+++ b/lib/keyringer/actions/recrypt
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Re-encrypt files to multiple recipients.
 #
diff --git a/lib/keyringer/actions/rmdir b/lib/keyringer/actions/rmdir
index 398cf11cb03260c23adcf26b46163d69b0967811..da7abe5a2fa414d66bdc714460e56c94da9a5ebd 100755
--- a/lib/keyringer/actions/rmdir
+++ b/lib/keyringer/actions/rmdir
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Remove folders.
 #
diff --git a/lib/keyringer/actions/shell b/lib/keyringer/actions/shell
index ab170b12299bf9e43861c4a9ab3627b87fca0bbf..491fe0a7437a04775b8139a3d1a4c8e25cf39042 100755
--- a/lib/keyringer/actions/shell
+++ b/lib/keyringer/actions/shell
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Interactive shell.
 #
diff --git a/lib/keyringer/actions/teardown b/lib/keyringer/actions/teardown
index 64da740dea68fff951bbfcc3ad97774f0bdb5561..5bfb12101596ce26c8b8e1e8675815c5ccbcdcc2 100755
--- a/lib/keyringer/actions/teardown
+++ b/lib/keyringer/actions/teardown
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Remove a keyring.
 #
diff --git a/lib/keyringer/actions/tree b/lib/keyringer/actions/tree
index 8f9d7cda7b51282df86b2f272800e9886785e00a..9c09bfcd7024882d3d46d4ffdb409f321478ea5e 100755
--- a/lib/keyringer/actions/tree
+++ b/lib/keyringer/actions/tree
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # List keys, tree version.
 #
diff --git a/lib/keyringer/actions/usage b/lib/keyringer/actions/usage
index 2ca7639dd4f6e6171234a1974b85b68ce76d6d7e..15096a0b2e446dae9133103432293efe7193aef4 100755
--- a/lib/keyringer/actions/usage
+++ b/lib/keyringer/actions/usage
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Show available commands
 #
diff --git a/lib/keyringer/actions/xclip b/lib/keyringer/actions/xclip
index 7afdf05ecca79d6dd711a5ac1d0672cf586de2ed..0e60bbd4d5558ad48d2dcff2bb2578b21b678087 100755
--- a/lib/keyringer/actions/xclip
+++ b/lib/keyringer/actions/xclip
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Decrypt secret header to clipboard.
 #
diff --git a/lib/keyringer/completions/bash/keyringer b/lib/keyringer/completions/bash/keyringer
index 27cf919c3b3974b5a96747ed6c86c6346455ec80..fc952eba60c4a27e97c2e8fa85a63a42c47e2b94 100644
--- a/lib/keyringer/completions/bash/keyringer
+++ b/lib/keyringer/completions/bash/keyringer
@@ -93,12 +93,12 @@ _keyringer() {
       recipients)
         opts="ls edit"
         ;;
-      ls|tree|mkdir|encrypt|encrypt-batch|decrypt|edit|append|append-batch|del|rm|recrypt|open|clip|xclip|find)
+      ls|tree|mkdir|encrypt|encrypt-batch|decrypt|edit|append|append-batch|del|rm|recrypt|open|clip|xclip|find|mv|cp)
         cur="`echo ${cur} | sed -e "s|^/*||"`" # avoid leading slash
         opts="$(bash -c "set -f && export KEYRINGER_CHECK_RECIPIENTS=false && export KEYRINGER_CHECK_VERSION=false && keyringer $instance ls -p -d ${cur}*" 2> /dev/null)"
         ;;
-      genpair)
-        opts="gpg ssh ssl ssl-self"
+      genkeys|genpair)
+        opts="gpg ssh x509 x509-self ssl ssl-self"
         ;;
       git)
         opts="$(_keyringer_git_complete ${cur})"
@@ -112,11 +112,15 @@ _keyringer() {
     esac
   elif [ "${#COMP_WORDS[@]}" == "5" ]; then
     case "${command}" in
+      mv|cp)
+        cur="`echo ${cur} | sed -e "s|^/*||"`" # avoid leading slash
+        opts="$(bash -c "set -f && export KEYRINGER_CHECK_RECIPIENTS=false && export KEYRINGER_CHECK_VERSION=false && keyringer $instance ls -p -d ${cur}*" 2> /dev/null)"
+        ;;
       recipients)
         cur="`echo ${cur} | sed -e "s|^/*||"`" # avoid leading slash
         opts="$(cd $path/config/recipients && ls --color=never -p ${cur}* 2> /dev/null)"
         ;;
-      genpair)
+      genkeys|genpair)
         cur="`echo ${cur} | sed -e "s|^/*||"`" # avoid leading slash
         opts="$(bash -c "set -f && export KEYRINGER_CHECK_RECIPIENTS=false && export KEYRINGER_CHECK_VERSION=false && keyringer $instance ls -p -d ${cur}*" 2> /dev/null)"
         ;;
diff --git a/lib/keyringer/completions/zsh/_keyringer b/lib/keyringer/completions/zsh/_keyringer
index ab95c3d4c7e9714f723d4effe4d269bc4a878400..d4b89b12eb03dbef95028191bdeabedc8f12da39 100644
--- a/lib/keyringer/completions/zsh/_keyringer
+++ b/lib/keyringer/completions/zsh/_keyringer
@@ -49,12 +49,12 @@ _keyringer() {
           recipients)
             compadd "$@" ls edit
             ;;
-          ls|tree|mkdir|encrypt|encrypt-batch|decrypt|edit|append|append-batch|del|rm|recrypt|open|clip|xclip|find)
+          ls|tree|mkdir|encrypt|encrypt-batch|decrypt|edit|append|append-batch|del|rm|recrypt|open|clip|xclip|find|mv|cp)
             words[4]="`echo $words[4] | sed -e "s|^/*||"`" # avoid leading slash
             compadd "$@" $(KEYRINGER_CHECK_RECIPIENTS=false KEYRINGER_CHECK_VERSION=false keyringer $words[2] ls -p -d $words[4]'*' 2> /dev/null)
             ;;
-          genpair)
-            compadd "$@" gpg ssh ssl ssl-self
+          genkeys|genpair)
+            compadd "$@" gpg ssh x509 x509-self ssl ssl-self
             ;;
           git)
             compadd "$@" $(_keyringer_git_complete $words[4])
@@ -68,11 +68,15 @@ _keyringer() {
         ;;
       misc)
         case "$words[3]" in
+          mv|cp)
+            words[5]="`echo $words[5] | sed -e "s|^/*||"`" # avoid leading slash
+            compadd "$@" $(KEYRINGER_CHECK_RECIPIENTS=false KEYRINGER_CHECK_VERSION=false keyringer $words[2] ls -p -d $words[5]'*' 2> /dev/null)
+            ;;
           recipients)
             words[5]="$(echo $words[5] | sed -e "s|^/||")" # TODO: avoid leading slash
             compadd "$@" $(cd $keyring_path/config/recipients && ls --color=never -p $words[5]* 2> /dev/null)
             ;;
-          genpair)
+          genkeys|genpair)
             words[5]="$(echo $words[5] | sed -e "s|^/||")" # TODO: avoid leading slash
             compadd "$@" $(KEYRINGER_CHECK_RECIPIENTS=false KEYRINGER_CHECK_VERSION=false keyringer $words[2] ls -p -d $words[5]'*' 2> /dev/null)
             ;;
diff --git a/lib/keyringer/functions b/lib/keyringer/functions
index 42c047d282b32f8b9ffed629d3bf36b764f38a26..ab519b2fa83097b8397c7a7f4a23f95a57f51e61 100755
--- a/lib/keyringer/functions
+++ b/lib/keyringer/functions
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Common functions.
 #
diff --git a/share/man/keyringer.1 b/share/man/keyringer.1
index 82cb520f59254a1324840af1aa40fcde3c950beb..13de0859c8e97272e8ebb70ee5839139d506a679 100644
--- a/share/man/keyringer.1
+++ b/share/man/keyringer.1
@@ -201,13 +201,21 @@ Useful inside scripts.
 .RS
 .RE
 .TP
-.B genpair <\f[I]ssh\f[]|\f[I]gpg\f[]|\f[I]ssl\f[]|\f[I]ssl-self\f[]>
+.B genkeys
+<\f[I]ssh\f[]|\f[I]gpg\f[]|\f[I]x509\f[]|\f[I]x509-self\f[]|\f[I]ssl\f[]|\f[I]ssl-self\f[]>
 [\f[I]options\f[]]
 Wrapper to generate encryption key-pairs, useful for automated key
 deployment.
 .RS
 .RE
 .TP
+.B genpair
+<\f[I]ssh\f[]|\f[I]gpg\f[]|\f[I]x509\f[]|\f[I]x509-self\f[]|\f[I]ssl\f[]|\f[I]ssl-self\f[]>
+[\f[I]options\f[]]
+Alias for \f[I]genkeys\f[] action.
+.RS
+.RE
+.TP
 .B open <\f[I]secret\f[]>
 Decrypt a secret into a temporary folder and open it using xdg-open,
 which tries to figure out the file type and then calls the associated
@@ -377,7 +385,7 @@ so be careful when decrypting secrets and writing them to the disk or
 other storage media.
 .PP
 Pay special attention that keyringer outputs data to stdout, which could
-be easilly spotted by any agent looking directly at you computer screen.
+be easily spotted by any agent looking directly at you computer screen.
 .PP
 The xclip action even copies secret data to the X11 clipboard, which can
 be accessed by any application running in the user\[aq]s X11 session, so
diff --git a/share/man/keyringer.1.mdwn b/share/man/keyringer.1.mdwn
index af098a3b2b7efe37e375e0a6994cbeda16c755e7..55ae216ac2f2b32a7034155c0c6e603e07a5e8de 100644
--- a/share/man/keyringer.1.mdwn
+++ b/share/man/keyringer.1.mdwn
@@ -150,9 +150,12 @@ encrypt-batch <*secret*> [*file*]
 :   Encrypt content, batch mode. Behavior is identical to *encrypt* action, but less
     verbose. Useful inside scripts.
 
-genpair <*ssh*|*gpg*|*ssl*|*ssl-self*> [*options*]
+genkeys <*ssh*|*gpg*|*x509*|*x509-self*|*ssl*|*ssl-self*> [*options*]
 :   Wrapper to generate encryption key-pairs, useful for automated key deployment.
 
+genpair <*ssh*|*gpg*|*x509*|*x509-self*|*ssl*|*ssl-self*> [*options*]
+:   Alias for *genkeys* action.
+
 open <*secret*>
 :   Decrypt a secret into a temporary folder and open it using xdg-open, which
     tries to figure out the file type and then calls the associated application.
@@ -288,7 +291,7 @@ Keyringer currently has the following limitations:
    other storage media.
 
    Pay special attention that keyringer outputs data to stdout, which could
-   be easilly spotted by any agent looking directly at you computer screen.
+   be easily spotted by any agent looking directly at you computer screen.
 
    The xclip action even copies secret data to the X11 clipboard, which can
    be accessed by any application running in the user's X11 session, so use