Browse Source

qnetd-certutil: Support adding multiple CAs

This is needed for hybrid PKI support.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
Jan Friesse 1 day ago
parent
commit
9159c9c4db
2 changed files with 50 additions and 18 deletions
  1. 5 1
      man/corosync-qnetd-certutil.8
  2. 45 17
      qdevices/corosync-qnetd-certutil.sh

+ 5 - 1
man/corosync-qnetd-certutil.8

@@ -35,7 +35,7 @@
 .SH NAME
 .SH NAME
 corosync-qnetd-certutil - tool to generate qnetd TLS certificates
 corosync-qnetd-certutil - tool to generate qnetd TLS certificates
 .SH SYNOPSIS
 .SH SYNOPSIS
-.B "corosync-qnetd-certutil [-i|-s] [-C ca_nickname] [-c certificate] [-G] [-g keysize] [-k keytype] [-n cluster_name] [-q paramset] [-S serv_nickname]"
+.B "corosync-qnetd-certutil [-I|-i|-s] [-C ca_nickname] [-c certificate] [-G] [-g keysize] [-k keytype] [-n cluster_name] [-q paramset] [-S serv_nickname]"
 .SH DESCRIPTION
 .SH DESCRIPTION
 .B corosync-qnetd-certutil
 .B corosync-qnetd-certutil
 is a frontend for the NSS certutil, it is used for generating the QNetd CA (Certificate Authority), 
 is a frontend for the NSS certutil, it is used for generating the QNetd CA (Certificate Authority), 
@@ -44,6 +44,10 @@ server certificate and signing cluster certificate used by
 when using the model 'net'.
 when using the model 'net'.
 .SH OPTIONS
 .SH OPTIONS
 .TP
 .TP
+.B -I
+Generate and add another QNetd CA and a new server certificate. Both the CA
+and server nicknames must be unique.
+.TP
 .B -i
 .B -i
 Initialize the QNetd NSS certificate database and generate the QNetd CA and server certificates.
 Initialize the QNetd NSS certificate database and generate the QNetd CA and server certificates.
 The default directory for the database is /etc/corosync/qnetd. This directory must be
 The default directory for the database is /etc/corosync/qnetd. This directory must be

+ 45 - 17
qdevices/corosync-qnetd-certutil.sh

