Make it possible to generate proxy certs with test/certs/mkcert.sh
[openssl.git] / test / certs / mkcert.sh
index 5116daaf79eac4a2951e29d453d96ac8a0bda456..39e3a1e28c3f6c7c382f0d13c82b28a9a9b48185 100755 (executable)
 #
 DAYS=36525
 
+if [ -z "$OPENSSL_SIGALG" ]; then
+    OPENSSL_SIGALG=sha256
+fi
+
 stderr_onerror() {
     (
         err=$("$@" >&3 2>&1) || {
@@ -36,7 +40,7 @@ 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);;
         *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;;
         esac
@@ -45,17 +49,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 "[req]\n%s\n%s\n[dn]\n" \
+                     "prompt = no" "distinguished_name = dn" "${dn}"
+                      for dn in "$@"; do echo "$dn"; done)
 }
 
 req_nocn() {
@@ -63,7 +68,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 +78,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 +89,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 +108,58 @@ 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
+    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}"
 }
 
 genee() {
@@ -132,7 +188,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 +205,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}" "$@"