commit
b1bc99510d
1 changed files with 714 additions and 0 deletions
@ -0,0 +1,714 @@ |
|||
#!/bin/bash |
|||
|
|||
if [ $# -lt 1 ]; then |
|||
echo "Usage: $0 pki_path" |
|||
exit 1 |
|||
fi |
|||
|
|||
MSG=">>> " |
|||
|
|||
function main_menu () { |
|||
# Menu constants |
|||
local MENU_INITIALIZE_CA="Initialize CA" |
|||
local MENU_ISSUE_CERT="Issue a certificate" |
|||
local MENU_ISSUE_CRL="Issue a CRL" |
|||
local MENU_REVOKE="Revoke a certificate" |
|||
local MENU_DUMP_CACERT="Dump the CA Certificate" |
|||
local MENU_SHOW_CACERT="Show the CA Certificate" |
|||
local MENU_DUMP_CRL="Dump the CRL" |
|||
local MENU_SHOW_CRL="Show the CRL" |
|||
local MENU_SHOW_CADB="Show the CA Database" |
|||
local MENU_EXPORT_CERT="Export a certificate" |
|||
local MENU_EXPORT_CACERT="Export the CA certificate" |
|||
local MENU_QUIT="Quit" |
|||
|
|||
# Variables |
|||
local cmd |
|||
|
|||
clear |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo "| Main Menu |" |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo |
|||
|
|||
select cmd in "$MENU_INITIALIZE_CA" "$MENU_ISSUE_CERT" "$MENU_ISSUE_CRL" \ |
|||
"$MENU_REVOKE" "$MENU_EXPORT_CERT" "$MENU_SHOW_CADB" "$MENU_DUMP_CACERT" \ |
|||
"$MENU_SHOW_CACERT" "$MENU_EXPORT_CACERT" "$MENU_DUMP_CRL" "$MENU_SHOW_CRL" "$MENU_QUIT"; do |
|||
|
|||
if [ -z "$cmd" ]; then |
|||
cmd="$REPLY" |
|||
fi |
|||
|
|||
case "$cmd" in |
|||
"$MENU_INITIALIZE_CA") |
|||
if is_ca_initialized; then |
|||
echo "${MSG}Error: CA is already initialized !" |
|||
continue |
|||
else |
|||
initialize_ca_menu |
|||
fi |
|||
;; |
|||
"$MENU_DUMP_CACERT") |
|||
if ! is_ca_initialized; then |
|||
echo "${MSG}Error: CA is not yet initialized !" |
|||
continue |
|||
else |
|||
dump_file "$pki_path/cacert.pem" |
|||
fi |
|||
;; |
|||
"$MENU_EXPORT_CACERT") |
|||
if ! is_ca_initialized; then |
|||
echo "${MSG}Error: CA is not yet initialized !" |
|||
continue |
|||
else |
|||
export_file "$pki_path/cacert.pem" |
|||
fi |
|||
;; |
|||
"$MENU_DUMP_CRL") |
|||
if ! is_ca_initialized; then |
|||
echo "${MSG}Error: CA is not yet initialized !" |
|||
continue |
|||
else |
|||
dump_file "$pki_path/crl.pem" |
|||
fi |
|||
;; |
|||
"$MENU_ISSUE_CERT") |
|||
if ! is_ca_initialized; then |
|||
echo "${MSG}Error: CA is not yet initialized !" |
|||
continue |
|||
else |
|||
issue_cert_menu |
|||
fi |
|||
;; |
|||
"$MENU_EXPORT_CERT") |
|||
if ! is_ca_initialized; then |
|||
echo "${MSG}Error: CA is not yet initialized !" |
|||
continue |
|||
else |
|||
export_cert_menu |
|||
fi |
|||
;; |
|||
"$MENU_REVOKE") |
|||
if ! is_ca_initialized; then |
|||
echo "${MSG}Error: CA is not yet initialized !" |
|||
continue |
|||
else |
|||
revoke_menu |
|||
fi |
|||
;; |
|||
"$MENU_ISSUE_CRL") |
|||
if ! is_ca_initialized; then |
|||
echo "${MSG}Error: CA is not yet initialized !" |
|||
continue |
|||
else |
|||
issue_crl |
|||
fi |
|||
;; |
|||
"$MENU_SHOW_CACERT") |
|||
if ! is_ca_initialized; then |
|||
echo "${MSG}Error: CA is not yet initialized !" |
|||
continue |
|||
else |
|||
show_cert "$pki_path/cacert.pem" |
|||
fi |
|||
;; |
|||
"$MENU_SHOW_CRL") |
|||
if ! is_ca_initialized; then |
|||
echo "${MSG}Error: CA is not yet initialized !" |
|||
continue |
|||
else |
|||
show_crl "$pki_path/crl.pem" |
|||
fi |
|||
;; |
|||
"$MENU_SHOW_CADB") |
|||
if ! is_ca_initialized; then |
|||
echo "${MSG}Error: CA is not yet initialized !" |
|||
continue |
|||
else |
|||
show_cadb |
|||
fi |
|||
;; |
|||
"$MENU_QUIT") |
|||
false |
|||
;; |
|||
*) |
|||
echo "${MSG}Error: $cmd is not a valid command !" |
|||
continue |
|||
;; |
|||
esac |
|||
|
|||
return |
|||
done |
|||
} |
|||
|
|||
function revoke_menu () { |
|||
clear |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo "| Revoke a certificate |" |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo |
|||
|
|||
local torevoke="" |
|||
local serial="" |
|||
|
|||
show_cadb |
|||
while [ -z "$torevoke" ]; do |
|||
read -p "${MSG}Serial number (\"l\" to show the CA DB, \"q\" to quit): " serial |
|||
case "$serial" in |
|||
l) |
|||
show_cadb |
|||
continue |
|||
;; |
|||
q) |
|||
return 0 |
|||
;; |
|||
*) |
|||
if [ -e "$certs_path/$serial.pem" ]; then |
|||
torevoke="$serial" |
|||
else |
|||
echo "${MSG}Unknown certificate with serial '$serial' !" |
|||
echo |
|||
fi |
|||
;; |
|||
esac |
|||
|
|||
done |
|||
|
|||
trap "rm -f \"\$OPENSSL_CONF\"" RETURN |
|||
cat <<EOF > "$OPENSSL_CONF" |
|||
$OPENSSL_CA_SECTION |
|||
EOF |
|||
my_openssl ca -revoke "$pki_path/certs/$serial.pem" |
|||
local ret="$?" |
|||
if [ "$ret" -eq 0 ]; then |
|||
pause |
|||
echo |
|||
echo "${MSG}Issuing CRL..." |
|||
issue_crl |
|||
ret="$?" |
|||
fi |
|||
|
|||
pause |
|||
return "$ret" |
|||
} |
|||
|
|||
function export_cert_menu () { |
|||
clear |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo "| Export a certificate |" |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo |
|||
|
|||
local toexport="" |
|||
local serial="" |
|||
|
|||
show_cadb |
|||
while [ -z "$toexport" ]; do |
|||
read -p "${MSG}Serial number (\"l\" to show the CA DB, \"q\" to quit): " serial |
|||
case "$serial" in |
|||
l) |
|||
show_cadb |
|||
continue |
|||
;; |
|||
q) |
|||
return 0 |
|||
;; |
|||
*) |
|||
if [ -e "$certs_path/$serial.pem" ]; then |
|||
toexport="$serial" |
|||
else |
|||
echo "${MSG}Unknown certificate with serial '$serial' !" |
|||
echo |
|||
fi |
|||
;; |
|||
esac |
|||
done |
|||
|
|||
export_file "$certs_path/$serial.pem" |
|||
} |
|||
|
|||
function export_file () { |
|||
local ret="0" |
|||
echo |
|||
echo "${MSG}Where do you want to save the file (leave blank to cancel) ?" |
|||
read -e -p "${MSG}Path: " path |
|||
if [ -n "$path" ]; then |
|||
cp "$1" "$path" |
|||
ret="$?" |
|||
pause |
|||
fi |
|||
|
|||
return "$ret" |
|||
} |
|||
|
|||
function initialize_ca_menu () { |
|||
# Menu constants |
|||
local MENU_QUIT="Back" |
|||
local MENU_DOIT="Commit" |
|||
local MENU_SET_DN="Set the certificate DN" |
|||
local MENU_SET_VALIDITY="Set the validity period" |
|||
local MENU_SET_SIZE="Set the key size" |
|||
|
|||
# Variables |
|||
local cmd |
|||
local ca_dn="/C=FR/O=$OWNER_NAME/OU=$OWNER_DOMAIN/CN=Root CA of $OWNER_DOMAIN" |
|||
local validity="3650" |
|||
local key_size="2048" |
|||
|
|||
while true; do |
|||
clear |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo "| Initialize the CA |" |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo |
|||
echo "DN: $ca_dn" |
|||
echo "Validity (days): $validity" |
|||
echo "Key size: $key_size" |
|||
echo |
|||
|
|||
select cmd in "$MENU_SET_DN" "$MENU_SET_VALIDITY" "$MENU_SET_SIZE" "$MENU_DOIT" \ |
|||
"$MENU_QUIT"; do |
|||
|
|||
if [ -z "$cmd" ]; then |
|||
cmd="$REPLY" |
|||
fi |
|||
|
|||
case "$cmd" in |
|||
"$MENU_SET_DN") |
|||
read -p "${MSG}DN: " ca_dn |
|||
;; |
|||
"$MENU_SET_VALIDITY") |
|||
read -p "${MSG}Validity (days): " validity |
|||
;; |
|||
"$MENU_SET_SIZE") |
|||
read -p "${MSG}Key Size: " key_size |
|||
;; |
|||
"$MENU_QUIT") |
|||
return |
|||
;; |
|||
"$MENU_DOIT") |
|||
initialize_ca |
|||
return $? |
|||
;; |
|||
*) |
|||
echo "${MSG}Error: $cmd is not a valid command !" |
|||
continue |
|||
;; |
|||
esac |
|||
|
|||
break |
|||
done |
|||
done |
|||
} |
|||
|
|||
function initialize_ca () { |
|||
clear |
|||
trap "rm -f \"\$OPENSSL_CONF\"" RETURN |
|||
|
|||
local protect_opt="" |
|||
if [ -z "$CA_PROTECT" ]; then |
|||
protect_opt="-nodes" |
|||
fi |
|||
|
|||
cat <<EOF > "$OPENSSL_CONF" |
|||
[ req ] |
|||
default_bits = $key_size |
|||
default_keyfile = $private_path/cakey.pem |
|||
default_md = $HASH_ALGO |
|||
|
|||
prompt = no |
|||
x509_extensions = rootca_extensions |
|||
distinguished_name = rootca_dn |
|||
|
|||
[ rootca_dn ] |
|||
$(openssl_dn "$ca_dn") |
|||
|
|||
[ rootca_extensions ] |
|||
basicConstraints = critical, CA:true, pathlen:0 |
|||
subjectKeyIdentifier = hash |
|||
authorityKeyIdentifier = keyid |
|||
keyUsage = critical, cRLSign, keyCertSign |
|||
EOF |
|||
|
|||
# Generate the keys and the certificate |
|||
my_openssl req -set_serial 0 -days "$validity" -x509 -newkey rsa: -outform PEM \ |
|||
$protect_opt -out "$pki_path/cacert.pem" |
|||
|
|||
local ret="$?" |
|||
if [ "$ret" -eq 0 ]; then |
|||
echo '01' > "$pki_path/serial" |
|||
echo '01' > "$pki_path/crlserial" |
|||
touch "$pki_path/index.txt" |
|||
touch "$pki_path/index.txt.attr" |
|||
issue_crl |
|||
fi |
|||
|
|||
pause |
|||
return "$ret" |
|||
} |
|||
|
|||
function openssl_dn () { |
|||
echo "$1" |sed 's/\//\n/g' |
|||
} |
|||
|
|||
function my_openssl () { |
|||
# Strip out the informative messages on stderr |
|||
openssl "$@" 2> >(egrep -v '^Using configuration from' 1>&2) |
|||
local ret=$? |
|||
# Ugly(tm): Wait for the "egrep" child process |
|||
sleep .3 |
|||
return $ret; |
|||
} |
|||
|
|||
function is_ca_initialized () { |
|||
test -e "$pki_path/cacert.pem" |
|||
} |
|||
|
|||
function pause () { |
|||
echo |
|||
read -p "Press enter to continue... " |
|||
} |
|||
|
|||
function dump_file () { |
|||
clear |
|||
cat "$1" |
|||
local ret="$?" |
|||
pause |
|||
return "$ret" |
|||
} |
|||
|
|||
function issue_cert_menu () { |
|||
# Menu constants |
|||
local MENU_QUIT="Back" |
|||
local MENU_DOIT="Commit" |
|||
local MENU_SET_CN="Set the certificate CN" |
|||
local MENU_SET_DNS="Set the certificate SAN (Subject Alt Name)" |
|||
local MENU_SET_VALIDITY="Set the validity period" |
|||
|
|||
# Variables |
|||
local cmd |
|||
local cn |
|||
local dn="/C=FR/O=$OWNER_NAME/OU=$OWNER_DOMAIN/CN=My Server" |
|||
local validity="730" |
|||
local san="" |
|||
|
|||
while true; do |
|||
clear |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo "| Issue a Certificate (1/2) |" |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo |
|||
echo "DN: $dn" |
|||
echo "Validity (days): $validity" |
|||
echo "Subject Alt Name: $san" |
|||
echo |
|||
|
|||
select cmd in "$MENU_SET_CN" "$MENU_SET_DNS" "$MENU_SET_VALIDITY" "$MENU_DOIT" \ |
|||
"$MENU_QUIT"; do |
|||
|
|||
if [ -z "$cmd" ]; then |
|||
cmd="$REPLY" |
|||
fi |
|||
|
|||
case "$cmd" in |
|||
"$MENU_SET_CN") |
|||
echo |
|||
echo "${MSG}The \"Common Name\" of your server can be its FQDN or anything else." |
|||
echo "${MSG}Examples: \"My Web Server\", \"myserver.$OWNER_DOMAIN\" or \"*.$OWNER_DOMAIN\"". |
|||
echo |
|||
read -p "${MSG}The \"Common Name\" of your server: " cn |
|||
dn="/C=FR/O=$OWNER_NAME/OU=$OWNER_DOMAIN/CN=$cn" |
|||
;; |
|||
"$MENU_SET_VALIDITY") |
|||
read -p "${MSG}Validity (days): " validity |
|||
;; |
|||
"$MENU_SET_DNS") |
|||
echo |
|||
echo "${MSG}The Subject Alt Name can contain DNS, IP, email or URI addresses." |
|||
echo "${MSG}Prefix each SAN by its type and separate each SAN by a \",\"." |
|||
echo "${MSG}Example: \"DNS:myserver.$OWNER_DOMAIN,IP:192.168.16.4\"" |
|||
echo |
|||
read -p "${MSG}Subject Alt Name (leave empty to disable the SAN): " san |
|||
;; |
|||
"$MENU_QUIT") |
|||
return |
|||
;; |
|||
"$MENU_DOIT") |
|||
issue_cert |
|||
return $? |
|||
;; |
|||
*) |
|||
echo "${MSG}Error: $cmd is not a valid command !" |
|||
continue |
|||
;; |
|||
esac |
|||
|
|||
break |
|||
done |
|||
done |
|||
} |
|||
|
|||
function issue_cert () { |
|||
clear |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo "| Issue a Certificate (2/2) |" |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo |
|||
|
|||
trap "rm -f \"\$OPENSSL_CONF\" \"$tmp_path/lastcert.pem\"" RETURN |
|||
|
|||
local san_ext |
|||
if [ -n "$san" ]; then |
|||
san_ext="subjectAltName = $san" |
|||
fi |
|||
cat <<EOF > "$OPENSSL_CONF" |
|||
$OPENSSL_CA_SECTION |
|||
|
|||
default_days = $validity |
|||
prompt = no |
|||
distinguished_name = certificate_dn |
|||
x509_extensions = certificate_extensions |
|||
policy = policy_any |
|||
|
|||
[ policy_any ] |
|||
countryName = supplied |
|||
organizationName = supplied |
|||
organizationalUnitName = supplied |
|||
commonName = supplied |
|||
|
|||
[ certificate_extensions ] |
|||
basicConstraints = critical, CA:false |
|||
subjectKeyIdentifier = hash |
|||
authorityKeyIdentifier = keyid,issuer |
|||
keyUsage = critical,digitalSignature,keyEncipherment |
|||
$san_ext |
|||
crlDistributionPoints = URI:$CDP_URL |
|||
extendedKeyUsage = serverAuth |
|||
EOF |
|||
|
|||
local csr_path="" |
|||
read -e -p "${MSG}CSR Path: " csr_path |
|||
while [ ! -r "$csr_path" ]; do |
|||
echo "${MSG}\"$csr_path\" does not exist !" |
|||
read -e -p "${MSG}CSR Path: " csr_path |
|||
done |
|||
|
|||
rm -f "$tmp_path/lastcert.pem" |
|||
|
|||
# Generate the certificate |
|||
my_openssl ca -subj "$dn" -utf8 -in "$csr_path" -notext -out "$tmp_path/lastcert.pem" |
|||
local ret="$?" |
|||
|
|||
pause |
|||
|
|||
if [ "$ret" -eq 0 ]; then |
|||
export_file "$tmp_path/lastcert.pem" |
|||
ret="$?" |
|||
fi |
|||
|
|||
return "$ret" |
|||
} |
|||
|
|||
function issue_crl () { |
|||
trap "rm -f \"\$OPENSSL_CONF\"" RETURN |
|||
cat <<EOF > "$OPENSSL_CONF" |
|||
$OPENSSL_CA_SECTION |
|||
EOF |
|||
my_openssl ca -gencrl -utf8 -notext -out "$pki_path/crl.pem" \ |
|||
&& my_openssl crl -inform PEM -in "$pki_path/crl.pem" -outform DER -out "$CRL_PATH" |
|||
} |
|||
|
|||
function show_cert () { |
|||
clear |
|||
|
|||
my_openssl x509 -noout -text -in "$1" | less |
|||
} |
|||
|
|||
function show_crl () { |
|||
clear |
|||
|
|||
my_openssl crl -noout -text -in "$1" | less |
|||
} |
|||
|
|||
function show_cadb () { |
|||
clear |
|||
|
|||
sed -r 's/^V\s+[0-9]+Z\s+([0-9a-zA-Z]+)\s+unknown\s+(.*)$/\1) \2/; t; d' "$pki_path/index.txt" |less |
|||
} |
|||
|
|||
function init_conf () { |
|||
# Default values |
|||
HASH_ALGO="sha1" |
|||
|
|||
# Initialization Wizard |
|||
clear |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo "| Initialization Wizard |" |
|||
echo "+-----------------------------------------------------------------------+" |
|||
echo |
|||
echo "What is your name (ex: Nicolas MASSE) ?" |
|||
while [ -z "$OWNER_NAME" ]; do read -p "${MSG}Your name is: " OWNER_NAME; done |
|||
echo |
|||
echo "Which domain name do you initialize (ex: itix.fr) ?" |
|||
while [ -z "$OWNER_DOMAIN" ]; do |
|||
read -p "${MSG}Your DNS domain name is: " OWNER_DOMAIN |
|||
done |
|||
echo |
|||
echo "Where do you want to publish the CRL (ex: http://pki.$OWNER_DOMAIN/ca.crl) ?" |
|||
while [ -z "$CDP_URL" ]; do |
|||
read -p "${MSG}The CRL will be published at: " CDP_URL |
|||
done |
|||
while [ -z "$CRL_PATH" ]; do |
|||
read -e -p "${MSG}Local CRL path (ex: /var/www/ca.crl): " CRL_PATH |
|||
done |
|||
echo |
|||
while [ -z "$CRL_VALIDITY" ]; do |
|||
read -p "${MSG}CRL validity period, in days (\"30\" is a good value): " CRL_VALIDITY |
|||
done |
|||
echo |
|||
echo "${MSG}Protect the CA key with a password (yes/no) ?" |
|||
local cmd="" |
|||
select cmd in "Yes" "No"; do |
|||
|
|||
if [ -z "$cmd" ]; then |
|||
cmd="$REPLY" |
|||
fi |
|||
|
|||
case "$cmd" in |
|||
[yY]*) |
|||
CA_PROTECT="y" |
|||
break; |
|||
;; |
|||
[nN]*) |
|||
CA_PROTECT="" |
|||
break; |
|||
;; |
|||
*) |
|||
echo "Unknown response '$cmd' !" |
|||
continue |
|||
;; |
|||
esac |
|||
done |
|||
|
|||
echo |
|||
echo "Thanks !" |
|||
|
|||
# Save the conf |
|||
save_conf |
|||
local ret="$?" |
|||
|
|||
pause |
|||
return "$ret" |
|||
} |
|||
|
|||
function save_conf () { |
|||
cat <<EOC > "$conf_path" |
|||
OWNER_NAME="$OWNER_NAME" |
|||
OWNER_DOMAIN="$OWNER_DOMAIN" |
|||
HASH_ALGO="$HASH_ALGO" |
|||
CDP_URL="$CDP_URL" |
|||
CRL_PATH="$CRL_PATH" |
|||
CRL_VALIDITY="$CRL_VALIDITY" |
|||
CA_PROTECT="$CA_PROTECT" |
|||
EOC |
|||
} |
|||
|
|||
# Safe mask |
|||
umask 077 |
|||
|
|||
# The CA directory |
|||
pki_path="$1" |
|||
if [ ! -e "$pki_path" ]; then |
|||
echo "${MSG}$pki_path does not exist. Do you want to create it (yes/no) ?" |
|||
cmd="" |
|||
select cmd in "Yes" "No"; do |
|||
|
|||
if [ -z "$cmd" ]; then |
|||
cmd="$REPLY" |
|||
fi |
|||
|
|||
case "$cmd" in |
|||
[yY]*) |
|||
# Nothing to do |
|||
break; |
|||
;; |
|||
[nN]*) |
|||
exit 0 |
|||
;; |
|||
*) |
|||
echo "Unknown response '$cmd' !" |
|||
continue |
|||
;; |
|||
esac |
|||
done |
|||
mkdir "$pki_path" || exit $? |
|||
fi |
|||
|
|||
tmp_path="$pki_path/tmp" |
|||
if [ ! -e "$tmp_path" ]; then |
|||
mkdir "$tmp_path" || exit $? |
|||
fi |
|||
|
|||
certs_path="$pki_path/certs" |
|||
if [ ! -e "$certs_path" ]; then |
|||
mkdir "$certs_path" || exit $? |
|||
fi |
|||
|
|||
private_path="$pki_path/private" |
|||
if [ ! -e "$private_path" ]; then |
|||
mkdir "$private_path" || exit $? |
|||
fi |
|||
|
|||
conf_path="$pki_path/nanoca.conf" |
|||
if [ -e "$conf_path" ]; then |
|||
. "$conf_path" |
|||
else |
|||
init_conf || exit $? |
|||
fi |
|||
|
|||
|
|||
# OpenSSL Conf. |
|||
export OPENSSL_CONF="$tmp_path/openssl.cnf" |
|||
OPENSSL_CA_SECTION=" |
|||
[ ca ] |
|||
default_ca = CA_default |
|||
|
|||
[ CA_default ] |
|||
default_md = $HASH_ALGO |
|||
dir = $pki_path |
|||
database = $pki_path/index.txt |
|||
new_certs_dir = $pki_path/certs |
|||
certificate = $pki_path/cacert.pem |
|||
serial = $pki_path/serial |
|||
crlnumber = $pki_path/crlserial |
|||
private_key = $private_path/cakey.pem |
|||
RANDFILE = $private_path/.rand |
|||
email_in_dn = no |
|||
copy_extensions = none |
|||
unique_subject = no |
|||
name_opt = ca_default |
|||
cert_opt = ca_default |
|||
default_crl_days = $CRL_VALIDITY |
|||
" |
|||
|
|||
# Automatic processing |
|||
if [ -n "$2" ]; then |
|||
case "$2" in |
|||
crl) |
|||
issue_crl |
|||
;; |
|||
*) |
|||
echo "Unknown action \"$2\" !" |
|||
echo |
|||
echo "Valid actions are :" |
|||
echo " - crl: Issues a CRL" |
|||
echo |
|||
false |
|||
;; |
|||
esac |
|||
exit $? |
|||
fi |
|||
|
|||
# Main loop |
|||
while main_menu; do :; done |
|||
|
|||
Loading…
Reference in new issue