#!/usr/bin/env zsh # zeasypki -- easy PKI # Copyright (C) 2022-2025 Sergey Matveev setopt ERR_EXIT PIPE_FAIL COUNTRY=${COUNTRY:-RU} path=( ~/work/gogost/cmd/cer-selfsigned-example ~/work/gogost/cmd/cer-dane-hash $path ) key_encrypt() { cmenctool 4<~/.cm/general.pub } key_decrypt() { cmenctool -d 8<~/.cm/general.prv } # ------------------------ >8 ------------------------ usage() { cat >&2 <$tmpl <$key certtool \ --generate-self-signed \ --load-privkey $key \ --template $tmpl \ --outfile $cert reply=(${mapfile[$key]} ${mapfile[$cert]}) } ca_new_ecdsa() { ca_new_xdsa "--key-type=ecdsa --bits 512" $1 } ee_key_new_ecdsa() { certtool_genkey "--key-type=ecdsa --bits 256" } ca_new_eddsa() { ca_new_xdsa "--key-type=ed25519" $1 } ee_key_new_eddsa() { certtool_genkey "--key-type=ed25519" } ee_key_new_gost() { cer-selfsigned-example -cn does-not-matter -ai 256A -only-key } ee_renew_xdsa() { local algo=$1 local ca=$2 local domain=$3 local cakey=`mktemp` local key=`mktemp` local tmpl=`mktemp` local cert=`mktemp` trap "rm -f $cakey $key $tmpl $cert" HUP PIPE INT QUIT TERM EXIT key_get ca/$algo/$ca mapfile[$cakey]=$REPLY key_get ee/$algo/$ca/$domain mapfile[$key]=$REPLY cat >$tmpl <>$cakey cat >>$cakey &2 exit 1 } ca_new_${algo} $domain _umask=`umask` umask 077 mapfile[${dst}/key.pem]=${reply[1]} umask $_umask mapfile[${dst}/cer.pem]=${reply[2]} print $dst ;; (encrypt) [[ $# -eq 2 ]] || usage key=$2/key.pem [[ -s $key ]] || { print no $key found >&2 exit 1 } umask 077 key_encrypt <$key >$key.enc rm $key ;; (new) [[ $# -eq 2 ]] || usage cols=(${(s:/:)2}) algo=${cols[2]} ca=${cols[3]} domain=${cols[4]} dst=ee/$algo/$ca/$domain [[ $dst = $2 ]] zf_mkdir -p $dst [[ ! -s $dst/key.pem ]] || { print $dst/key.pem already exists >&2 exit 1 } _umask=`umask` umask 077 ee_key_new_${algo} >$dst/key.pem umask $_umask ee_renew_${algo} $ca $domain >$dst/cer.pem ;; (renew) [[ $# -eq 2 ]] || usage cols=(${(s:/:)2}) algo=${cols[2]} ca=${cols[3]} domain=${cols[4]} ee_renew_${algo} $ca $domain >ee/$algo/$ca/$domain/cer.pem ;; (dane) [[ $# -eq 2 ]] || usage dane_${${(s:/:)2}[2]} <$2/cer.pem ;; (keypair) [[ $# -eq 2 ]] || usage key_get $2 print -- "$REPLY" cat $2/cer.pem ;; (rem) zmodload -F zsh/datetime b:strftime export LC_ALL=C for cer (**/cer.pem) { certtool --certificate-info <$cer | while read line ; do [[ ! $line =~ "^Not After: .*" ]] || break done [[ $MATCH ]] # Not After: Sat Jul 02 10:02:29 UTC 2022 cols=(${=MATCH}) strftime -s ts_ugly -r "%b %d %H:%M:%S UTC %Y" ${(j: :)cols[4,-1]} strftime -s ts_good %F $ts_ugly print REM $ts_good +30 MSG $cer } ;; (list) print -C1 ee/*/*/*(/on) ;; (list-ca) print -C1 ca/*/*(/on) ;; (*) usage ;; esac