Home | History | Annotate | Line # | Download | only in certs
mkcert.sh revision 1.1.1.2.2.1
      1 #! /bin/bash
      2 #
      3 # Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
      4 # Copyright (c) 2016 Viktor Dukhovni <openssl-users (at] dukhovni.org>.
      5 # All rights reserved.
      6 #
      7 # Licensed under the OpenSSL license (the "License").  You may not use
      8 # this file except in compliance with the License.  You can obtain a copy
      9 # in the file LICENSE in the source distribution or at
     10 # https://www.openssl.org/source/license.html
     11 
     12 # This file is dual-licensed and is also available under other terms.
     13 # Please contact the author.
     14 
     15 # 100 years should be enough for now
     16 if [ -z "$DAYS" ]; then
     17     DAYS=36525
     18 fi
     19 
     20 if [ -z "$OPENSSL_SIGALG" ]; then
     21     OPENSSL_SIGALG=sha256
     22 fi
     23 
     24 if [ -z "$REQMASK" ]; then
     25     REQMASK=utf8only
     26 fi
     27 
     28 stderr_onerror() {
     29     (
     30         err=$("$@" >&3 2>&1) || {
     31             printf "%s\n" "$err" >&2
     32             exit 1
     33         }
     34     ) 3>&1
     35 }
     36 
     37 key() {
     38     local key=$1; shift
     39 
     40     local alg=rsa
     41     if [ -n "$OPENSSL_KEYALG" ]; then
     42         alg=$OPENSSL_KEYALG
     43     fi
     44 
     45     local bits=2048
     46     if [ -n "$OPENSSL_KEYBITS" ]; then
     47         bits=$OPENSSL_KEYBITS
     48     fi
     49 
     50     if [ ! -f "${key}.pem" ]; then
     51         args=(-algorithm "$alg")
     52         case $alg in
     53         rsa) args=("${args[@]}" -pkeyopt rsa_keygen_bits:$bits );;
     54         ec)  args=("${args[@]}" -pkeyopt "ec_paramgen_curve:$bits")
     55                args=("${args[@]}" -pkeyopt ec_param_enc:named_curve);;
     56         dsa)  args=(-paramfile "$bits");;
     57         ed25519)  ;;
     58         ed448)  ;;
     59         *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;;
     60         esac
     61         stderr_onerror \
     62             openssl genpkey "${args[@]}" -out "${key}.pem"
     63     fi
     64 }
     65 
     66 # Usage: $0 req keyname dn1 dn2 ...
     67 req() {
     68     local key=$1; shift
     69 
     70     key "$key"
     71     local errs
     72 
     73     stderr_onerror \
     74         openssl req -new -"${OPENSSL_SIGALG}" -key "${key}.pem" \
     75             -config <(printf "string_mask=%s\n[req]\n%s\n%s\n[dn]\n" \
     76               "$REQMASK" "prompt = no" "distinguished_name = dn"
     77                       for dn in "$@"; do echo "$dn"; done)
     78 }
     79 
     80 req_nocn() {
     81     local key=$1; shift
     82 
     83     key "$key"
     84     stderr_onerror \
     85         openssl req -new -"${OPENSSL_SIGALG}" -subj / -key "${key}.pem" \
     86             -config <(printf "[req]\n%s\n[dn]\nCN_default =\n" \
     87 		      "distinguished_name = dn")
     88 }
     89 
     90 cert() {
     91     local cert=$1; shift
     92     local exts=$1; shift
     93 
     94     stderr_onerror \
     95         openssl x509 -req -"${OPENSSL_SIGALG}" -out "${cert}.pem" \
     96             -extfile <(printf "%s\n" "$exts") "$@"
     97 }
     98 
     99 genroot() {
    100     local cn=$1; shift
    101     local key=$1; shift
    102     local cert=$1; shift
    103     local skid="subjectKeyIdentifier = hash"
    104     local akid="authorityKeyIdentifier = keyid"
    105 
    106     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
    107     for eku in "$@"
    108     do
    109         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
    110     done
    111     csr=$(req "$key" "CN = $cn") || return 1
    112     echo "$csr" |
    113        cert "$cert" "$exts" -signkey "${key}.pem" -set_serial 1 -days "${DAYS}"
    114 }
    115 
    116 genca() {
    117     local cn=$1; shift
    118     local key=$1; shift
    119     local cert=$1; shift
    120     local cakey=$1; shift
    121     local cacert=$1; shift
    122     local skid="subjectKeyIdentifier = hash"
    123     local akid="authorityKeyIdentifier = keyid"
    124 
    125     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
    126     for eku in "$@"
    127     do
    128         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
    129     done
    130     if [ -n "$NC" ]; then
    131         exts=$(printf "%s\nnameConstraints = %s\n" "$exts" "$NC")
    132     fi
    133     csr=$(req "$key" "CN = $cn") || return 1
    134     echo "$csr" |
    135         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
    136 	    -set_serial 2 -days "${DAYS}"
    137 }
    138 
    139 gen_nonbc_ca() {
    140     local cn=$1; shift
    141     local key=$1; shift
    142     local cert=$1; shift
    143     local cakey=$1; shift
    144     local cacert=$1; shift
    145     local skid="subjectKeyIdentifier = hash"
    146     local akid="authorityKeyIdentifier = keyid"
    147 
    148     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid")
    149     exts=$(printf "%s\nkeyUsage = %s\n" "$exts" "keyCertSign, cRLSign")
    150     for eku in "$@"
    151     do
    152         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
    153     done
    154     csr=$(req "$key" "CN = $cn") || return 1
    155     echo "$csr" |
    156         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
    157 	    -set_serial 2 -days "${DAYS}"
    158 }
    159 
    160 # Usage: $0 genpc keyname certname eekeyname eecertname pcext1 pcext2 ...
    161 #
    162 # Note: takes csr on stdin, so must be used with $0 req like this:
    163 #
    164 # $0 req keyname dn | $0 genpc keyname certname eekeyname eecertname pcext ...
    165 genpc() {
    166     local key=$1; shift
    167     local cert=$1; shift
    168     local cakey=$1; shift
    169     local ca=$1; shift
    170 
    171     exts=$(printf "%s\n%s\n%s\n%s\n" \
    172 	    "subjectKeyIdentifier = hash" \
    173 	    "authorityKeyIdentifier = keyid, issuer:always" \
    174 	    "basicConstraints = CA:false" \
    175 	    "proxyCertInfo = critical, @pcexts";
    176            echo "[pcexts]";
    177            for x in "$@"; do echo $x; done)
    178     cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
    179 	 -set_serial 2 -days "${DAYS}"
    180 }
    181 
    182 # Usage: $0 geneealt keyname certname eekeyname eecertname alt1 alt2 ...
    183 #
    184 # Note: takes csr on stdin, so must be used with $0 req like this:
    185 #
    186 # $0 req keyname dn | $0 geneealt keyname certname eekeyname eecertname alt ...
    187 geneealt() {
    188     local key=$1; shift
    189     local cert=$1; shift
    190     local cakey=$1; shift
    191     local ca=$1; shift
    192 
    193     exts=$(printf "%s\n%s\n%s\n%s\n" \
    194 	    "subjectKeyIdentifier = hash" \
    195 	    "authorityKeyIdentifier = keyid" \
    196 	    "basicConstraints = CA:false" \
    197 	    "subjectAltName = @alts";
    198            echo "[alts]";
    199            for x in "$@"; do echo $x; done)
    200     cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
    201 	 -set_serial 2 -days "${DAYS}"
    202 }
    203 
    204 genee() {
    205     local OPTIND=1
    206     local purpose=serverAuth
    207 
    208     while getopts p: o
    209     do
    210         case $o in
    211         p) purpose="$OPTARG";;
    212         *) echo "Usage: $0 genee [-p EKU] cn keyname certname cakeyname cacertname" >&2
    213            return 1;;
    214         esac
    215     done
    216 
    217     shift $((OPTIND - 1))
    218     local cn=$1; shift
    219     local key=$1; shift
    220     local cert=$1; shift
    221     local cakey=$1; shift
    222     local ca=$1; shift
    223 
    224     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
    225 	    "subjectKeyIdentifier = hash" \
    226 	    "authorityKeyIdentifier = keyid, issuer" \
    227 	    "basicConstraints = CA:false" \
    228 	    "extendedKeyUsage = $purpose" \
    229 	    "subjectAltName = @alts" "DNS=${cn}")
    230     csr=$(req "$key" "CN = $cn") || return 1
    231     echo "$csr" |
    232 	cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
    233 	    -set_serial 2 -days "${DAYS}" "$@"
    234 }
    235 
    236 geneenocsr() {
    237     local OPTIND=1
    238     local purpose=serverAuth
    239 
    240     while getopts p: o
    241     do
    242         case $o in
    243         p) purpose="$OPTARG";;
    244         *) echo "Usage: $0 genee [-p EKU] cn certname cakeyname cacertname" >&2
    245            return 1;;
    246         esac
    247     done
    248 
    249     shift $((OPTIND - 1))
    250     local cn=$1; shift
    251     local cert=$1; shift
    252     local cakey=$1; shift
    253     local ca=$1; shift
    254 
    255     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
    256 	    "subjectKeyIdentifier = hash" \
    257 	    "authorityKeyIdentifier = keyid, issuer" \
    258 	    "basicConstraints = CA:false" \
    259 	    "extendedKeyUsage = $purpose" \
    260 	    "subjectAltName = @alts" "DNS=${cn}")
    261 	cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
    262 	    -set_serial 2 -days "${DAYS}" "$@"
    263 }
    264 
    265 genss() {
    266     local cn=$1; shift
    267     local key=$1; shift
    268     local cert=$1; shift
    269 
    270     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
    271 	    "subjectKeyIdentifier   = hash" \
    272 	    "authorityKeyIdentifier = keyid, issuer" \
    273 	    "basicConstraints = CA:false" \
    274 	    "extendedKeyUsage = serverAuth" \
    275 	    "subjectAltName = @alts" "DNS=${cn}")
    276     csr=$(req "$key" "CN = $cn") || return 1
    277     echo "$csr" |
    278         cert "$cert" "$exts" -signkey "${key}.pem" \
    279             -set_serial 1 -days "${DAYS}" "$@"
    280 }
    281 
    282 gennocn() {
    283     local key=$1; shift
    284     local cert=$1; shift
    285 
    286     csr=$(req_nocn "$key") || return 1
    287     echo "$csr" |
    288 	cert "$cert" "" -signkey "${key}.pem" -set_serial 1 -days -1 "$@"
    289 }
    290 
    291 "$@"
    292