From 0cd81cb99e4b609d227fd19f7aebb9d18c1522b7 Mon Sep 17 00:00:00 2001 From: mrjk Date: Wed, 28 Feb 2018 00:14:45 -0500 Subject: [PATCH] Dev: gpg improvements Done: * Echo log message to stderr * Fix missing pgp files in git autoscan * Add mod_gpg help * Semi automate gpg identity creation * Add a header function for mod_gpg * Enable gpg gen-key in bastch mode * Add gpg config safe standard autogenration --- lib/idm_lib_std.sh | 2 +- lib/idmgr_mod_git.sh | 13 +++++- lib/idmgr_mod_gpg.sh | 103 +++++++++++++++++++++++++++++++++++++----- shell/gpg-agent_conf | 0 shell/gpg_conf | 104 +++++++++++++++++++++++++++++++++++++++++++ shell/gpg_gen.tpl | 16 +++++++ 6 files changed, 225 insertions(+), 13 deletions(-) create mode 100644 shell/gpg-agent_conf create mode 100644 shell/gpg_conf create mode 100644 shell/gpg_gen.tpl diff --git a/lib/idm_lib_std.sh b/lib/idm_lib_std.sh index 0c969b6..25db80c 100644 --- a/lib/idm_lib_std.sh +++ b/lib/idm_lib_std.sh @@ -208,7 +208,7 @@ lib_log () esac if [[ -n "$level" ]]; then - printf "$color%*.6s$reset: %s\n" 6 "${level}_____" "$msg" >&2 + >&2 printf "$color%*.6s$reset: %s\n" 6 "${level}_____" "$msg" # >&2 else echo "Error while log output msg: $msg" fi diff --git a/lib/idmgr_mod_git.sh b/lib/idmgr_mod_git.sh index 3411f11..458638d 100644 --- a/lib/idmgr_mod_git.sh +++ b/lib/idmgr_mod_git.sh @@ -374,13 +374,24 @@ idm_git_get_files_of_interest () find_args="-maxdepth 2 -type f " { + # ssh find $HOME/.ssh/ $find_args -name "${id}*" 2>/dev/null find $HOME/.ssh/known_hosts.d/ $find_args -name "${id}*" 2>/dev/null + + # Openstack find $HOME/.openstack/$id/ $find_args 2>/dev/null - find $GNUPGHOME/private-keys-v1.d/ $find_args 2>/dev/null + + # GPG + find $GNUPGHOME $find_args 2>/dev/null + + # Pass find $PASSWORD_STORE_DIR/ $find_args 2>/dev/null + + # IDM find $IDM_DIR_ID/ $find_args -name "$id*" 2>/dev/null find $IDM_CONFIG_DIR/ $find_args -name "*$id*" 2>/dev/null + + # Git echo "${git_id_config}" } | sed -E "s@$HOME/?@@g" diff --git a/lib/idmgr_mod_gpg.sh b/lib/idmgr_mod_gpg.sh index 483ba9b..c515f5e 100644 --- a/lib/idmgr_mod_gpg.sh +++ b/lib/idmgr_mod_gpg.sh @@ -5,7 +5,15 @@ IDM_MOD_DEPS="id" idm_gpg__help () { - echo "Not implemented yet" + local id=$1 + + echo "gpg" + printf " %-20s: %s\n" "gpg ls" "Show private keys" + printf " %-20s: %s\n" "gpg init " "Create new identity" + printf " %-20s: %s\n" "gpg new " "Create new sub-identity" + printf " %-20s: %s\n" "gpg del" "Delete identity" + echo "" + } ## Required functions @@ -76,7 +84,11 @@ idm_gpg__new () { local id=${1} lib_id_is_enabled $id - key="$( idm_gpg_match_one_pubkey $id )" + key="$( idm_gpg_match_one_pubkey $id )" 2>/dev/null || + { + lib_log ERR "You need to have a valid key${key:+: '$key'}" + return 1 + } idm_gpg_cli_helper $id sub gpg --edit-key $key addkey @@ -89,16 +101,57 @@ idm_gpg__init () { local id=${1} lib_id_is_enabled $id + idm_gpg_header $id ! idm_gpg_match_one_pubkey $id &>/dev/null || \ idm_exit 1 "You already have an id !" + # Check entropy + [ "$( cat /proc/sys/kernel/random/entropy_avail || echo 0)" -lt 3000 ] && + lib_log ERR "You are low in entropy, operation may never end up :/" + # Generate top secret id idm_gpg_cli_helper $id main - gpg --gen-key + + ( + # Get config + eval "$( lib_id_get_config $id )" + + if [ ${#common_name} -lt 5 ]; then + + if [ ${#id} -lt 5 ]; then + key_name=$email + else + key_name=$id + fi + else + key_name=$common_name + fi + + # Parse file + key_type=RSA \ + key_lenght=4096 \ + subkey_type=RSA\ + subkey_lenght=4096 \ + key_name=$key_name \ + key_email=$email \ + key_expire=2y \ + key_sec=$gpghome/$id.enc \ + key_pub=$gpghome/$id.pub \ + envsubst < $IDM_DIR_ROOT/shell/gpg_gen.tpl > $IDM_DIR_CACHE/gpg_gen_$id + ) + + # Generate key + gpg --batch --gen-key $IDM_DIR_CACHE/gpg_gen_$id + #gpg --verbose --batch --gen-key $IDM_DIR_CACHE/gpg_gen_$id + #echo $? + #gpg --gen-key + #gpg --full-generate-key # Generate encyption key - idm_gpg_new $id + #idm_gpg__new $id + + # See:https://gist.github.com/TheFox/cf3e67984ea794e612d5 lib_log NOTICE "Your personal key $name is ready :)" } @@ -109,11 +162,15 @@ idm_gpg__del () local id=${1} local key=${2:-$1} + # TOFIX: + # It is not clear here if we delete private or public keys! + # Scan key key=$(idm_gpg_match_one_pubkey $key) - lib_log WARN "Do you really want to destroy the '$key' key?" - idm_cli_timeout 1 || rc=$? + # Gpg is annoying enough ... + #lib_log WARN "Do you really want to destroy the '$key' key?" + #idm_cli_timeout 1 || rc=$? gpg --delete-key "$key" || true gpg --delete-secret-key "$key" || true @@ -121,17 +178,41 @@ idm_gpg__del () } +idm_gpg__config () +{ + local id=$1 + idm_gpg_header $id + + # See: + # https://lecorvaisier.ca/2018/02/21/signing-your-commits-with-gpg/ + # https://blog.eleven-labs.com/en/openpgp-almost-perfect-key-pair-part-1/ + # https://blog.tinned-software.net/create-gnupg-key-with-sub-keys-to-sign-encrypt-authenticate/ + # Best practices: https://blog.josefsson.org/tag/gpg-agent/ + + envsubst < $IDM_DIR_ROOT/shell/gpg_conf > $gpgconf + + +} + ## Internal functions ########################################## +idm_gpg_header () +{ + local id=${1} + runtime=${XDG_RUNTIME_DIR}/pgp-agent/$id + gpghome=~/.config/gpg/$id + gpgconf=$gpghome/gpg.conf + + export GPG_TTY=$(tty) + export GNUPGHOME=$gpghome + +} + idm_gpg_start () { local id=${1} - local gpghome=~/.config/gpg/$id - local runtime=${XDG_RUNTIME_DIR}/pgp-agent/$id - - export GPG_TTY=$(tty) - export GNUPGHOME=$gpghome + idm_gpg_header $id # Ensure directories exist if [ ! -d "$GNUPGHOME" ]; then diff --git a/shell/gpg-agent_conf b/shell/gpg-agent_conf new file mode 100644 index 0000000..e69de29 diff --git a/shell/gpg_conf b/shell/gpg_conf new file mode 100644 index 0000000..63c2d72 --- /dev/null +++ b/shell/gpg_conf @@ -0,0 +1,104 @@ +# GnuPG Options +# (OpenPGP-Configuration-Options) + +# Assume that command line arguments are given as UTF8 strings. +utf8-strings + + +# ### (OpenPGP-Esoteric-Options) +# ============================================ +# +# Use name as the message digest algorithm used when signing a key. Running the +# program with the command --version yields a list of supported algorithms. Be +# aware that if you choose an algorithm that GnuPG supports but other OpenPGP +# implementations do not, then some users will not be able to use the key +# signatures you make, or quite possibly your entire key. +# +# SHA-1 is the only algorithm specified for OpenPGP V4. By changing the +# cert-digest-algo, the OpenPGP V4 specification is not met but with even +# GnuPG 1.4.10 (release 2009) supporting SHA-2 algorithm, this should be safe. +# Source: https://tools.ietf.org/html/rfc4880#section-12.2 +cert-digest-algo SHA512 +digest-algo SHA256 +# digest-algo SHA512 stronger + +# Selects how passphrases for symmetric encryption are mangled. 3 (the default) +# iterates the whole process a number of times (see --s2k-count). +s2k-mode 3 + + +# ### (OpenPGP-Protocol-Options) +# ============================================ +# +# Use name as the cipher algorithm for symmetric encryption with a passphrase +# if --personal-cipher-preferences and --cipher-algo are not given. The +# default is AES-128. +s2k-cipher-algo AES256 + +# Use name as the digest algorithm used to mangle the passphrases for symmetric +# encryption. The default is SHA-1. +s2k-digest-algo SHA512 + +# Specify how many times the passphrases mangling for symmetric encryption is +# repeated. This value may range between 1024 and 65011712 inclusive. The +# default is inquired from gpg-agent. Note that not all values in the +# 1024-65011712 range are legal and if an illegal value is selected, GnuPG will +# round up to the nearest legal value. This option is only meaningful if +# --s2k-mode is set to the default of 3. +s2k-count 1015808 +#s2k-count 65011712 + +# Set the list of personal digest/cipher/compression preferences. This allows +# the user to safely override the algorithm chosen by the recipient key +# preferences, as GPG will only select an algorithm that is usable by all +# recipients. +personal-digest-preferences SHA512 SHA384 SHA256 SHA224 +# personal-digest-preferences SHA512 #stronger +personal-cipher-preferences AES256 AES192 AES CAST5 CAMELLIA192 BLOWFISH TWOFISH CAMELLIA128 3DES +#personal-cipher-preferences AES256 #stronger +personal-compress-preferences ZLIB BZIP2 ZIP + +# Set the list of default preferences to string. This preference list is used +# for new keys and becomes the default for "setpref" in the edit menu. +default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed +# default-preference-list SHA512 SHA384 SHA256 RIPEMD160 AES256 TWOFISH BLOWFISH ZLIB BZIP2 ZIP Uncompressed # Stronger?Weaker? + + +# ### GnuPG View Options +# ============================================ +# +# Select how to display key IDs. "long" is the more accurate (but less +# convenient) 16-character key ID. Add an "0x" to include an "0x" at the +# beginning of the key ID. +keyid-format 0xlong + +# List all keys with their fingerprints. This is the same output as --list-keys +# but with the additional output of a line with the fingerprint. If this +# command is given twice, the fingerprints of all secondary keys are listed too. +with-fingerprint + + +# ### Sources: +# https://blog.tinned-software.net/create-gnupg-key-with-sub-keys-to-sign-encrypt-authenticate/ +# https://blog.eleven-labs.com/en/openpgp-almost-perfect-key-pair-part-1/ + + +# Other + +# Avoid information leaked +no-emit-version +no-comments +export-options export-minimal + +# Displays the validity of the keys +list-options show-uid-validity +verify-options show-uid-validity + +# Limits the algorithms used + +cipher-algo AES256 +compress-algo ZLIB + +disable-cipher-algo 3DES +weak-digest SHA1 + diff --git a/shell/gpg_gen.tpl b/shell/gpg_gen.tpl new file mode 100644 index 0000000..d3a7cb4 --- /dev/null +++ b/shell/gpg_gen.tpl @@ -0,0 +1,16 @@ +%echo Generating new identity for $id: +%echo id : $key_name ($key_email) +%echo strengh : $key_type $key_lenght +%echo files : $key_sec $key_pub +%ask-passphrase +Key-Type: $key_type +Key-Length: $key_lenght +Key-Usage: sign +Subkey-Type: $subkey_type +Subkey-Length: $subkey_lenght +Subkey-Usage: encrypt,sign,auth +Name-Real: $key_name +Name-Email: $key_email +Expire-Date: $key_expire +%commit +%echo done