From dc8fe54203e7353c5f873ef20a1b85c4c7a00b17 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 11 Apr 2025 08:27:11 +0200 Subject: update --- bin/crypt | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100755 bin/crypt (limited to 'bin') diff --git a/bin/crypt b/bin/crypt new file mode 100755 index 0000000..01e7a31 --- /dev/null +++ b/bin/crypt @@ -0,0 +1,36 @@ +#!/bin/sh + +# (de)crypt using ssh rsa key. ed25519 not supported. + +tmp="/tmp/enc-$$" +mkdir -p "$tmp" +trap 'rm -rf $tmp' INT TERM EXIT + +# Encrypt stdin to stdout. +encrypt() { + # Generate a random 256 bits one-time key, for symmetric aes encryption. + openssl rand 32 >"$tmp/key" + + # Output the one-time key asymmetrically encrypted with the rsa pubkey. + ssh-keygen -e -f ~/.ssh/id_rsa.pub -m PKCS8 >"$tmp/pk" + openssl pkeyutl -encrypt -pubin -inkey "$tmp/pk" <"$tmp/key" + + # Now encrypt stdin to stdout, using the clear otk. + openssl aes-256-cbc -pbkdf2 -pass "file:$tmp/key" +} + +# Decrypt stdin to stdout. +decrypt() { + # The first 256 input bytes contains the one time key to be decrypted + # with the private rsa key. + dd ibs=256 count=1 iflag=direct | + openssl pkeyutl -decrypt -inkey ~/.ssh/id_rsa -out "$tmp/key" + + # The remaining input is the payload decrypted with the aes key. + openssl aes-256-cbc -d -pbkdf2 -pass "file:$tmp/key" +} + +cmd=encrypt +[ "$1" = "-d" ] && cmd=decrypt && shift +[ "$1" ] && exec 0<"$1" +"$cmd" -- cgit v1.2.3 From b7927432c7574abb47425fd1af5e7d8ab8fc936c Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 11 Apr 2025 13:33:08 +0200 Subject: improve crypt --- bin/crypt | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) (limited to 'bin') diff --git a/bin/crypt b/bin/crypt index 01e7a31..939f3f5 100755 --- a/bin/crypt +++ b/bin/crypt @@ -1,36 +1,53 @@ #!/bin/sh -# (de)crypt using ssh rsa key. ed25519 not supported. +usage='Usage: crypt [-de] [-o output] [input] -tmp="/tmp/enc-$$" -mkdir -p "$tmp" -trap 'rm -rf $tmp' INT TERM EXIT +Encrypt or decrypt input (default: stdin) to ouput (default: stdout), +using ssh rsa key. + +Options: + -d action is decrypt (default: encrypt) + -e action is encrypt + -o output set ouput (default: stdout)' + +key="$(mktemp)" +trap 'rm -f $key' EXIT # Encrypt stdin to stdout. encrypt() { # Generate a random 256 bits one-time key, for symmetric aes encryption. - openssl rand 32 >"$tmp/key" + openssl rand 32 >"$key" + + # Convert (only once) the ssh RSA public to PKCS8, for openssl. + [ -f ~/.ssh/id_rsa.pub.pkcs8 ] || + ssh-keygen -e -f ~/.ssh/id_rsa.pub -m PKCS8 >~/.ssh/id_rsa.pub.pkcs8 # Output the one-time key asymmetrically encrypted with the rsa pubkey. - ssh-keygen -e -f ~/.ssh/id_rsa.pub -m PKCS8 >"$tmp/pk" - openssl pkeyutl -encrypt -pubin -inkey "$tmp/pk" <"$tmp/key" + openssl pkeyutl -encrypt -pubin -inkey ~/.ssh/id_rsa.pub.pkcs8 <"$key" # Now encrypt stdin to stdout, using the clear otk. - openssl aes-256-cbc -pbkdf2 -pass "file:$tmp/key" + openssl aes-256-cbc -pbkdf2 -pass "file:$key" } # Decrypt stdin to stdout. decrypt() { - # The first 256 input bytes contains the one time key to be decrypted - # with the private rsa key. - dd ibs=256 count=1 iflag=direct | - openssl pkeyutl -decrypt -inkey ~/.ssh/id_rsa -out "$tmp/key" + # Recover the aes key from the first 256 input bytes. + dd ibs=256 count=1 iflag=direct status=none | + openssl pkeyutl -decrypt -inkey ~/.ssh/id_rsa -out "$key" - # The remaining input is the payload decrypted with the aes key. - openssl aes-256-cbc -d -pbkdf2 -pass "file:$tmp/key" + # The remaining input is the payload, decrypt it with the aes key. + openssl aes-256-cbc -d -pbkdf2 -pass "file:$key" } cmd=encrypt -[ "$1" = "-d" ] && cmd=decrypt && shift -[ "$1" ] && exec 0<"$1" +while getopts :deo: opt; do + case $opt in + d) cmd=decrypt ;; + e) cmd=encrypt ;; + o) exec 1>"$OPTARG" ;; + *) echo "$usage" >&2; exit 1 ;; + esac +done +shift $((OPTIND - 1)) +[ "$1" ] && [ "$1" != "-" ] && exec 0<"$1" "$cmd" -- cgit v1.2.3 From 6b2ff5de7a85ac0dd21c4e6a3c6871099182d8ee Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sun, 13 Apr 2025 20:03:35 +0200 Subject: cle --- bin/cle | 42 ++++++++++++++++++++++++++++++++++++++++++ bin/crypt | 8 +++----- 2 files changed, 45 insertions(+), 5 deletions(-) create mode 100755 bin/cle (limited to 'bin') diff --git a/bin/cle b/bin/cle new file mode 100755 index 0000000..63a7153 --- /dev/null +++ b/bin/cle @@ -0,0 +1,42 @@ +#!/bin/sh -C + +clip() { print "$1" | tee /dev/tty | head -n 1 | pbcopy; } + +del() { rm -i ~/.cle/"$1"; } + +die() { echo "$@" >&2; exit 1; } + +edit() { + [ "$1" ] || die 'missing argument' + tmp=$(mktemp) f=~/.cle/"$1" + trap 'rm -f "$tmp"' EXIT + print "$1" >| "$tmp" || mkdir -p "${f%/*}" + [ -s "$tmp" ] || gen >| "$tmp" + "${EDITOR:-vim}" "$tmp" + crypt "$tmp" >| "$f" +} + +gen() { LC_ALL=C tr -dc 'A-Za-z0-9!?%=' < /dev/urandom | head -c 10; } + +list() { cd ~/.cle && find -- * -type f; } + +print() { [ -f ~/.cle/"$1" ] && crypt -d < ~/.cle/"$1"; } + +tui() { + list | fzf --preview 'cle print {}' \ + --preview-window hidden \ + --header 'ctrl-del: delete, ctrl-e: edit, ctrl-n: new' \ + --bind 'ctrl-delete:execute(cle del {})+reload(cle list)' \ + --bind 'ctrl-e:execute(cle edit {})' \ + --bind 'ctrl-n:execute(cle edit {q})+reload(cle list)' \ + --bind 'ctrl-v:toggle-preview' \ + --query "$1" --select-1 | + xargs cle clip +} + +case $1 in + (clip|del|edit|gen|list|print) + cmd=$1; shift; $cmd "$@" ;; + (*) + tui "$@" ;; +esac diff --git a/bin/crypt b/bin/crypt index 939f3f5..c63d60a 100755 --- a/bin/crypt +++ b/bin/crypt @@ -1,13 +1,12 @@ #!/bin/sh -usage='Usage: crypt [-de] [-o output] [input] +usage='Usage: crypt [-d] [-o output] [input] Encrypt or decrypt input (default: stdin) to ouput (default: stdout), using ssh rsa key. Options: -d action is decrypt (default: encrypt) - -e action is encrypt -o output set ouput (default: stdout)' key="$(mktemp)" @@ -40,14 +39,13 @@ decrypt() { } cmd=encrypt -while getopts :deo: opt; do +while getopts :do: opt; do case $opt in d) cmd=decrypt ;; - e) cmd=encrypt ;; o) exec 1>"$OPTARG" ;; *) echo "$usage" >&2; exit 1 ;; esac done shift $((OPTIND - 1)) -[ "$1" ] && [ "$1" != "-" ] && exec 0<"$1" +[ "$1" ] && exec 0<"$1" "$cmd" -- cgit v1.2.3 From 5ec6897410333a16f3ecc3f572b6d7dc490168d9 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Mon, 14 Apr 2025 10:29:17 +0200 Subject: update --- bin/cle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'bin') diff --git a/bin/cle b/bin/cle index 63a7153..b0dccbc 100755 --- a/bin/cle +++ b/bin/cle @@ -1,4 +1,4 @@ -#!/bin/sh -C +#!/bin/sh -Ce clip() { print "$1" | tee /dev/tty | head -n 1 | pbcopy; } @@ -25,11 +25,11 @@ print() { [ -f ~/.cle/"$1" ] && crypt -d < ~/.cle/"$1"; } tui() { list | fzf --preview 'cle print {}' \ --preview-window hidden \ - --header 'ctrl-del: delete, ctrl-e: edit, ctrl-n: new' \ + --header 'Ret Select, Esc Cancel, ^E Edit, ^N New, ^P Preview, ^Del Delete' \ --bind 'ctrl-delete:execute(cle del {})+reload(cle list)' \ --bind 'ctrl-e:execute(cle edit {})' \ --bind 'ctrl-n:execute(cle edit {q})+reload(cle list)' \ - --bind 'ctrl-v:toggle-preview' \ + --bind 'ctrl-p:toggle-preview' \ --query "$1" --select-1 | xargs cle clip } -- cgit v1.2.3 From 197f065a22a712d20d91862cbfb6ef4615774b4d Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Tue, 15 Apr 2025 16:09:54 +0200 Subject: update --- bin/cle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/cle b/bin/cle index b0dccbc..af18e89 100755 --- a/bin/cle +++ b/bin/cle @@ -18,7 +18,7 @@ edit() { gen() { LC_ALL=C tr -dc 'A-Za-z0-9!?%=' < /dev/urandom | head -c 10; } -list() { cd ~/.cle && find -- * -type f; } +list() { cd ~/.cle && find -- * -name .git -prune -o -type f -print; } print() { [ -f ~/.cle/"$1" ] && crypt -d < ~/.cle/"$1"; } -- cgit v1.2.3 From 0616e0cc96c141a686a4a4a3c1d1391e8b43b356 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Wed, 16 Apr 2025 17:42:53 +0200 Subject: improve crypt --- bin/crypt | 60 +++++++++++++++++++++++++++--------------------------------- 1 file changed, 27 insertions(+), 33 deletions(-) (limited to 'bin') diff --git a/bin/crypt b/bin/crypt index c63d60a..64afc42 100755 --- a/bin/crypt +++ b/bin/crypt @@ -1,51 +1,45 @@ #!/bin/sh -usage='Usage: crypt [-d] [-o output] [input] +crypt_usage='Usage: crypt [-d] [-o output] [input] -Encrypt or decrypt input (default: stdin) to ouput (default: stdout), -using ssh rsa key. +Encrypt or decrypt input (stdin) to ouput (stdout), using ssh rsa key. Options: -d action is decrypt (default: encrypt) -o output set ouput (default: stdout)' -key="$(mktemp)" -trap 'rm -f $key' EXIT - # Encrypt stdin to stdout. encrypt() { - # Generate a random 256 bits one-time key, for symmetric aes encryption. - openssl rand 32 >"$key" - - # Convert (only once) the ssh RSA public to PKCS8, for openssl. - [ -f ~/.ssh/id_rsa.pub.pkcs8 ] || - ssh-keygen -e -f ~/.ssh/id_rsa.pub -m PKCS8 >~/.ssh/id_rsa.pub.pkcs8 + set -- "$(openssl rand -hex 32)" - # Output the one-time key asymmetrically encrypted with the rsa pubkey. - openssl pkeyutl -encrypt -pubin -inkey ~/.ssh/id_rsa.pub.pkcs8 <"$key" + echo "$1" | openssl pkeyutl -encrypt -pubin -inkey /dev/fd/3 3<<- EOF + $(ssh-keygen -e -f ~/.ssh/id_rsa.pub -m PKCS8) + EOF - # Now encrypt stdin to stdout, using the clear otk. - openssl aes-256-cbc -pbkdf2 -pass "file:$key" + openssl aes-256-cbc -pbkdf2 -pass file:/dev/fd/3 3<<- EOF + $1 + EOF } # Decrypt stdin to stdout. decrypt() { - # Recover the aes key from the first 256 input bytes. - dd ibs=256 count=1 iflag=direct status=none | - openssl pkeyutl -decrypt -inkey ~/.ssh/id_rsa -out "$key" - - # The remaining input is the payload, decrypt it with the aes key. - openssl aes-256-cbc -d -pbkdf2 -pass "file:$key" + openssl aes-256-cbc -d -pbkdf2 -pass file:/dev/fd/3 3<<- EOF + $(dd ibs=256 count=1 iflag=direct status=none | + openssl pkeyutl -decrypt -inkey ~/.ssh/id_rsa) + EOF } -cmd=encrypt -while getopts :do: opt; do - case $opt in - d) cmd=decrypt ;; - o) exec 1>"$OPTARG" ;; - *) echo "$usage" >&2; exit 1 ;; - esac -done -shift $((OPTIND - 1)) -[ "$1" ] && exec 0<"$1" -"$cmd" +# Execute main only if not sourced. +if [ "${0##*/}" = "crypt" ]; then + cmd=encrypt + while getopts :do: opt; do + case $opt in + d) cmd=decrypt ;; + o) exec 1>"$OPTARG" ;; + *) echo "$crypt_usage" >&2; exit 1 ;; + esac + done + shift $((OPTIND - 1)) + [ "$1" ] && exec 0<"$1" + "$cmd" +fi -- cgit v1.2.3 From 932179c84fd566d821e05da91c4924d7cb0e591f Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Wed, 16 Apr 2025 19:25:29 +0200 Subject: update --- bin/cle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/cle b/bin/cle index af18e89..1ff9dd0 100755 --- a/bin/cle +++ b/bin/cle @@ -13,7 +13,7 @@ edit() { print "$1" >| "$tmp" || mkdir -p "${f%/*}" [ -s "$tmp" ] || gen >| "$tmp" "${EDITOR:-vim}" "$tmp" - crypt "$tmp" >| "$f" + crypt < "$tmp" >| "$f" } gen() { LC_ALL=C tr -dc 'A-Za-z0-9!?%=' < /dev/urandom | head -c 10; } -- cgit v1.2.3 From ba6dd3256c9508ed0c71c7f3346d910803d54a46 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Thu, 17 Apr 2025 21:19:07 +0200 Subject: update --- bin/cle | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/cle b/bin/cle index 1ff9dd0..b26d8b7 100755 --- a/bin/cle +++ b/bin/cle @@ -2,7 +2,14 @@ clip() { print "$1" | tee /dev/tty | head -n 1 | pbcopy; } -del() { rm -i ~/.cle/"$1"; } +checkpath() { set -- $(realpath "$1"); [ "${1#~/.cle/}" != "$1" ]; } + +del() { + set -- ~/.cle/"$1" + checkpath "$1" || die "invalid path $1" + rm -i "$1" + rmdir -p "${1%/*}" 2>/dev/null || true +} die() { echo "$@" >&2; exit 1; } -- cgit v1.2.3 From 733d2209b0c78adaf55baf26b4aa67ef08f057ab Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 25 Apr 2025 16:49:35 +0200 Subject: update --- bin/cle | 50 +------------------------------------------------- 1 file changed, 1 insertion(+), 49 deletions(-) mode change 100755 => 120000 bin/cle (limited to 'bin') diff --git a/bin/cle b/bin/cle deleted file mode 100755 index b26d8b7..0000000 --- a/bin/cle +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -Ce - -clip() { print "$1" | tee /dev/tty | head -n 1 | pbcopy; } - -checkpath() { set -- $(realpath "$1"); [ "${1#~/.cle/}" != "$1" ]; } - -del() { - set -- ~/.cle/"$1" - checkpath "$1" || die "invalid path $1" - rm -i "$1" - rmdir -p "${1%/*}" 2>/dev/null || true -} - -die() { echo "$@" >&2; exit 1; } - -edit() { - [ "$1" ] || die 'missing argument' - tmp=$(mktemp) f=~/.cle/"$1" - trap 'rm -f "$tmp"' EXIT - print "$1" >| "$tmp" || mkdir -p "${f%/*}" - [ -s "$tmp" ] || gen >| "$tmp" - "${EDITOR:-vim}" "$tmp" - crypt < "$tmp" >| "$f" -} - -gen() { LC_ALL=C tr -dc 'A-Za-z0-9!?%=' < /dev/urandom | head -c 10; } - -list() { cd ~/.cle && find -- * -name .git -prune -o -type f -print; } - -print() { [ -f ~/.cle/"$1" ] && crypt -d < ~/.cle/"$1"; } - -tui() { - list | fzf --preview 'cle print {}' \ - --preview-window hidden \ - --header 'Ret Select, Esc Cancel, ^E Edit, ^N New, ^P Preview, ^Del Delete' \ - --bind 'ctrl-delete:execute(cle del {})+reload(cle list)' \ - --bind 'ctrl-e:execute(cle edit {})' \ - --bind 'ctrl-n:execute(cle edit {q})+reload(cle list)' \ - --bind 'ctrl-p:toggle-preview' \ - --query "$1" --select-1 | - xargs cle clip -} - -case $1 in - (clip|del|edit|gen|list|print) - cmd=$1; shift; $cmd "$@" ;; - (*) - tui "$@" ;; -esac diff --git a/bin/cle b/bin/cle new file mode 120000 index 0000000..a0092cf --- /dev/null +++ b/bin/cle @@ -0,0 +1 @@ +../.cle/cle \ No newline at end of file -- cgit v1.2.3