3 # Copyright (C) 2022 Sergey Matveev <stargrave@stargrave.org>
7 KEY_ENCRYPT_RECIPIENT=${KEY_ENCRYPT_RECIPIENT:-CF60E89A59231E76E2636422AE1A8109E49857EF}
10 # Turn on PyGOST utilities
11 path=(~/local/stow/py310/bin ~/work/pygost/pygost/asn1schemas $path)
12 export -TU PYTHONPATH pythonpath
13 pythonpath=(~/work/pygost ~/work/pyderasn)
16 gpg --encrypt --recipient $KEY_ENCRYPT_RECIPIENT
23 # ------------------------ >8 ------------------------
28 \$ $0:t ca [ecdsa|gost] NAME -- new CA keypair
29 \$ $0:t list-ca -- list CA keypairs
30 \$ $0:t list -- list EE ones
31 \$ $0:t rem -- list certificate expirations
32 \$ $0:t new KEY -- new EE
33 \$ $0:t renew KEY -- renew EE
34 \$ $0:t dane KEY -- show DANE SHA256 hash
35 \$ $0:t encrypt KEY -- encrypt private key
36 \$ $0:t keypair KEY -- PEM-encoded full keypair
41 zmodload -F zsh/files b:zf_mkdir
45 [[ -s $1/key.pem ]] &&
46 REPLY=`< ${1}/key.pem` ||
47 REPLY=`key_decrypt < ${1}/key.pem.enc`
51 certtool --generate-privkey --ecc --bits $1 --no-text
59 trap "rm -f $key $tmpl $cert" HUP PIPE INT QUIT TERM EXIT
61 dn = "cn=$domain,c=$COUNTRY"
63 expiration_days = 3650
67 certtool_genkey 512 > $key
69 --generate-self-signed \
73 reply=(${mapfile[$key]} ${mapfile[$cert]})
81 cert-selfsigned-example.py --cn does-not-matter --ai 256A --only-key
91 trap "rm -f $cakey $key $tmpl $cert" HUP PIPE INT QUIT TERM EXIT
93 mapfile[$cakey]=$REPLY
94 key_get ee/ecdsa/$ca/$domain
97 dn = "cn=$domain,c=RU"
103 --load-ca-certificate ca/ecdsa/$ca/cer.pem \
104 --load-ca-privkey $cakey \
105 --generate-certificate \
106 --load-privkey $key \
116 trap "rm -f $cakey $key $cert" HUP PIPE INT QUIT TERM EXIT
118 mapfile[$cakey]=$REPLY
119 >> $cakey < ca/gost/$ca/cer.pem
120 key_get ee/gost/$ca/$domain
122 cert-selfsigned-example.py \
123 --issue-with $cakey \
125 --cn $domain --country $COUNTRY --ai 256A
132 trap "rm -f $key $cert" HUP PIPE INT QUIT TERM EXIT
133 cert-selfsigned-example.py \
141 reply=(${mapfile[$key]} ${mapfile[$cert]})
145 certtool --key-id --hash=sha256
154 [[ $# -eq 3 ]] || usage
159 [[ -s $dst/key.pem ]] && {
160 print $dst/key.pem already exists >&2
163 ca_new_${algo} $domain
166 mapfile[${dst}/key.pem]=${reply[1]}
168 mapfile[${dst}/cer.pem]=${reply[2]}
172 [[ $# -eq 2 ]] || usage
175 print no $key found >&2
179 key_encrypt < $key > $key.enc
183 [[ $# -eq 2 ]] || usage
188 dst=ee/$algo/$ca/$domain
191 [[ -s $dst/key.pem ]] && {
192 print $dst/key.pem already exists >&2
197 ee_key_new_${algo} > $dst/key.pem
199 ee_renew_${algo} $ca $domain > $dst/cer.pem
202 [[ $# -eq 2 ]] || usage
207 ee_renew_${algo} $ca $domain > ee/$algo/$ca/$domain/cer.pem
210 [[ $# -eq 2 ]] || usage
211 dane_${${(s:/:)2}[2]} < $2/cer.pem
214 [[ $# -eq 2 ]] || usage
220 zmodload -F zsh/datetime b:strftime
222 for cer (**/cer.pem) {
223 certtool --certificate-info < $cer | while read line ; do
224 [[ $line =~ "^\s*Not After: .*" ]] && break
227 # Not After: Sat Jul 02 10:02:29 UTC 2022
229 strftime -s ts_ugly -r "%b %d %H:%M:%S UTC %Y" ${(j: :)cols[4,-1]}
230 strftime -s ts_good %F $ts_ugly
231 print REM $ts_good +30 MSG $cer
234 (list) print -C1 ee/*/*/*(/on) ;;
235 (list-ca) print -C1 ca/*/*(/on) ;;