3 # Copyright (C) 2022-2023 Sergey Matveev <stargrave@stargrave.org>
7 KEY_ENCRYPT_RECIPIENT=${KEY_ENCRYPT_RECIPIENT:-12AD32689C660D426967FD75CB8205632107AD8A}
11 ~/work/gogost/cmd/cer-selfsigned-example
12 ~/work/gogost/cmd/cer-dane-hash
17 gpg --encrypt --recipient $KEY_ENCRYPT_RECIPIENT
24 # ------------------------ >8 ------------------------
29 \$ $ZSH_ARGZERO:t ca [ecdsa|gost|eddsa] NAME -- new CA keypair
30 \$ $ZSH_ARGZERO:t list-ca -- list CA keypairs
31 \$ $ZSH_ARGZERO:t list -- list EE ones
32 \$ $ZSH_ARGZERO:t rem -- list certificate expirations
33 \$ $ZSH_ARGZERO:t new KEY -- new EE
34 \$ $ZSH_ARGZERO:t renew KEY -- renew EE
35 \$ $ZSH_ARGZERO:t dane KEY -- show DANE SHA256 hash
36 \$ $ZSH_ARGZERO:t encrypt KEY -- encrypt private key
37 \$ $ZSH_ARGZERO:t keypair KEY -- PEM-encoded full keypair
42 zmodload -F zsh/files b:zf_mkdir
46 [[ -s $1/key.pem ]] &&
47 REPLY=`< ${1}/key.pem` ||
48 REPLY=`key_decrypt < ${1}/key.pem.enc`
52 certtool --generate-privkey ${=1} --no-text
61 trap "rm -f $key $tmpl $cert" HUP PIPE INT QUIT TERM EXIT
63 dn = "cn=$domain,c=$COUNTRY"
65 expiration_days = 3650
69 certtool_genkey "$keytype" > $key
71 --generate-self-signed \
75 reply=(${mapfile[$key]} ${mapfile[$cert]})
79 ca_new_xdsa "--key-type=ecdsa --bits 512" $1
83 certtool_genkey "--key-type=ecdsa --bits 256"
87 ca_new_xdsa "--key-type=ed25519" $1
91 certtool_genkey "--key-type=ed25519"
95 cer-selfsigned-example -cn does-not-matter -ai 256A -only-key
106 trap "rm -f $cakey $key $tmpl $cert" HUP PIPE INT QUIT TERM EXIT
108 mapfile[$cakey]=$REPLY
109 key_get ee/$algo/$ca/$domain
112 dn = "cn=$domain,c=RU"
113 expiration_days = 365
118 --load-ca-certificate ca/$algo/$ca/cer.pem \
119 --load-ca-privkey $cakey \
120 --generate-certificate \
121 --load-privkey $key \
126 ee_renew_xdsa ecdsa "$1" "$2"
130 ee_renew_xdsa eddsa "$1" "$2"
139 trap "rm -f $cakey $key $cert" HUP PIPE INT QUIT TERM EXIT
141 mapfile[$cakey]=$REPLY
143 cat >> $cakey < ca/gost/$ca/cer.pem
144 key_get ee/gost/$ca/$domain
146 cer-selfsigned-example \
149 -cn $domain -country $COUNTRY -ai 256A
156 trap "rm -f $key $cert" HUP PIPE INT QUIT TERM EXIT
157 cer-selfsigned-example \
165 reply=(${mapfile[$key]} ${mapfile[$cert]})
169 certtool --key-id --hash=sha256
182 [[ $# -eq 3 ]] || usage
187 [[ -s $dst/key.pem ]] && {
188 print $dst/key.pem already exists >&2
191 ca_new_${algo} $domain
194 mapfile[${dst}/key.pem]=${reply[1]}
196 mapfile[${dst}/cer.pem]=${reply[2]}
200 [[ $# -eq 2 ]] || usage
203 print no $key found >&2
207 key_encrypt < $key > $key.enc
211 [[ $# -eq 2 ]] || usage
216 dst=ee/$algo/$ca/$domain
219 [[ -s $dst/key.pem ]] && {
220 print $dst/key.pem already exists >&2
225 ee_key_new_${algo} > $dst/key.pem
227 ee_renew_${algo} $ca $domain > $dst/cer.pem
230 [[ $# -eq 2 ]] || usage
235 ee_renew_${algo} $ca $domain > ee/$algo/$ca/$domain/cer.pem
238 [[ $# -eq 2 ]] || usage
239 dane_${${(s:/:)2}[2]} < $2/cer.pem
242 [[ $# -eq 2 ]] || usage
248 zmodload -F zsh/datetime b:strftime
250 for cer (**/cer.pem) {
251 certtool --certificate-info < $cer | while read line ; do
252 [[ $line =~ "^\s*Not After: .*" ]] && break
255 # Not After: Sat Jul 02 10:02:29 UTC 2022
257 strftime -s ts_ugly -r "%b %d %H:%M:%S UTC %Y" ${(j: :)cols[4,-1]}
258 strftime -s ts_good %F $ts_ugly
259 print REM $ts_good +30 MSG $cer
262 (list) print -C1 ee/*/*/*(/on) ;;
263 (list-ca) print -C1 ca/*/*(/on) ;;