You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
3.7 KiB

  1. #!/bin/bash
  2. #:-
  3. . /etc/shlib
  4. #:-
  5. include common
  6. include pretty
  7. usage="$exname [--server] [--altname ALTNAME] [--days DAYS] COMMONNAME EMAIL"
  8. . /etc/default/ca
  9. CA_PASSWORD_FILE=${CA_PASSWORD_FILE:-$CA_CONFIG/password}
  10. if ! [ -e "$CA_PASSWORD_FILE" ]; then
  11. die "Password file '$CA_PASSWORD_FILE' does not exist. Either create it or set \$CA_PASSWORD_FILE."
  12. fi
  13. ##
  14. ## Arguments
  15. ##
  16. server_cert=
  17. altnames=()
  18. while [ "$1" ]; do
  19. case "$1" in
  20. "--server")
  21. server_cert=true
  22. ;;
  23. "--altname="*)
  24. altnames=(${altnames[@]} ${1#--altname=})
  25. ;;
  26. "--altname")
  27. altnames=(${altnames[@]} $2)
  28. shift
  29. ;;
  30. "--days="*)
  31. DAYS="${1#--altname=}"
  32. ;;
  33. "--days")
  34. DAYS="${2}"
  35. shift
  36. ;;
  37. *)
  38. [ -z ${common_name+x} ] && { common_name=$1 ; shift; continue; }
  39. [ -z ${email+x} ] && { email=$1 ; shift; continue; }
  40. die "Unexpected argument '$1'."
  41. ;;
  42. esac
  43. shift
  44. done
  45. if [ -z "${common_name+x}" ] || [ -z "${email+x}" ]; then
  46. err "Missing mandatory positional argument."
  47. print_usage
  48. exit 1
  49. fi
  50. for i in COUNTRY STATE ORGANISATION DAYS; do
  51. if [ -z "${!i}" ]; then
  52. die "Missing/Empty variable '$i'. You can add it to \`/etc/default/ca\`."
  53. fi
  54. done
  55. keyfile="$CA_DATA/keys/$common_name"
  56. if [ -e "$keyfile.crt+key" ]; then
  57. warn "Keyfile '$keyfile.crt+key' already exist."
  58. exit 0
  59. fi
  60. tmpdir=$(mktemp -d)
  61. trap 'rm -rf "$tmpdir"' EXIT
  62. ##
  63. ## Subject building
  64. ##
  65. subject=()
  66. [ -z "${COUNTRY+x}" ] || subject=("${subject[@]}" "C=$COUNTRY")
  67. [ -z "${STATE+x}" ] || subject=("${subject[@]}" "ST=$STATE")
  68. [ -z "${ORGANISATION+x}" ] || subject=("${subject[@]}" "O=$ORGANISATION")
  69. subject=("${subject[@]}" "CN=$common_name")
  70. subject=("${subject[@]}" "emailAddress=$email")
  71. SUBJECT=$(for elt in "${subject[@]}"; do echo -n "/$elt"; done)
  72. ##
  73. ## Openssl Options
  74. ##
  75. openssl_opts=()
  76. openssl_req_opts=()
  77. openssl_ca_opts=()
  78. [ -z "${DAYS+x}" ] && openssl_opts=("${openssl_opts[@]}" "-days" "$DAYS")
  79. if [ "$server_cert" ]; then
  80. if ! egrep "^#\s*nsCertType\s*=\s*server\s*$" "/etc/ssl/openssl.cnf" > /dev/null 2>&1; then
  81. err "Unexistent line about 'nsCertType' in '/etc/ssl/openssl.cnf' reference."
  82. die "Can't activate the server certificate."
  83. fi
  84. [ -e "$tmpdir/openssl.cnf" ] || cp /etc/ssl/openssl.cnf "$tmpdir/openssl.cnf"
  85. sed -ri 's/^#\s*(nsCertType\s*=\s*server\s*)$/\1/g' "$tmpdir/openssl.cnf"
  86. new_openssl_cnf=true
  87. fi
  88. if [ "${altnames[*]}" ]; then
  89. [ -e "$tmpdir/openssl.cnf" ] || cp /etc/ssl/openssl.cnf "$tmpdir/openssl.cnf"
  90. openssl_req_opts=("${openssl_req_opts[@]}" "-reqexts" SAN)
  91. openssl_ca_opts=("${openssl_ca_opts[@]}" "-extensions" SAN)
  92. cat <<EOF >> "$tmpdir/openssl.cnf"
  93. [SAN]
  94. subjectAltName = $(for altname in "${altnames[@]}"; do echo -n "DNS:$altname,"; done | rev | cut -c 2- | rev)
  95. EOF
  96. new_openssl_cnf=true
  97. fi
  98. [ "$new_openssl_cnf" ] && openssl_opts=("${openssl_opts[@]}" "-config" "$tmpdir/openssl.cnf")
  99. ##
  100. ## Okay, lets do the real work
  101. ##
  102. cd "$tmpdir"
  103. Wrap -q -d "Generating request" <<EOF || exit 1
  104. openssl req -new -nodes \
  105. -keyout "$tmpdir/newkey.pem" \
  106. -out "$tmpdir/newreq.pem" \
  107. -subj "$SUBJECT" \
  108. ${openssl_opts[@]} \
  109. ${openssl_req_opts[@]}
  110. EOF
  111. Wrap -q -d "Signing request" <<EOF || exit 1
  112. openssl ca -batch \
  113. -policy policy_anything \
  114. -out "$tmpdir/newcert.pem" \
  115. -passin file:"$CA_PASSWORD_FILE" \
  116. ${openssl_opts[@]} \
  117. ${openssl_ca_opts[@]} \
  118. -infiles "$tmpdir/newreq.pem"
  119. EOF
  120. mv newcert.pem "$keyfile.crt"
  121. mv newkey.pem "$keyfile.key"
  122. cat "$keyfile.crt" "$keyfile.key" > "$keyfile.crt+key"