github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/scripts/make-cert (about)

     1  #! /bin/bash --posix
     2  
     3  # make-cert: Make a signed certificate for a user/service that may be used to
     4  #            authenticate the user and grant access to methods.
     5  #
     6  # Usage: make-cert signing-key newkey serial username [methods]
     7  
     8  umask 077
     9  set -o noglob
    10  set -o nounset
    11  
    12  if [ "$#" -lt 4 ] || [ "$#" -gt 5 ]; then
    13      echo 'Usage: make-cert signing-key newkey serial username [methods]'
    14      echo '  methods: an optional filename of a file containing newline-separated'
    15      echo '           method names or a comma-separated list of method names'
    16      echo 'If serial="AUTO" then the serial numbers are auto-incremented and use'
    17      echo 'the .serial file to maintain state.'
    18      exit 1
    19  fi
    20  
    21  readonly signing_key="$1"
    22  readonly newkey="$2"
    23  
    24  KEY_LIFETIME=${KEY_LIFETIME:-1096}
    25  
    26  if [ "$3" = "AUTO" ]; then
    27      if [ -r .serial ]; then
    28  	old_serial=$(< .serial)
    29      else
    30  	old_serial=1
    31      fi
    32      readonly serial=$(($old_serial + 1))
    33      echo "$serial" > .serial
    34  else
    35      readonly serial="$3"
    36  fi
    37  
    38  readonly username="$4"
    39  
    40  if [ "$#" -lt 5 ]; then
    41      readonly methods=
    42  else
    43      readonly methods="$5"
    44  fi
    45  
    46  if [ ! -r "$signing_key.pem" ]; then
    47      echo "Unable to read: $signing_key.pem"
    48      exit 1
    49  fi
    50  if [ ! -r "$signing_key.key.pem" ]; then
    51      echo "Unable to read: $signing_key.key.pem"
    52      exit 1
    53  fi
    54  
    55  # First create methods extension file if appropriate.
    56  tmpfile="$(mktemp)"
    57  if [ -z "$methods" ]; then
    58      readonly methods_args=
    59  else
    60      readonly methods_args="-extensions methods_extension"
    61      counter=1
    62      echo '[methods_extension]'                                  > "$tmpfile"
    63      echo '1.3.6.1.4.1.9586.100.7.1=ASN1:SEQUENCE:methods_sect' >> "$tmpfile"
    64      echo '[methods_sect]'                                      >> "$tmpfile"
    65      if [ -r "$methods" ]; then
    66  	while read method || [ -n "$method" ]; do
    67  	    echo "field$counter=UTF8:\"$method\"" >> "$tmpfile"
    68  	    counter=$(($counter + 1))
    69  	done < "$methods"
    70      else
    71  	for method in $(tr , '\n' <<< "$methods"); do
    72  	    echo "field$counter=UTF8:\"$method\"" >> "$tmpfile"
    73  	    counter=$(($counter + 1))
    74  	done
    75      fi
    76  fi
    77  
    78  # Now generate the signed certificate.
    79  openssl genpkey -algorithm RSA -out "$newkey.key.pem" \
    80  		-pkeyopt rsa_keygen_bits:2048
    81  openssl req -new -key "$newkey.key.pem" -days "$KEY_LIFETIME" \
    82  	    -extensions v3_ca \
    83  	    -batch -out "$newkey.csr" -utf8 -subj "/CN=$username"
    84  openssl x509 -req -sha256 -days "$KEY_LIFETIME" -in "$newkey.csr" \
    85  	     -extfile "$tmpfile" $methods_args \
    86  	     -CAkey "$signing_key.key.pem" -CA "$signing_key.pem" \
    87  	     -set_serial "$serial" \
    88  	     -out "$newkey.pem"
    89  rm -f "$tmpfile"
    90  chmod a+r "$newkey.pem"