@@ -56,8 +56,9 @@ errx() {
 }
 }
 
 
 usage() {
 usage() {
-    echo "$0: [-i|-s] [-C ca_nickname] [-c certificate] [-G] [-g keysize] [-k keytype] [-n cluster_name] [-q paramset] [-S serv_nickname]"
+    echo "$0: [-I|-i|-s] [-C ca_nickname] [-c certificate] [-G] [-g keysize] [-k keytype] [-n cluster_name] [-q paramset] [-S serv_nickname]"
     echo
     echo
+    echo " -I                  Generate and add another QNetd CA and new server certificate"
     echo " -i                  Initialize QNetd CA and generate server certificate"
     echo " -i                  Initialize QNetd CA and generate server certificate"
     echo " -s                  Sign cluster certificate (needs cluster certificate)"
     echo " -s                  Sign cluster certificate (needs cluster certificate)"
     echo " -C ca_nickname      NSS database QNetd CA certificate nickname"
     echo " -C ca_nickname      NSS database QNetd CA certificate nickname"
@@ -149,6 +150,41 @@ get_certutil_key_params() {
     echo "$CERTUTIL_PARAMS"
     echo "$CERTUTIL_PARAMS"
 }
 }
 
 
+nss_nickname_exists() {
+    certutil -L -d "$DB_DIR" -n "$1" >/dev/null 2>&1
+}
+
+add_qnetd_ca() {
+    cert_files=`find_certdb_files`
+    if [ "$cert_files" == "" ];then
+        errx 1 "Certificate database doesn't exist. Use $0 -i to create it"
+    fi
+
+    if nss_nickname_exists "$CA_NICKNAME";then
+        errx 1 "Certificate nickname \"$CA_NICKNAME\" already exists in the database."
+    fi
+
+    if nss_nickname_exists "$SERVER_NICKNAME";then
+        errx 1 "Certificate nickname \"$SERVER_NICKNAME\" already exists in the database."
+    fi
+
+    echo "Creating new CA"
+    # Create self-signed certificate (CA). Asks 3 questions (is this CA, lifetime and critical extension
+    echo -e "y\n0\ny\n" | certutil -S -n "$CA_NICKNAME" -s "$CA_SUBJECT" -x \
+        -t "CT,," -m "$(get_serial_no)" -v $CRT_VALIDITY -d "$DB_DIR" \
+        -z "$NOISE_FILE" -f "$PWD_FILE" -2 $(get_certutil_key_params)
+
+    # Export CA certificate in ascii
+    certutil -L -d "$DB_DIR" -n "$CA_NICKNAME" > "$CA_EXPORT_FILE"
+    certutil -L -d "$DB_DIR" -n "$CA_NICKNAME" -a >> "$CA_EXPORT_FILE"
+    chown_ref_cfgdir "$CA_EXPORT_FILE"
+
+    certutil -S -n "$SERVER_NICKNAME" -s "$SERVER_SUBJECT" -c "$CA_NICKNAME" -t "u,u,u" -m "$(get_serial_no)" \
+        -v $CRT_VALIDITY -d "$DB_DIR" -z "$NOISE_FILE" -f "$PWD_FILE" $(get_certutil_key_params)
+
+    echo "QNetd CA certificate is exported as $CA_EXPORT_FILE"
+}
+
 init_qnetd_ca() {
 init_qnetd_ca() {
     cert_files=`find_certdb_files`
     cert_files=`find_certdb_files`
     if [ "$cert_files" != "" ];then
     if [ "$cert_files" != "" ];then
@@ -180,21 +216,7 @@ init_qnetd_ca() {
 
 
     create_new_noise_file "$NOISE_FILE"
     create_new_noise_file "$NOISE_FILE"
 
 
-    echo "Creating new CA"
-    # Create self-signed certificate (CA). Asks 3 questions (is this CA, lifetime and critical extension
-    echo -e "y\n0\ny\n" | certutil -S -n "$CA_NICKNAME" -s "$CA_SUBJECT" -x \
-        -t "CT,," -m "$(get_serial_no)" -v $CRT_VALIDITY -d "$DB_DIR" \
-        -z "$NOISE_FILE" -f "$PWD_FILE" -2 $(get_certutil_key_params)
-
-    # Export CA certificate in ascii
-    certutil -L -d "$DB_DIR" -n "$CA_NICKNAME" > "$CA_EXPORT_FILE"
-    certutil -L -d "$DB_DIR" -n "$CA_NICKNAME" -a >> "$CA_EXPORT_FILE"
-    chown_ref_cfgdir "$CA_EXPORT_FILE"
-
-    certutil -S -n "$SERVER_NICKNAME" -s "$SERVER_SUBJECT" -c "$CA_NICKNAME" -t "u,u,u" -m "$(get_serial_no)" \
-        -v $CRT_VALIDITY -d "$DB_DIR" -z "$NOISE_FILE" -f "$PWD_FILE" $(get_certutil_key_params)
-
-    echo "QNetd CA certificate is exported as $CA_EXPORT_FILE"
+    add_qnetd_ca
 }
 }
 
 
 
 
@@ -230,8 +252,11 @@ CERTIFICATE_FILE=""
 CLUSTER_NAME=""
 CLUSTER_NAME=""
 SET_GROUP_WRITE_BIT=true
 SET_GROUP_WRITE_BIT=true
 
 
-while getopts ":GhisC:c:g:k:n:q:S:" opt; do
+while getopts ":IGhisC:c:g:k:n:q:S:" opt; do
     case $opt in
     case $opt in
+        I)
+            OPERATION=add_qnetd_ca
+            ;;
         i)
         i)
             OPERATION=init_qnetd_ca
             OPERATION=init_qnetd_ca
             ;;
             ;;
@@ -281,6 +306,9 @@ CRT_FILE="$DB_DIR/cluster-$CLUSTER_NAME.crt"
 CA_SUBJECT="CN=$CA_NICKNAME"
 CA_SUBJECT="CN=$CA_NICKNAME"
 
 
 case "$OPERATION" in
 case "$OPERATION" in
+    "add_qnetd_ca")
+        add_qnetd_ca
+    ;;
     "init_qnetd_ca")
     "init_qnetd_ca")
         init_qnetd_ca
         init_qnetd_ca
     ;;
     ;;