feat: Enhance certificate generation with user type support and additional SANs
/ test-shell (push) Successful in 17s
/ test-shell (push) Successful in 17s
This commit is contained in:
+67
-26
@@ -57,8 +57,9 @@ _require_ca_dir() {
|
||||
fi
|
||||
}
|
||||
|
||||
_is_ip() { [[ "$1" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ ]]; }
|
||||
_is_dns() { [[ "$1" =~ ^[a-z0-9-]+(\.[a-z0-9-]+)*$ ]]; }
|
||||
_is_ip() { [[ "$1" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ ]]; }
|
||||
_is_dns() { [[ "$1" =~ ^[a-z0-9-]+(\.[a-z0-9-]+)*$ ]]; }
|
||||
_is_email() { [[ "$1" =~ ^[^@]+@[^@]+\.[^@]+$ ]]; }
|
||||
|
||||
make_ca() {
|
||||
local CA_DAYS=3650
|
||||
@@ -187,6 +188,7 @@ make_cert() {
|
||||
local ISSUING_CA=""
|
||||
local CERT_DAYS=365
|
||||
local CERT_DIR=""
|
||||
local CERT_TYPE="server"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
@@ -218,6 +220,16 @@ make_cert() {
|
||||
return 1
|
||||
fi
|
||||
CERT_DAYS="$2"; shift 2 ;;
|
||||
--type)
|
||||
if [[ -z "$2" ]]; then
|
||||
echo "ERROR: --type requires a value." >&2
|
||||
return 1
|
||||
fi
|
||||
if [[ "$2" != "server" && "$2" != "user" ]]; then
|
||||
echo "ERROR: --type must be 'server' or 'user'." >&2
|
||||
return 1
|
||||
fi
|
||||
CERT_TYPE="$2"; shift 2 ;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
@@ -233,7 +245,7 @@ make_cert() {
|
||||
echo "ERROR: Subject name is required." >&2
|
||||
return 1
|
||||
fi
|
||||
if ! _is_dns "$CERT_SUBJECT_NAME"; then
|
||||
if [[ "$CERT_TYPE" == "server" ]] && ! _is_dns "$CERT_SUBJECT_NAME"; then
|
||||
echo "ERROR: Invalid subject name '$CERT_SUBJECT_NAME'. Must be a valid DNS name." >&2
|
||||
return 1
|
||||
fi
|
||||
@@ -256,11 +268,17 @@ make_cert() {
|
||||
fi
|
||||
|
||||
local CERT_NAME="${CERT_SUBJECT_NAME%%.*}"
|
||||
local SANS=("DNS:${CERT_SUBJECT_NAME}")
|
||||
local SANS=()
|
||||
|
||||
if [[ "$CERT_TYPE" == "server" ]]; then
|
||||
SANS=("DNS:${CERT_SUBJECT_NAME}")
|
||||
fi
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
if _is_ip "$1"; then
|
||||
SANS+=("IP:$1")
|
||||
elif _is_email "$1"; then
|
||||
SANS+=("email:$1")
|
||||
elif _is_dns "$1"; then
|
||||
SANS+=("DNS:$1")
|
||||
else
|
||||
@@ -270,7 +288,11 @@ make_cert() {
|
||||
shift
|
||||
done
|
||||
|
||||
echo "Generating server certificate for '$CERT_SUBJECT_NAME' with SANs:"
|
||||
if [[ "$CERT_TYPE" == "server" ]]; then
|
||||
echo "Generating server certificate for '$CERT_SUBJECT_NAME' with SANs:"
|
||||
else
|
||||
echo "Generating user certificate for '$CERT_SUBJECT_NAME':"
|
||||
fi
|
||||
for san in "${SANS[@]}"; do echo " - $san"; done
|
||||
|
||||
if [[ -f "$CERT_DIR/${CERT_NAME}_cert.pem" && -f "$CERT_DIR/${CERT_NAME}_key.pem" ]]; then
|
||||
@@ -278,28 +300,47 @@ make_cert() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
local SANS_EXT="subjectAltName=$(IFS=,; echo "${SANS[*]}")"
|
||||
local REQ_ARGS=(
|
||||
-newkey rsa:4096
|
||||
-keyout "$CERT_DIR/${CERT_NAME}_key.pem"
|
||||
-noenc
|
||||
-subj "/CN=${CERT_SUBJECT_NAME}"
|
||||
-addext "basicConstraints=critical,CA:FALSE"
|
||||
)
|
||||
|
||||
echo "Generating server certificate and key..."
|
||||
if ! openssl req \
|
||||
-newkey rsa:4096 \
|
||||
-keyout "$CERT_DIR/${CERT_NAME}_key.pem" \
|
||||
-noenc \
|
||||
-subj "/CN=${CERT_SUBJECT_NAME}" \
|
||||
-addext "basicConstraints=critical,CA:FALSE" \
|
||||
-addext "keyUsage=critical,digitalSignature,keyEncipherment" \
|
||||
-addext "extendedKeyUsage=serverAuth,clientAuth" \
|
||||
-addext "$SANS_EXT" \
|
||||
${AIA_URL:+-addext "authorityInfoAccess=caIssuers;URI:${AIA_URL}"} \
|
||||
| openssl x509 \
|
||||
-req \
|
||||
-CA "$SIGNING_CERT" \
|
||||
-CAkey "$SIGNING_KEY" \
|
||||
-copy_extensions copyall \
|
||||
-days "$CERT_DAYS" \
|
||||
-text \
|
||||
-out "$CERT_DIR/${CERT_NAME}_cert.pem"; then
|
||||
echo "ERROR: Failed to generate server certificate and key." >&2
|
||||
local X509_ARGS=(
|
||||
-req
|
||||
-CA "$SIGNING_CERT"
|
||||
-CAkey "$SIGNING_KEY"
|
||||
-copy_extensions copyall
|
||||
-days "$CERT_DAYS"
|
||||
-text
|
||||
-out "$CERT_DIR/${CERT_NAME}_cert.pem"
|
||||
)
|
||||
|
||||
if [[ "$CERT_TYPE" == "server" ]]; then
|
||||
REQ_ARGS+=(
|
||||
-addext "keyUsage=critical,digitalSignature,keyEncipherment"
|
||||
-addext "extendedKeyUsage=serverAuth,clientAuth"
|
||||
-addext "subjectAltName=$(IFS=,; echo "${SANS[*]}")"
|
||||
)
|
||||
else
|
||||
REQ_ARGS+=(
|
||||
-addext "keyUsage=critical,digitalSignature,nonRepudiation"
|
||||
-addext "extendedKeyUsage=clientAuth,emailProtection,codeSigning"
|
||||
)
|
||||
if [[ ${#SANS[@]} -gt 0 ]]; then
|
||||
REQ_ARGS+=(-addext "subjectAltName=$(IFS=,; echo "${SANS[*]}")")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$AIA_URL" ]]; then
|
||||
REQ_ARGS+=(-addext "authorityInfoAccess=caIssuers;URI:${AIA_URL}")
|
||||
fi
|
||||
|
||||
echo "Generating certificate and key..."
|
||||
if ! openssl req "${REQ_ARGS[@]}" | openssl x509 "${X509_ARGS[@]}"; then
|
||||
echo "ERROR: Failed to generate certificate and key." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user