Add DSA support to mkcert.sh
[openssl.git] / test / certs / mkcert.sh
index 5116daaf79eac4a2951e29d453d96ac8a0bda456..e547274d0941e116dcf8e0ac923feac64d598300 100755 (executable)
@@ -8,7 +8,17 @@
 
 # 100 years should be enough for now
 #
-DAYS=36525
+if [ -z "$DAYS" ]; then
+    DAYS=36525
+fi
+
+if [ -z "$OPENSSL_SIGALG" ]; then
+    OPENSSL_SIGALG=sha256
+fi
+
+if [ -z "$REQMASK" ]; then
+    REQMASK=utf8only
+fi
 
 stderr_onerror() {
     (
@@ -36,8 +46,9 @@ key() {
         args=(-algorithm "$alg")
         case $alg in
         rsa) args=("${args[@]}" -pkeyopt rsa_keygen_bits:$bits );;
-        ecdsa) args=("${args[@]}" -pkeyopt "ec_paramgen_curve:$bits")
+        ec args=("${args[@]}" -pkeyopt "ec_paramgen_curve:$bits")
                args=("${args[@]}" -pkeyopt ec_param_enc:named_curve);;
+        dsa)  args=(-paramfile "$bits");;
         *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;;
         esac
         stderr_onerror \
@@ -45,17 +56,18 @@ key() {
     fi
 }
 
+# Usage: $0 req keyname dn1 dn2 ...
 req() {
     local key=$1; shift
-    local cn=$1; shift
 
     key "$key"
     local errs
 
     stderr_onerror \
-        openssl req -new -sha256 -key "${key}.pem" \
-            -config <(printf "[req]\n%s\n%s\n[dn]\nCN=%s\n" \
-                     "prompt = no" "distinguished_name = dn" "${cn}")
+        openssl req -new -"${OPENSSL_SIGALG}" -key "${key}.pem" \
+            -config <(printf "string_mask=%s\n[req]\n%s\n%s\n[dn]\n" \
+              "$REQMASK" "prompt = no" "distinguished_name = dn"
+                      for dn in "$@"; do echo "$dn"; done)
 }
 
 req_nocn() {
@@ -63,7 +75,7 @@ req_nocn() {
 
     key "$key"
     stderr_onerror \
-        openssl req -new -sha256 -subj / -key "${key}.pem" \
+        openssl req -new -"${OPENSSL_SIGALG}" -subj / -key "${key}.pem" \
             -config <(printf "[req]\n%s\n[dn]\nCN_default =\n" \
                      "distinguished_name = dn")
 }
@@ -73,7 +85,7 @@ cert() {
     local exts=$1; shift
 
     stderr_onerror \
-        openssl x509 -req -sha256 -out "${cert}.pem" \
+        openssl x509 -req -"${OPENSSL_SIGALG}" -out "${cert}.pem" \
             -extfile <(printf "%s\n" "$exts") "$@"
 }
 
@@ -84,8 +96,12 @@ genroot() {
     local skid="subjectKeyIdentifier = hash"
     local akid="authorityKeyIdentifier = keyid"
 
-    exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = CA:true")
-    csr=$(req "$key" "$cn") || return 1
+    exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
+    for eku in "$@"
+    do
+        exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
+    done
+    csr=$(req "$key" "CN = $cn") || return 1
     echo "$csr" |
        cert "$cert" "$exts" -signkey "${key}.pem" -set_serial 1 -days "${DAYS}"
 }
@@ -99,11 +115,83 @@ genca() {
     local skid="subjectKeyIdentifier = hash"
     local akid="authorityKeyIdentifier = keyid"
 
-    exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = CA:true")
-    csr=$(req "$key" "$cn") || return 1
+    exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
+    for eku in "$@"
+    do
+        exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
+    done
+    if [ -n "$NC" ]; then
+        exts=$(printf "%s\nnameConstraints = %s\n" "$exts" "$NC")
+    fi
+    csr=$(req "$key" "CN = $cn") || return 1
     echo "$csr" |
         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
-           -set_serial 2 -days "${DAYS}" "$@"
+           -set_serial 2 -days "${DAYS}"
+}
+
+gen_nonbc_ca() {
+    local cn=$1; shift
+    local key=$1; shift
+    local cert=$1; shift
+    local cakey=$1; shift
+    local cacert=$1; shift
+    local skid="subjectKeyIdentifier = hash"
+    local akid="authorityKeyIdentifier = keyid"
+
+    exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid")
+    exts=$(printf "%s\nkeyUsage = %s\n" "$exts" "keyCertSign, cRLSign")
+    for eku in "$@"
+    do
+        exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
+    done
+    csr=$(req "$key" "CN = $cn") || return 1
+    echo "$csr" |
+        cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
+           -set_serial 2 -days "${DAYS}"
+}
+
+# Usage: $0 genpc keyname certname eekeyname eecertname pcext1 pcext2 ...
+#
+# Note: takes csr on stdin, so must be used with $0 req like this:
+#
+# $0 req keyname dn | $0 genpc keyname certname eekeyname eecertname pcext ...
+genpc() {
+    local key=$1; shift
+    local cert=$1; shift
+    local cakey=$1; shift
+    local ca=$1; shift
+
+    exts=$(printf "%s\n%s\n%s\n%s\n" \
+           "subjectKeyIdentifier = hash" \
+           "authorityKeyIdentifier = keyid, issuer:always" \
+           "basicConstraints = CA:false" \
+           "proxyCertInfo = critical, @pcexts";
+           echo "[pcexts]";
+           for x in "$@"; do echo $x; done)
+    cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
+        -set_serial 2 -days "${DAYS}"
+}
+
+# Usage: $0 genalt keyname certname eekeyname eecertname alt1 alt2 ...
+#
+# Note: takes csr on stdin, so must be used with $0 req like this:
+#
+# $0 req keyname dn | $0 genalt keyname certname eekeyname eecertname alt ...
+geneealt() {
+    local key=$1; shift
+    local cert=$1; shift
+    local cakey=$1; shift
+    local ca=$1; shift
+
+    exts=$(printf "%s\n%s\n%s\n%s\n" \
+           "subjectKeyIdentifier = hash" \
+           "authorityKeyIdentifier = keyid" \
+           "basicConstraints = CA:false" \
+           "subjectAltName = @alts";
+           echo "[alts]";
+           for x in "$@"; do echo $x; done)
+    cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
+        -set_serial 2 -days "${DAYS}"
 }
 
 genee() {
@@ -132,7 +220,7 @@ genee() {
            "basicConstraints = CA:false" \
            "extendedKeyUsage = $purpose" \
            "subjectAltName = @alts" "DNS=${cn}")
-    csr=$(req "$key" "$cn") || return 1
+    csr=$(req "$key" "CN = $cn") || return 1
     echo "$csr" |
        cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
            -set_serial 2 -days "${DAYS}" "$@"
@@ -149,7 +237,7 @@ genss() {
            "basicConstraints = CA:false" \
            "extendedKeyUsage = serverAuth" \
            "subjectAltName = @alts" "DNS=${cn}")
-    csr=$(req "$key" "$cn") || return 1
+    csr=$(req "$key" "CN = $cn") || return 1
     echo "$csr" |
         cert "$cert" "$exts" -signkey "${key}.pem" \
             -set_serial 1 -days "${DAYS}" "$@"