diff --git a/flake.nix b/flake.nix index 6af21a0..090d630 100644 --- a/flake.nix +++ b/flake.nix @@ -39,6 +39,7 @@ fos-mount = pkgs.writeShellScriptBin "fos-mount" (builtins.readFile ./fos-mount); fos-partitions = pkgs.writeShellScriptBin "fos-partitions" (builtins.readFile ./fos-partitions); fos-renew = pkgs.writeShellScriptBin "fos-renew" (builtins.readFile ./fos-renew); + fos-rotate-passwords = pkgs.writeShellScriptBin "fos-renew" (builtins.readFile ./fos-rotate-passwords); fos-sync = pkgs.writeShellScriptBin "fos-sync" (builtins.readFile ./fos-sync); fos-working-directory = pkgs.writeShellScriptBin "fos-working-directory" (builtins.readFile ./fos-working-directory); openpgp-ca = pkgs.openpgp-ca.overrideAttrs (prevAttrs: rec { diff --git a/fos-renew b/fos-renew old mode 100644 new mode 100755 index aadec23..51cd175 --- a/fos-renew +++ b/fos-renew @@ -26,16 +26,14 @@ if [ -z "$expired_certs" ]; then exit 0 fi -# ensure primary secret without whitespace exists -if [ ! -f /tmp/fos/primary-secret-trimmed ]; then - cat /tmp/fos/primary-secret | tr -d "[:space:]" > /tmp/fos/primary-secret-trimmed -fi - # export current keylist oca -d /tmp/fos/famedly.oca keylist export -fp /tmp/fos/ --sig-uri https://tmp.only # remove unneeded sig rm -f /tmp/fos/tmp.only +# export CA private key +oca -d /tmp/fos/famedly.oca ca private > /tmp/fos/ca-secret.asc + for id in $expired_certs; do email=$(cat /tmp/fos/keylist.json | jq -r ".keys[] | select(.fingerprint == \"${id}\") | .email") name=$(cat /tmp/fos/keylist.json | jq -r ".keys[] | select(.fingerprint == \"${id}\") | .name") @@ -47,18 +45,21 @@ for id in $expired_certs; do sq -q cert import "$archive_path/public.asc" || exit 1 # extend expiration date for public key - sq -q --password-file "/tmp/fos/primary-secret-trimmed" key expire --cert "$id" --expiration 2y || exit 1 + sq -q --password-file "/tmp/fos/primary-secret" key expire --cert "$id" --expiration 2y || exit 1 # extend expiration date for all subkeys of public key subkeys=$(cat $archive_path/public.asc | gpg -q --with-colons --import-options show-only --import | grep "fpr" | tail -n +2 | cut -d ":" -f10) for skid in $subkeys; do echo "sq -q key subkey expire --cert "$id" --key "$skid" --expiration 2y" - sq -q --password-file "/tmp/fos/primary-secret-trimmed" key subkey expire --cert "$id" --key "$skid" --expiration 2y || exit 1 + sq -q --password-file "/tmp/fos/primary-secret" key subkey expire --cert "$id" --key "$skid" --expiration 2y || exit 1 done + # renew certification using the CA private key + sq pki vouch add --expiration 2y --certifier-file /tmp/fos/ca-secret.asc --cert "$id" --userid-by-email "$email" --overwrite --output "$archive_path/public.asc" + # write the new cert and inspect it for review sq cert export --cert "$id" --output "$archive_path/public.asc" --overwrite || exit 1 - sq inspect --cert-file "$archive_path/public.asc" + sq inspect --certifications --cert-file "$archive_path/public.asc" if confirm "update OCA with $archive_path/public.asc and commit file?"; then oca -d /tmp/fos/famedly.oca user update -f "$archive_path/public.asc" || exit 1 diff --git a/fos-rotate-passwords b/fos-rotate-passwords new file mode 100755 index 0000000..e933da5 --- /dev/null +++ b/fos-rotate-passwords @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +function show_help { + cat << EOF +usage: + +fos-rotate-passwords --old /path/to/old-password-file --new /path/to/new-password-file +EOF +} + +function confirm { + while true; do + read -p "$* (y/n): " answer + case $answer in + [Yy]) return 0 ;; + [Nn]) exit 1 ;; + esac + done +} + +while [[ "$#" -gt 0 ]]; do + case $1 in + -o|--old) old="$2"; shift ;; + -n|--new) new="$2"; shift ;; + *) echo "Unknown parameter: $1"; show_help; exit 1 ;; + esac + shift +done + +for var in "old" "new"; do + if [[ -z "${!var}" ]]; then + echo "missing parameter --$var" + show_help + exit 1 + fi +done + +confirm "re-encrypt all keys and PINs in $(fos-working-directory)/archive/ with password $new?" + +secret_keys=$(find $(fos-working-directory)/archive/ -type f -name "secret.asc") +pins=$(find $(fos-working-directory)/archive/ -type f -name "*pin.asc") + +for key in $secret_keys; do + sq key password --batch \ + --password-file $old \ + --new-password-file $new \ + --cert-file $key \ + --output $key \ + --overwrite +done + +for pin in $pins; do + sq decrypt -q --batch \ + --password-file $old \ + $pin |\ + sq encrypt -q --batch \ + --without-signature \ + --with-password-file $new \ + --output $pin \ + --overwrite +done diff --git a/iso.nix b/iso.nix index c957c84..4060013 100644 --- a/iso.nix +++ b/iso.nix @@ -151,6 +151,7 @@ in flake.packages.${system}.fos-mount flake.packages.${system}.fos-partitions flake.packages.${system}.fos-renew + flake.packages.${system}.fos-rotate-passwords flake.packages.${system}.fos-sync flake.packages.${system}.fos-working-directory ];