From afffbcfb82c931cc2518ff70eae397bf3a1c9c04 Mon Sep 17 00:00:00 2001 From: jfmartel Date: Mon, 12 May 2025 16:32:45 -0400 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20la=20m=C3=A9thode=20de=20migration?= =?UTF-8?q?=20du=20CA=20Server=20dans=20les=20notes=20de=20d=C3=A9veloppem?= =?UTF-8?q?ent=20et=20fichiers=20requis.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Doc interne/Notes de développement.docx | Bin 34037 -> 37722 bytes OpenVPN/CA Server/easy-rsa/easyrsa | 2579 +++++++++++ .../CA Server/easy-rsa/openssl-easyrsa.cnf | 138 + OpenVPN/CA Server/easy-rsa/pki/ca.crt | 20 + .../227AB3CB8805008CDFAF02BEAF63F959.pem | 71 + .../2A951944ADF0A2C8E81A4C541C1899E5.pem | 73 + .../3509162241A87805B57226316EC39402.pem | 71 + .../35F253A0DF2EA1227A3926855218BBD5.pem | 71 + .../44E31288C38E1632F41EBB13CA4D4C8D.pem | 71 + .../785E579993BEF247DACC6C8E0D713DF8.pem | 71 + .../7A066FB2ED7056F494707BB17BDCBE73.pem | 73 + .../A67F642294224A39B948259B999DAEA7.pem | 71 + .../ABBA5527AA06497B13DDF25BAE2708FE.pem | 71 + .../D1AE61458E84E38E5B923FAABB819D59.pem | 71 + OpenVPN/CA Server/easy-rsa/pki/index.txt | 10 + OpenVPN/CA Server/easy-rsa/pki/index.txt.attr | 1 + .../CA Server/easy-rsa/pki/index.txt.attr.old | 1 + OpenVPN/CA Server/easy-rsa/pki/index.txt.old | 9 + .../easy-rsa/pki/issued/DO_server.crt | 73 + .../easy-rsa/pki/issued/Otarcik202501.crt | 71 + OpenVPN/CA Server/easy-rsa/pki/issued/easyrsa | 4095 +++++++++++++++++ .../easy-rsa/pki/issued/edgerouterchambly.crt | 71 + .../CA Server/easy-rsa/pki/issued/fred.crt | 71 + OpenVPN/CA Server/easy-rsa/pki/issued/jf.crt | 71 + .../CA Server/easy-rsa/pki/issued/pascal.crt | 71 + .../easy-rsa/pki/issued/remoteclient.crt | 71 + .../easy-rsa/pki/issued/stationKA2401.crt | 71 + .../easy-rsa/pki/openssl-easyrsa.cnf | 138 + OpenVPN/CA Server/easy-rsa/pki/private/ca.key | 30 + .../CA Server/easy-rsa/pki/reqs/DO_server.req | 8 + .../easy-rsa/pki/reqs/Otarcik202501.req | 8 + .../easy-rsa/pki/reqs/edgerouterchambly.req | 8 + OpenVPN/CA Server/easy-rsa/pki/reqs/fred.req | 8 + OpenVPN/CA Server/easy-rsa/pki/reqs/jf.req | 8 + .../CA Server/easy-rsa/pki/reqs/pascal.req | 8 + .../easy-rsa/pki/reqs/remoteclient.req | 8 + .../easy-rsa/pki/reqs/stationKA2401.req | 8 + .../easy-rsa/pki/safessl-easyrsa.cnf | 138 + OpenVPN/CA Server/easy-rsa/pki/serial | 1 + OpenVPN/CA Server/easy-rsa/pki/serial.old | 1 + OpenVPN/CA Server/easy-rsa/vars | 9 + OpenVPN/CA Server/easy-rsa/vars.example | 221 + OpenVPN/ccd/Otarcik202501 | 1 + OpenVPN/ccd/remoteclient | 1 + OpenVPN/ccd/stationKA2401 | 1 + OpenVPN/jf2.ovpn | 269 ++ OpenVPN/server.conf | 9 +- Otarcik_CAN/Config/Station.cfg | Bin 709 -> 701 bytes Otarcik_CAN/Logs/SystemLog.txt | 36 + 49 files changed, 9048 insertions(+), 8 deletions(-) create mode 100644 OpenVPN/CA Server/easy-rsa/easyrsa create mode 100644 OpenVPN/CA Server/easy-rsa/openssl-easyrsa.cnf create mode 100644 OpenVPN/CA Server/easy-rsa/pki/ca.crt create mode 100644 OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/227AB3CB8805008CDFAF02BEAF63F959.pem create mode 100644 OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/2A951944ADF0A2C8E81A4C541C1899E5.pem create mode 100644 OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/3509162241A87805B57226316EC39402.pem create mode 100644 OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/35F253A0DF2EA1227A3926855218BBD5.pem create mode 100644 OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/44E31288C38E1632F41EBB13CA4D4C8D.pem create mode 100644 OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/785E579993BEF247DACC6C8E0D713DF8.pem create mode 100644 OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/7A066FB2ED7056F494707BB17BDCBE73.pem create mode 100644 OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/A67F642294224A39B948259B999DAEA7.pem create mode 100644 OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/ABBA5527AA06497B13DDF25BAE2708FE.pem create mode 100644 OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/D1AE61458E84E38E5B923FAABB819D59.pem create mode 100644 OpenVPN/CA Server/easy-rsa/pki/index.txt create mode 100644 OpenVPN/CA Server/easy-rsa/pki/index.txt.attr create mode 100644 OpenVPN/CA Server/easy-rsa/pki/index.txt.attr.old create mode 100644 OpenVPN/CA Server/easy-rsa/pki/index.txt.old create mode 100644 OpenVPN/CA Server/easy-rsa/pki/issued/DO_server.crt create mode 100644 OpenVPN/CA Server/easy-rsa/pki/issued/Otarcik202501.crt create mode 100644 OpenVPN/CA Server/easy-rsa/pki/issued/easyrsa create mode 100644 OpenVPN/CA Server/easy-rsa/pki/issued/edgerouterchambly.crt create mode 100644 OpenVPN/CA Server/easy-rsa/pki/issued/fred.crt create mode 100644 OpenVPN/CA Server/easy-rsa/pki/issued/jf.crt create mode 100644 OpenVPN/CA Server/easy-rsa/pki/issued/pascal.crt create mode 100644 OpenVPN/CA Server/easy-rsa/pki/issued/remoteclient.crt create mode 100644 OpenVPN/CA Server/easy-rsa/pki/issued/stationKA2401.crt create mode 100644 OpenVPN/CA Server/easy-rsa/pki/openssl-easyrsa.cnf create mode 100644 OpenVPN/CA Server/easy-rsa/pki/private/ca.key create mode 100644 OpenVPN/CA Server/easy-rsa/pki/reqs/DO_server.req create mode 100644 OpenVPN/CA Server/easy-rsa/pki/reqs/Otarcik202501.req create mode 100644 OpenVPN/CA Server/easy-rsa/pki/reqs/edgerouterchambly.req create mode 100644 OpenVPN/CA Server/easy-rsa/pki/reqs/fred.req create mode 100644 OpenVPN/CA Server/easy-rsa/pki/reqs/jf.req create mode 100644 OpenVPN/CA Server/easy-rsa/pki/reqs/pascal.req create mode 100644 OpenVPN/CA Server/easy-rsa/pki/reqs/remoteclient.req create mode 100644 OpenVPN/CA Server/easy-rsa/pki/reqs/stationKA2401.req create mode 100644 OpenVPN/CA Server/easy-rsa/pki/safessl-easyrsa.cnf create mode 100644 OpenVPN/CA Server/easy-rsa/pki/serial create mode 100644 OpenVPN/CA Server/easy-rsa/pki/serial.old create mode 100644 OpenVPN/CA Server/easy-rsa/vars create mode 100644 OpenVPN/CA Server/easy-rsa/vars.example create mode 100644 OpenVPN/ccd/Otarcik202501 create mode 100644 OpenVPN/ccd/remoteclient create mode 100644 OpenVPN/ccd/stationKA2401 create mode 100644 OpenVPN/jf2.ovpn diff --git a/Doc interne/Notes de développement.docx b/Doc interne/Notes de développement.docx index fe498b2dea2d601112f757359a0a981d52ce41f7..710eab4f01a5c04aa0d3a320b04f62e14e56dc76 100644 GIT binary patch delta 31385 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 G?f(InyuXY9 delta 27658 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 Z4Fdu3p6vY}t-&A62Bv^p4fu!mzW_|)yHo%G diff --git a/OpenVPN/CA Server/easy-rsa/easyrsa b/OpenVPN/CA Server/easy-rsa/easyrsa new file mode 100644 index 0000000..2c8134a --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/easyrsa @@ -0,0 +1,2579 @@ +#!/bin/sh + +# Easy-RSA 3 -- A Shell-based CA Utility +# +# Copyright (C) 2018 by the Open-Source OpenVPN development community. +# A full list of contributors can be found in the ChangeLog. +# +# This code released under version 2 of the GNU GPL; see COPYING and the +# Licensing/ directory of this project for full licensing details. + +# Help/usage output to stdout +usage() { + # command help: + print " +Easy-RSA 3 usage and overview + +USAGE: easyrsa [options] COMMAND [command-options] + +A list of commands is shown below. To get detailed usage and help for a +command, run: + ./easyrsa help COMMAND + +For a listing of options that can be supplied before the command, use: + ./easyrsa help options + +Here is the list of commands available with a short syntax reminder. Use the +'help' command above to get full usage details. + + init-pki + build-ca [ cmd-opts ] + gen-dh + gen-req [ cmd-opts ] + sign-req + build-client-full [ cmd-opts ] + build-server-full [ cmd-opts ] + revoke [cmd-opts] + renew [cmd-opts] + build-serverClient-full [ cmd-opts ] + gen-crl + update-db + show-req [ cmd-opts ] + show-cert [ cmd-opts ] + show-ca [ cmd-opts ] + import-req + export-p7 [ cmd-opts ] + export-p8 [ cmd-opts ] + export-p12 [ cmd-opts ] + set-rsa-pass [ cmd-opts ] + set-ec-pass [ cmd-opts ] + upgrade +" + + # collect/show dir status: + err_source="Not defined: vars autodetect failed and no value provided" + work_dir="${EASYRSA:-$err_source}" + pki_dir="${EASYRSA_PKI:-$err_source}" + print "\ +DIRECTORY STATUS (commands would take effect on these locations) + EASYRSA: $work_dir + PKI: $pki_dir +" +} # => usage() + +# Detailed command help +# When called with no args, calls usage(), otherwise shows help for a command +cmd_help() { + text="" + opts="" + case "$1" in + init-pki|clean-all) text=" + init-pki [ cmd-opts ] + Removes & re-initializes the PKI dir for a clean PKI" ;; + build-ca) text=" + build-ca [ cmd-opts ] + Creates a new CA" + opts=" + nopass - do not encrypt the CA key (default is encrypted) + subca - create an intermediate CA keypair and request (default is a root CA) + intca - alias to the above" ;; + gen-dh) text=" + gen-dh + Generates DH (Diffie-Hellman) parameters" ;; + gen-req) text=" + gen-req [ cmd-opts ] + Generate a standalone keypair and request (CSR) + + This request is suitable for sending to a remote CA for signing." + opts=" + nopass - do not encrypt the private key (default is encrypted)" ;; + sign|sign-req) text=" + sign-req + Sign a certificate request of the defined type. must be a known + type such as 'client', 'server', 'serverClient', or 'ca' (or a user-added type.) + + This request file must exist in the reqs/ dir and have a .req file + extension. See import-req below for importing reqs from other sources." ;; + build|build-client-full|build-server-full|build-serverClient-full) text=" + build-client-full [ cmd-opts ] + build-server-full [ cmd-opts ] + build-serverClient-full [ cmd-opts ] + Generate a keypair and sign locally for a client and/or server + + This mode uses the as the X509 CN." + opts=" + nopass - do not encrypt the private key (default is encrypted) + inline - create an inline credentials file for this node" ;; + revoke) text=" + revoke [reason] + Revoke a certificate specified by the filename_base, with an optional + revocation reason that is one of: + unspecified + keyCompromise + CACompromise + affiliationChanged + superseded + cessationOfOperation + certificateHold";; + renew) text=" + renew [ cmd-opts ] + Renew a certificate specified by the filename_base" + opts=" + nopass - do not encrypt the private key (default is encrypted)" ;; + gen-crl) text=" + gen-crl + Generate a CRL" ;; + update-db) text=" + update-db + Update the index.txt database + + This command will use the system time to update the status of issued + certificates." ;; + show-req|show-cert) text=" + show-req [ cmd-opts ] + show-cert [ cmd-opts ] + Shows details of the req or cert referenced by filename_base + + Human-readable output is shown, including any requested cert options when + showing a request." + opts=" + full - show full req/cert info, including pubkey/sig data" ;; + show-ca) text=" + show-ca [ cmd-opts ] + Shows details of the CA cert + + Human-readable output is shown." + opts=" + full - show full cert info, including pubkey/sig data" ;; + import-req) text=" + import-req + Import a certificate request from a file + + This will copy the specified file into the reqs/ dir in + preparation for signing. + The is the filename base to create. + + Example usage: + import-req /some/where/bob_request.req bob" ;; + export-p12) text=" + export-p12 [ cmd-opts ] + Export a PKCS#12 file with the keypair specified by " + opts=" + noca - do not include the ca.crt file in the PKCS12 output + nokey - do not include the private key in the PKCS12 output" ;; + export-p7) text=" + export-p7 [ cmd-opts ] + Export a PKCS#7 file with the pubkey specified by " + opts=" + noca - do not include the ca.crt file in the PKCS7 output" ;; + export-p8) text=" + export-p8 [ cmd-opts ] + Export a PKCS#8 file with the private key specified by " + opts=" + noca - do not include the ca.crt file in the PKCS7 output" ;; + set-rsa-pass|set-ec-pass) text=" + set-rsa-pass [ cmd-opts ] + set-ec-pass [ cmd-opts ] + Set a new passphrase on an RSA or EC key for the listed ." + opts=" + nopass - use no password and leave the key unencrypted + file - (advanced) treat the file as a raw path, not a short-name" ;; + upgrade) text=" + upgrade + Upgrade EasyRSA PKI and/or CA. must be one of: + pki - Upgrade EasyRSA v2.x PKI to EasyRSA v3.x PKI (includes CA below) + ca - Upgrade EasyRSA v3.0.5 CA or older to EasyRSA v3.0.6 CA or later." ;; + altname|subjectaltname|san) text=" + --subject-alt-name=SAN_FORMAT_STRING + This global option adds a subjectAltName to the request or issued + certificate. It MUST be in a valid format accepted by openssl or + req/cert generation will fail. Note that including multiple such names + requires them to be comma-separated; further invocations of this + option will REPLACE the value. + + Examples of the SAN_FORMAT_STRING shown below: + DNS:alternate.example.net + DNS:primary.example.net,DNS:alternate.example.net + IP:203.0.113.29 + email:alternate@example.net" ;; + options) + opt_usage ;; + "") + usage ;; + *) text=" + Unknown command: '$1' (try without commands for a list of commands)" ;; + esac + + # display the help text + print "$text" + [ -n "$opts" ] && print " + cmd-opts is an optional set of command options from this list: +$opts" +} # => cmd_help() + +# Options usage +opt_usage() { + print " +Easy-RSA Global Option Flags + +The following options may be provided before the command. Options specified +at runtime override env-vars and any 'vars' file in use. Unless noted, +non-empty values to options are mandatory. + +General options: + +--batch : set automatic (no-prompts when possible) mode +--passin=ARG : set -passin ARG for openssl +--passout=ARG : set -passout ARG for openssl +--pki-dir=DIR : declares the PKI directory +--vars=FILE : define a specific 'vars' file to use for Easy-RSA config +--version : prints EasyRSA version and build information, then exits + +Certificate & Request options: (these impact cert/req field values) + +--days=# : sets the signing validity to the specified number of days +--digest=ALG : digest to use in the requests & certificates +--dn-mode=MODE : DN mode to use (cn_only or org) +--keysize=# : size in bits of keypair to generate +--req-cn=NAME : default CN to use +--subca-len=# : path length of signed intermediate CA certs; must be >= 0 if used +--subject-alt-name : Add a subjectAltName. For more info and syntax, see: + ./easyrsa help altname +--use-algo=ALG : crypto alg to use: choose rsa (default) or ec +--curve=NAME : for elliptic curve, sets the named curve to use +--copy-ext : Copy included request X509 extensions (namely subjAltName + +Organizational DN options: (only used with the 'org' DN mode) + (values may be blank for org DN options) + +--req-c=CC : country code (2-letters) +--req-st=NAME : State/Province +--req-city=NAME : City/Locality +--req-org=NAME : Organization +--req-email=NAME : Email addresses +--req-ou=NAME : Organizational Unit + +Deprecated features: + +--ns-cert=YESNO : yes or no to including deprecated NS extensions +--ns-comment=COMMENT : NS comment to include (value may be blank) +" +} # => opt_usage() + +# Wrapper around printf - clobber print since it's not POSIX anyway +# shellcheck disable=SC1117 +print() { printf "%s\n" "$*" || exit 1; } + +# Exit fatally with a message to stderr +# present even with EASYRSA_BATCH as these are fatal problems +die() { + print " +Easy-RSA error: + +$1" 1>&2 + exit "${2:-1}" +} # => die() + +# non-fatal warning output +warn() { + [ ! "$EASYRSA_BATCH" ] && \ + print " +$1" 1>&2 + + return 0 +} # => warn() + +# informational notices to stdout +notice() { + [ ! "$EASYRSA_BATCH" ] && \ + print " +$1" + + return 0 +} # => notice() + +# yes/no case-insensitive match (operates on stdin pipe) +# Returns 0 when input contains yes, 1 for no, 2 for no match +# If both strings are present, returns 1; first matching line returns. +awk_yesno() { + #shellcheck disable=SC2016 + awkscript=' +BEGIN {IGNORECASE=1; r=2} +{ if(match($0,"no")) {r=1; exit} + if(match($0,"yes")) {r=0; exit} +} END {exit r}' + awk "$awkscript" +} # => awk_yesno() + +# intent confirmation helper func +# returns without prompting in EASYRSA_BATCH +confirm() { + [ "$EASYRSA_BATCH" ] && return + prompt="$1" + value="$2" + msg="$3" + input="" + print " +$msg + +Type the word '$value' to continue, or any other input to abort." + printf %s " $prompt" + #shellcheck disable=SC2162 + read input + [ "$input" = "$value" ] && return + notice "Aborting without confirmation." + exit 9 +} # => confirm() + +# mktemp wrapper +easyrsa_mktemp() { + [ -n "$EASYRSA_TEMP_DIR_session" ] || die "EASYRSA_TEMP_DIR_session not initialized!" + [ -d "$EASYRSA_TEMP_DIR_session" ] || mkdir -p "$EASYRSA_TEMP_DIR_session" || + die "Could not create temporary directory '$EASYRSA_TEMP_DIR_session'. Permission or concurrency problem?" + [ -d "$EASYRSA_TEMP_DIR_session" ] || die "Temporary directory '$EASYRSA_TEMP_DIR_session' does not exist" + + template="$EASYRSA_TEMP_DIR_session/tmp.XXXXXX" + tempfile=$(mktemp "$template") || return + + # win32 mktemp shipped by easyrsa returns template as file! + if [ "$template" = "$tempfile" ]; then + # but win32 mktemp -d does work + # but win32 mktemp -u does not work + tempfile=$(mktemp -du "$tempfile") || return + printf "" > "$tempfile" || return + fi + echo "$tempfile" +} # => easyrsa_mktemp + +# remove temp files and do terminal cleanups +cleanup() { + [ -z "$EASYRSA_TEMP_DIR_session" ] || rm -rf "$EASYRSA_TEMP_DIR_session" + # shellcheck disable=SC2039 + (stty echo 2>/dev/null) || { (set -o echo 2>/dev/null) && set -o echo; } + echo "" # just to get a clean line +} # => cleanup() + +easyrsa_openssl() { + openssl_command=$1; shift + + case $openssl_command in + makesafeconf) has_config=true;; + ca|req|srp|ts) has_config=true;; + *) has_config=false;; + esac + + if ! $has_config; then + "$EASYRSA_OPENSSL" "$openssl_command" "$@" + return + fi + + easyrsa_openssl_conf=$(easyrsa_mktemp) || die "Failed to create temporary file" + easyrsa_extra_exts= + if [ -n "$EASYRSA_EXTRA_EXTS" ]; then + easyrsa_extra_exts=$(easyrsa_mktemp) || die "Failed to create temporary file" + cat >"$easyrsa_extra_exts" <<-EOF + req_extensions = req_extra + [ req_extra ] + $EASYRSA_EXTRA_EXTS + EOF + fi + + # Make LibreSSL safe config file from OpenSSL config file + sed \ + -e "s\`ENV::EASYRSA\`EASYRSA\`g" \ + -e "s\`\$dir\`$EASYRSA_PKI\`g" \ + -e "s\`\$EASYRSA_PKI\`$EASYRSA_PKI\`g" \ + -e "s\`\$EASYRSA_CERT_EXPIRE\`$EASYRSA_CERT_EXPIRE\`g" \ + -e "s\`\$EASYRSA_CRL_DAYS\`$EASYRSA_CRL_DAYS\`g" \ + -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \ + -e "s\`\$EASYRSA_KEY_SIZE\`$EASYRSA_KEY_SIZE\`g" \ + -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \ + -e "s\`\$EASYRSA_DN\`$EASYRSA_DN\`g" \ + -e "s\`\$EASYRSA_REQ_COUNTRY\`$EASYRSA_REQ_COUNTRY\`g" \ + -e "s\`\$EASYRSA_REQ_PROVINCE\`$EASYRSA_REQ_PROVINCE\`g" \ + -e "s\`\$EASYRSA_REQ_CITY\`$EASYRSA_REQ_CITY\`g" \ + -e "s\`\$EASYRSA_REQ_ORG\`$EASYRSA_REQ_ORG\`g" \ + -e "s\`\$EASYRSA_REQ_OU\`$EASYRSA_REQ_OU\`g" \ + -e "s\`\$EASYRSA_REQ_CN\`$EASYRSA_REQ_CN\`g" \ + -e "s\`\$EASYRSA_REQ_EMAIL\`$EASYRSA_REQ_EMAIL\`g" \ + ${EASYRSA_EXTRA_EXTS:+-e "/^#%EXTRA_EXTS%/r $easyrsa_extra_exts"} \ + "$EASYRSA_SSL_CONF" > "$easyrsa_openssl_conf" || + die "Failed to update $easyrsa_openssl_conf" + + if [ "$openssl_command" = "makesafeconf" ]; then + cp "$easyrsa_openssl_conf" "$EASYRSA_SAFE_CONF" + err=$? + else + "$EASYRSA_OPENSSL" "$openssl_command" -config "$easyrsa_openssl_conf" "$@" + err=$? + fi + + rm -f "$easyrsa_openssl_conf" + rm -f "$easyrsa_extra_exts" + return $err +} # => easyrsa_openssl + +vars_source_check() { + # Check for defined EASYRSA_PKI + [ -n "$EASYRSA_PKI" ] || die "\ +EASYRSA_PKI env-var undefined" +} # => vars_source_check() + +# Verify supplied curve exists and generate curve file if needed +verify_curve_ec() { + if ! "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" > /dev/null; then + die "\ +Curve $EASYRSA_CURVE not found. Run openssl ecparam -list_curves to show a +list of supported curves." + fi + + # Check that the ecparams dir exists + [ -d "$EASYRSA_EC_DIR" ] || mkdir "$EASYRSA_EC_DIR" || die "\ +Failed creating ecparams dir (permissions?) at: +$EASYRSA_EC_DIR" + + # Check that the required ecparams file exists + out="$EASYRSA_EC_DIR/${EASYRSA_CURVE}.pem" + [ -f "$out" ] && return 0 + "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" -out "$out" || die "\ +Failed to generate ecparam file (permissions?) when writing to: +$out" + + # Explicitly return success for caller + return 0 +} + +# Verify if Edward Curve exists +verify_curve_ed() { + if [ "ed25519" = "$EASYRSA_CURVE" ] && "$EASYRSA_OPENSSL" genpkey -algorithm ED25519 > /dev/null; then + return 0 + elif [ "ed448" = "$EASYRSA_CURVE" ] && "$EASYRSA_OPENSSL" genpkey -algorithm ED448 > /dev/null; then + return 0 + fi + die "Curve $EASYRSA_CURVE not found." +} + +verify_ssl_lib () { + # Verify EASYRSA_OPENSSL command gives expected output + if [ -z "$EASYRSA_SSL_OK" ]; then + val="$("$EASYRSA_OPENSSL" version)" + case "${val%% *}" in + OpenSSL|LibreSSL) + print "\ +Using SSL: $EASYRSA_OPENSSL $("$EASYRSA_OPENSSL" version)" ;; + *) die "\ +Missing or invalid OpenSSL +Expected to find openssl command at: $EASYRSA_OPENSSL" ;; + esac + fi + EASYRSA_SSL_OK=1 + + # Verify EASYRSA_SSL_CONF file exists + [ -f "$EASYRSA_SSL_CONF" ] || die "\ +The OpenSSL config file cannot be found. +Expected location: $EASYRSA_SSL_CONF" +} # => verify_ssl_lib () + +# Basic sanity-check of PKI init and complain if missing +verify_pki_init() { + help_note="Run easyrsa without commands for usage and command help." + + # check that the pki dir exists + vars_source_check + [ -d "$EASYRSA_PKI" ] || die "\ +EASYRSA_PKI does not exist (perhaps you need to run init-pki)? +Expected to find the EASYRSA_PKI at: $EASYRSA_PKI +$help_note" + + # verify expected dirs present: + for i in private reqs; do + [ -d "$EASYRSA_PKI/$i" ] || die "\ +Missing expected directory: $i (perhaps you need to run init-pki?) +$help_note" + done + + # verify ssl lib + verify_ssl_lib +} # => verify_pki_init() + +# Verify core CA files present +verify_ca_init() { + help_note="Run without commands for usage and command help." + + # First check the PKI has been initialized + verify_pki_init + + # Verify expected files are present. Allow files to be regular files + # (or symlinks), but also pipes, for flexibility with ca.key + for i in serial index.txt index.txt.attr ca.crt private/ca.key; do + if [ ! -f "$EASYRSA_PKI/$i" ] && [ ! -p "$EASYRSA_PKI/$i" ]; then + [ "$1" = "test" ] && return 1 + die "\ +Missing expected CA file: $i (perhaps you need to run build-ca?) +$help_note" + fi + done + + # When operating in 'test' mode, return success. + # test callers don't care about CA-specific dir structure + [ "$1" = "test" ] && return 0 + + # verify expected CA-specific dirs: + for i in issued certs_by_serial + do + [ -d "$EASYRSA_PKI/$i" ] || die "\ +Missing expected CA dir: $i (perhaps you need to run build-ca?) +$help_note" + done + + # explicitly return success for callers + return 0 + +} # => verify_ca_init() + +# init-pki backend: +init_pki() { + + # If EASYRSA_PKI exists, confirm before we rm -rf (skiped with EASYRSA_BATCH) + if [ -e "$EASYRSA_PKI" ]; then + confirm "Confirm removal: " "yes" " +WARNING!!! + +You are about to remove the EASYRSA_PKI at: $EASYRSA_PKI +and initialize a fresh PKI here." + # now remove it: + rm -rf "$EASYRSA_PKI" || die "Removal of PKI dir failed. Check/correct errors above" + fi + + # new dirs: + for i in private reqs; do + mkdir -p "$EASYRSA_PKI/$i" || die "Failed to create PKI file structure (permissions?)" + done + + # Create $EASYRSA_SAFE_CONF ($OPENSSL_CONF) prevents bogus warnings (especially useful on win32) + if [ ! -f "$EASYRSA_SSL_CONF" ] && [ -f "$EASYRSA/openssl-easyrsa.cnf" ]; + then + cp "$EASYRSA/openssl-easyrsa.cnf" "$EASYRSA_SSL_CONF" + easyrsa_openssl makesafeconf + fi + + notice "\ +init-pki complete; you may now create a CA or requests. +Your newly created PKI dir is: $EASYRSA_PKI +" + return 0 +} # => init_pki() + +hide_read_pass() +{ + # shellcheck disable=SC2039 + if stty -echo 2>/dev/null; then + read -r "$@" + stty echo + elif (set +o echo 2>/dev/null); then + set +o echo + read -r "$@" + set -o echo + elif (echo | read -r -s 2>/dev/null) ; then + read -r -s "$@" + else + warn "Could not disable echo. Password will be shown on screen!" + read -r "$@" + fi +} # => hide_read_pass() + +# build-ca backend: +build_ca() { + opts="" + sub_ca="" + nopass="" + crypto="-aes256" + while [ -n "$1" ]; do + case "$1" in + intca) sub_ca=1 ;; + subca) sub_ca=1 ;; + nopass) nopass=1 ;; + *) warn "Ignoring unknown command option: '$1'" ;; + esac + shift + done + + verify_pki_init + [ "$EASYRSA_ALGO" = "ec" ] && verify_curve_ec + [ "$EASYRSA_ALGO" = "ed" ] && verify_curve_ed + + # setup for the simpler intermediate CA situation and overwrite with root-CA if needed: + out_file="$EASYRSA_PKI/reqs/ca.req" + out_key="$EASYRSA_PKI/private/ca.key" + if [ ! $sub_ca ]; then + out_file="$EASYRSA_PKI/ca.crt" + opts="$opts -x509 -days $EASYRSA_CA_EXPIRE " + fi + + # Test for existing CA, and complain if already present + if verify_ca_init test; then + die "\ +Unable to create a CA as you already seem to have one set up. +If you intended to start a new CA, run init-pki first." + fi + # If a private key exists here, a intermediate ca was created but not signed. + # Notify the user and require a signed ca.crt or a init-pki: + [ -f "$out_key" ] && \ + die "\ +A CA private key exists but no ca.crt is found in your PKI dir of: +$EASYRSA_PKI +Refusing to create a new CA keypair as this operation would overwrite your +current CA keypair. If you intended to start a new CA, run init-pki first." + + # create necessary files and dirs: + err_file="Unable to create necessary PKI files (permissions?)" + for i in issued certs_by_serial \ + revoked/certs_by_serial revoked/private_by_serial revoked/reqs_by_serial \ + renewed/certs_by_serial renewed/private_by_serial renewed/reqs_by_serial; + do + mkdir -p "$EASYRSA_PKI/$i" || die "$err_file" + done + printf "" > "$EASYRSA_PKI/index.txt" || die "$err_file" + printf "" > "$EASYRSA_PKI/index.txt.attr" || die "$err_file" + print "01" > "$EASYRSA_PKI/serial" || die "$err_file" + + # Default CN only when not in global EASYRSA_BATCH mode: + # shellcheck disable=SC2015 + [ "$EASYRSA_BATCH" ] && opts="$opts -batch" || export EASYRSA_REQ_CN="Easy-RSA CA" + + out_key_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + out_file_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + # Get password from user if necessary + if [ ! $nopass ] && ( [ -z "$EASYRSA_PASSOUT" ] || [ -z "$EASYRSA_PASSIN" ] ); then + out_key_pass_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + echo + printf "Enter New CA Key Passphrase: " + hide_read_pass kpass + echo + printf "Re-Enter New CA Key Passphrase: " + hide_read_pass kpass2 + echo + # shellcheck disable=2154 + if [ "$kpass" = "$kpass2" ]; + then + printf "%s" "$kpass" > "$out_key_pass_tmp" + else + die "Passphrases do not match." + fi + fi + + # create the CA key using AES256 + crypto_opts="" + if [ ! $nopass ]; then + crypto_opts="$crypto" + if [ -z "$EASYRSA_PASSOUT" ]; then + if [ "ed" = "$EASYRSA_ALGO" ]; then + crypto_opts="$crypto_opts -pass file:$out_key_pass_tmp" + else + crypto_opts="$crypto_opts -passout file:$out_key_pass_tmp" + fi + fi + fi + if [ "$EASYRSA_ALGO" = "rsa" ]; then + #shellcheck disable=SC2086 + "$EASYRSA_OPENSSL" genrsa -out "$out_key_tmp" $crypto_opts ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} "$EASYRSA_ALGO_PARAMS" || \ + die "Failed create CA private key" + elif [ "$EASYRSA_ALGO" = "ec" ]; then + #shellcheck disable=SC2086 + "$EASYRSA_OPENSSL" ecparam -in "$EASYRSA_ALGO_PARAMS" -genkey | \ + "$EASYRSA_OPENSSL" ec -out "$out_key_tmp" $crypto_opts ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} || \ + die "Failed create CA private key" + elif [ "ed" = "$EASYRSA_ALGO" ]; then + if [ "ed25519" = "$EASYRSA_CURVE" ]; then + "$EASYRSA_OPENSSL" genpkey -algorithm ED25519 -out $out_key_tmp $crypto_opts ${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} || \ + die "Failed create CA private key" + elif [ "ed448" = "$EASYRSA_CURVE" ]; then + "$EASYRSA_OPENSSL" genpkey -algorithm ED448 -out $out_key_tmp $crypto_opts ${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} || \ + die "Failed create CA private key" + fi + fi + + # create the CA keypair: + crypto_opts="" + [ ! $nopass ] && [ -z "$EASYRSA_PASSIN" ] && crypto_opts="-passin file:$out_key_pass_tmp" + + #shellcheck disable=SC2086 + easyrsa_openssl req -utf8 -new -key "$out_key_tmp" \ + -out "$out_file_tmp" $crypto_opts $opts ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} || \ + die "Failed to build the CA" + + mv "$out_key_tmp" "$out_key" + mv "$out_file_tmp" "$out_file" + [ -f "$out_key_pass_tmp" ] && rm "$out_key_pass_tmp" + + # Success messages + if [ $sub_ca ]; then + notice "\ +NOTE: Your intermediate CA request is at $out_file +and now must be sent to your parent CA for signing. Place your resulting cert +at $EASYRSA_PKI/ca.crt prior to signing operations. +" + else notice "\ +CA creation complete and you may now import and sign cert requests. +Your new CA certificate file for publishing is at: +$out_file +" + fi + return 0 +} # => build_ca() + +# gen-dh backend: +gen_dh() { + verify_pki_init + + out_file="$EASYRSA_PKI/dh.pem" + + # check to see if we already have a dh parameters file + if [ -e "$EASYRSA_PKI/dh.pem" ]; then + if [ "$EASYRSA_BATCH" = "1" ]; then + # if batch is enabled, die + die "file $EASYRSA_PKI/dh.pem already exists!" + else + # warn the user, give them a chance to force overwrite + confirm "Overwrite? " "yes" "*** File $EASYRSA_PKI/dh.pem already exists! ***" + fi + fi + + "$EASYRSA_OPENSSL" dhparam -out "$out_file" "$EASYRSA_KEY_SIZE" || \ + die "Failed to build DH params" + notice "\ +DH parameters of size $EASYRSA_KEY_SIZE created at $out_file +" + return 0 +} # => gen_dh() + +# gen-req backend: +gen_req() { + # pull filename base and use as default interactive CommonName: + [ -n "$1" ] || die "\ +Error: gen-req must have a file base as the first argument. +Run easyrsa without commands for usage and commands." + key_out="$EASYRSA_PKI/private/$1.key" + req_out="$EASYRSA_PKI/reqs/$1.req" + [ ! "$EASYRSA_BATCH" ] && EASYRSA_REQ_CN="$1" + shift + + # function opts support + opts= + while [ -n "$1" ]; do + case "$1" in + nopass) opts="$opts -nodes" ;; + # batch flag supports internal callers needing silent operation + batch) EASYRSA_BATCH=1 ;; + *) warn "Ignoring unknown command option: '$1'" ;; + esac + shift + done + + verify_pki_init + [ "$EASYRSA_ALGO" = "ec" ] && verify_curve_ec + [ "$EASYRSA_ALGO" = "ed" ] && verify_curve_ed + + # don't wipe out an existing private key without confirmation + [ -f "$key_out" ] && confirm "Confirm key overwrite: " "yes" "\ + +WARNING!!! + +An existing private key was found at $key_out +Continuing with key generation will replace this key." + + # When EASYRSA_EXTRA_EXTS is defined, append it to openssl's [req] section: + if [ -n "$EASYRSA_EXTRA_EXTS" ]; then + # Setup & insert the extra ext data keyed by a magic line + extra_exts=" +req_extensions = req_extra +[ req_extra ] +$EASYRSA_EXTRA_EXTS" + #shellcheck disable=SC2016 + awkscript=' +{if ( match($0, "^#%EXTRA_EXTS%") ) + { while ( getline<"/dev/stdin" ) {print} next } + {print} +}' + conf_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + print "$extra_exts" | \ + awk "$awkscript" "$EASYRSA_SSL_CONF" \ + > "$conf_tmp" \ + || die "Copying SSL config to temp file failed" + # Use this new SSL config for the rest of this function + EASYRSA_SSL_CONF="$conf_tmp" + fi + + key_out_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + req_out_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + # generate request + [ $EASYRSA_BATCH ] && opts="$opts -batch" + # shellcheck disable=2086,2148 + algo_opts="" + if [ "ed" = "$EASYRSA_ALGO" ]; then + algo_opts=" -newkey $EASYRSA_CURVE " + else + algo_opts=" -newkey $EASYRSA_ALGO:$EASYRSA_ALGO_PARAMS " + fi + easyrsa_openssl req -utf8 -new $algo_opts \ + -keyout "$key_out_tmp" -out "$req_out_tmp" $opts ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} \ + || die "Failed to generate request" + mv "$key_out_tmp" "$key_out" + mv "$req_out_tmp" "$req_out" + notice "\ +Keypair and certificate request completed. Your files are: +req: $req_out +key: $key_out +" + return 0 +} # => gen_req() + +# common signing backend +sign_req() { + crt_type="$1" + opts="" + req_in="$EASYRSA_PKI/reqs/$2.req" + crt_out="$EASYRSA_PKI/issued/$2.crt" + + # Randomize Serial number + if [ "$EASYRSA_RAND_SN" != "no" ]; + then + i="" + serial="" + check_serial="" + for i in 1 2 3 4 5; do + "$EASYRSA_OPENSSL" rand -hex -out "$EASYRSA_PKI/serial" 16 + serial="$(cat "$EASYRSA_PKI/serial")" + check_serial="$("$EASYRSA_OPENSSL" ca -config "$EASYRSA_SSL_CONF" -status "$serial" 2>&1)" + case "$check_serial" in + *"not present in db"*) break ;; + *) continue ;; + esac + done + fi + + # Support batch by internal caller: + [ "$3" = "batch" ] && EASYRSA_BATCH=1 + + verify_ca_init + + # Check argument sanity: + [ -n "$2" ] || die "\ +Incorrect number of arguments provided to sign-req: +expected 2, got $# (see command help for usage)" + + # Cert type must exist under the EASYRSA_EXT_DIR + [ -r "$EASYRSA_EXT_DIR/$crt_type" ] || die "\ +Unknown cert type '$crt_type'" + + # Request file must exist + [ -f "$req_in" ] || die "\ +No request found for the input: '$2' +Expected to find the request at: $req_in" + + # Confirm input is a cert req + verify_file req "$req_in" || die "\ +The certificate request file is not in a valid X509 request format. +File Path: $req_in" + + # Display the request subject in an easy-to-read format + # Confirm the user wishes to sign this request + confirm "Confirm request details: " "yes" " +You are about to sign the following certificate. +Please check over the details shown below for accuracy. Note that this request +has not been cryptographically verified. Please be sure it came from a trusted +source or that you have verified the request checksum with the sender. + +Request subject, to be signed as a $crt_type certificate for $EASYRSA_CERT_EXPIRE days: + +$(display_dn req "$req_in") +" # => confirm end + + # Generate the extensions file for this cert: + ext_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + { + # Append first any COMMON file (if present) then the cert-type extensions + cat "$EASYRSA_EXT_DIR/COMMON" + cat "$EASYRSA_EXT_DIR/$crt_type" + # copy req extensions + [ "$EASYRSA_CP_EXT" ] && print "copy_extensions = copy" + + # Support a dynamic CA path length when present: + [ "$crt_type" = "ca" ] && [ -n "$EASYRSA_SUBCA_LEN" ] && \ + print "basicConstraints = CA:TRUE, pathlen:$EASYRSA_SUBCA_LEN" + + # Deprecated Netscape extension support, if enabled + if print "$EASYRSA_NS_SUPPORT" | awk_yesno; then + [ -n "$EASYRSA_NS_COMMENT" ] && \ + print "nsComment = \"$EASYRSA_NS_COMMENT\"" + case "$crt_type" in + serverClient) print "nsCertType = serverClient" ;; + server) print "nsCertType = server" ;; + client) print "nsCertType = client" ;; + ca) print "nsCertType = sslCA" ;; + esac + fi + + # If type is server and no subjectAltName was requested, + # add one to the extensions file + if [ "$crt_type" = 'server' ] || [ "$crt_type" = 'serverClient' ]; + then + echo "$EASYRSA_EXTRA_EXTS" | grep -q subjectAltName + if [ $? -ne 0 ]; + then + san=$(display_san req "$req_in") + + if [ -n "$san" ]; + then + print "subjectAltName = $san" + else + default_server_san "$req_in" + fi + fi + fi + + # Add any advanced extensions supplied by env-var: + [ -n "$EASYRSA_EXTRA_EXTS" ] && print "$EASYRSA_EXTRA_EXTS" + + : # needed to keep die from inherting the above test + } > "$ext_tmp" || die "\ +Failed to create temp extension file (bad permissions?) at: +$ext_tmp" + + # sign request + crt_out_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + easyrsa_openssl ca -utf8 -in "$req_in" -out "$crt_out_tmp" \ + -extfile "$ext_tmp" -days "$EASYRSA_CERT_EXPIRE" -batch $opts ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} \ + || die "signing failed (openssl output above may have more detail)" + mv "$crt_out_tmp" "$crt_out" + rm -f "$ext_tmp" + notice "\ +Certificate created at: $crt_out +" + return 0 +} # => sign_req() + +# common build backend +# used to generate+sign in 1 step +build_full() { + verify_ca_init + + # pull filename base: + [ -n "$2" ] || die "\ +Error: didn't find a file base name as the first argument. +Run easyrsa without commands for usage and commands." + crt_type="$1" name="$2" + req_out="$EASYRSA_PKI/reqs/$2.req" + key_out="$EASYRSA_PKI/private/$2.key" + crt_out="$EASYRSA_PKI/issued/$2.crt" + shift 2 + + # function opts support + req_opts= + while [ -n "$1" ]; do + case "$1" in + nopass) req_opts="$req_opts nopass" ;; + inline) EASYRSA_INLINE=1 ;; + *) warn "Ignoring unknown command option: '$1'" ;; + esac + shift + done + + # abort on existing req/key/crt files + err_exists="\ +file already exists. Aborting build to avoid overwriting this file. +If you wish to continue, please use a different name or remove the file. +Matching file found at: " + [ -f "$req_out" ] && die "Request $err_exists $req_out" + [ -f "$key_out" ] && die "Key $err_exists $key_out" + [ -f "$crt_out" ] && die "Certificate $err_exists $crt_out" + + # create request + EASYRSA_REQ_CN="$name" + #shellcheck disable=SC2086 + gen_req "$name" batch $req_opts + + # Sign it + ( sign_req "$crt_type" "$name" batch ) || { + rm -f "$req_out" "$key_out" + die "Failed to sign '$name'" + } + + # inline it + if [ $EASYRSA_INLINE ]; then + inline_creds + fi +} # => build_full() + +# Create inline credentials file for this node +inline_creds () +{ + [ -f "$EASYRSA_PKI/$EASYRSA_REQ_CN.creds" ] \ + && die "Inline file exists: $EASYRSA_PKI/$EASYRSA_REQ_CN.creds" + { + printf "%s\n" "# $crt_type: $EASYRSA_REQ_CN" + printf "%s\n" "" + printf "%s\n" "" + cat "$EASYRSA_PKI/ca.crt" + printf "%s\n" "" + printf "%s\n" "" + printf "%s\n" "" + cat "$crt_out" + printf "%s\n" "" + printf "%s\n" "" + printf "%s\n" "" + cat "$key_out" + printf "%s\n" "" + printf "%s\n" "" + } > "$EASYRSA_PKI/$EASYRSA_REQ_CN.creds" +} # => inline_creds () + +# revoke backend +revoke() { + verify_ca_init + + # pull filename base: + [ -n "$1" ] || die "\ +Error: didn't find a file base name as the first argument. +Run easyrsa without commands for usage and command help." + crt_in="$EASYRSA_PKI/issued/$1.crt" + + opts="" + if [ "$2" ]; then + opts="$opts -crl_reason $2" + fi + + verify_file x509 "$crt_in" || die "\ +Unable to revoke as the input file is not a valid certificate. Unexpected +input in file: $crt_in" + + # confirm operation by displaying DN: + confirm "Continue with revocation: " "yes" " +Please confirm you wish to revoke the certificate with the following subject: + +$(display_dn x509 "$crt_in") +" # => confirm end + + # referenced cert must exist: + [ -f "$crt_in" ] || die "\ +Unable to revoke as no certificate was found. Certificate was expected +at: $crt_in" + + # shellcheck disable=SC2086 + easyrsa_openssl ca -utf8 -revoke "$crt_in" ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} $opts || die "\ +Failed to revoke certificate: revocation command failed." + + # move revoked files so we can reissue certificates with the same name + move_revoked "$1" + + notice "\ +IMPORTANT!!! + +Revocation was successful. You must run gen-crl and upload a CRL to your +infrastructure in order to prevent the revoked cert from being accepted. +" # => notice end + return 0 +} #= revoke() + +# move-revoked +# moves revoked certificates to an alternative folder +# allows reissuing certificates with the same name +move_revoked() { + verify_ca_init + + [ -n "$1" ] || die "\ +Error: didn't find a file base name as the first argument. +Run easyrsa without commands for usage and command help." + + crt_in="$EASYRSA_PKI/issued/$1.crt" + key_in="$EASYRSA_PKI/private/$1.key" + req_in="$EASYRSA_PKI/reqs/$1.req" + + verify_file x509 "$crt_in" || die "\ +Unable to move revoked input file. The file is not a valid certificate. Unexpected +input in file: $crt_in" + + if [ -e "$req_in" ] + then + verify_file req "$req_in" || die "\ +Unable to move request. The file is not a valid request. Unexpected +input in file: $req_in" + fi + + # get the serial number of the certificate -> serial=XXXX + cert_serial="$(easyrsa_openssl x509 -in "$crt_in" -noout -serial)" + # remove the serial= part -> we only need the XXXX part + cert_serial=${cert_serial##*=} + + crt_by_serial="$EASYRSA_PKI/certs_by_serial/$cert_serial.pem" + crt_by_serial_revoked="$EASYRSA_PKI/revoked/certs_by_serial/$cert_serial.crt" + key_by_serial_revoked="$EASYRSA_PKI/revoked/private_by_serial/$cert_serial.key" + req_by_serial_revoked="$EASYRSA_PKI/revoked/reqs_by_serial/$cert_serial.req" + + # make sure revoked dirs exist + [ -d "$EASYRSA_PKI/revoked" ] || mkdir "$EASYRSA_PKI/revoked" + [ -d "$EASYRSA_PKI/revoked/certs_by_serial" ] || mkdir "$EASYRSA_PKI/revoked/certs_by_serial" + [ -d "$EASYRSA_PKI/revoked/private_by_serial" ] || mkdir "$EASYRSA_PKI/revoked/private_by_serial" + [ -d "$EASYRSA_PKI/revoked/reqs_by_serial" ] || mkdir "$EASYRSA_PKI/revoked/reqs_by_serial" + + # move crt, key and req file to revoked folders + mv "$crt_in" "$crt_by_serial_revoked" + + # only move the req if we have it + [ -e "$req_in" ] && mv "$req_in" "$req_by_serial_revoked" + + # only move the key if we have it + [ -e "$key_in" ] && mv "$key_in" "$key_by_serial_revoked" + + # move the rest of the files (p12, p7, ...) + # shellcheck disable=SC2231 + for file in $EASYRSA_PKI/private/$1\.??? + do + # get file extension + file_ext="${file##*.}" + + [ -f "$file" ] && mv "$file" "$EASYRSA_PKI/revoked/private_by_serial/$cert_serial.$file_ext" + done + + # remove the dublicate certificate in the certs_by_serial folder + rm "$crt_by_serial" + + return 0 + +} #= move_revoked() + +# renew backend +renew() { + verify_ca_init + + # pull filename base: + [ -n "$1" ] || die "\ +Error: didn't find a file base name as the first argument. +Run easyrsa without commands for usage and command help." + crt_in="$EASYRSA_PKI/issued/$1.crt" + + opts="" + if [ "$2" ]; then + opts="$2" + fi + + verify_file x509 "$crt_in" || die "\ +Unable to renew as the input file is not a valid certificate. Unexpected +input in file: $crt_in" + + # confirm operation by displaying DN: + confirm "Continue with renew: " "yes" " +Please confirm you wish to renew the certificate with the following subject: + +$(display_dn x509 "$crt_in") +" # => confirm end + + # referenced cert must exist: + [ -f "$crt_in" ] || die "\ +Unable to renew as no certificate was found. Certificate was expected +at: $crt_in" + + # Check if old cert is expired or expires within 30 days + expire_date=$( + easyrsa_openssl x509 -in "$crt_in" -noout -enddate | + sed 's/^notAfter=//' + ) + case $(uname 2>/dev/null) in + "Darwin"|*"BSD") + expire_date=$(date -j -f '%b %d %T %Y %Z' "$expire_date" +%s) + allow_renew_date=$(date -j -v"+${EASYRSA_CERT_RENEW}d" +%s) + ;; + *) + # This works on Windows, too, since uname doesn't exist and this is catch-all + expire_date=$(date -d "$expire_date" +%s) + allow_renew_date=$(date -d "+${EASYRSA_CERT_RENEW}day" +%s) + ;; + esac + + [ "$expire_date" -lt "$allow_renew_date" ] || die "\ +Certificate expires in more than $EASYRSA_CERT_RENEW days. +Renewal not allowed." + + # Extract certificate usage from old cert + cert_ext_key_usage=$( + easyrsa_openssl x509 -in "$crt_in" -noout -text | + sed -n "/X509v3 Extended Key Usage:/{n;s/^ *//g;p;}" + ) + case $cert_ext_key_usage in + "TLS Web Client Authentication") + cert_type=client + ;; + "TLS Web Server Authentication") + cert_type=server + ;; + "TLS Web Server Authentication, TLS Web Client Authentication") + cert_type=serverClient + ;; + esac + + # Use SAN from --subject-alt-name if set else use SAN from old cert + echo "$EASYRSA_EXTRA_EXTS" | grep -q subjectAltName || \ + { + san=$( + easyrsa_openssl x509 -in "$crt_in" -noout -text | + sed -n "/X509v3 Subject Alternative Name:/{n;s/IP Address:/IP:/;s/ //g;p;}" + ) + [ -n "$san" ] && export EASYRSA_EXTRA_EXTS="\ +$EASYRSA_EXTRA_EXTS +subjectAltName = $san" + } + + # move renewed files so we can reissue certificate with the same name + # FIXME: Modify revoke() to also work on the renewed certs subdir + move_renewed "$1" + + # renew certificate + # shellcheck disable=SC2086 + build_full $cert_type $1 $opts || die "\ +Failed to renew certificate: renew command failed." + + notice "\ +IMPORTANT!!! + +Renew was successful. +You may want to revoke the old certificate once the new one has been deployed. +" # => notice end + return 0 +} #= renew() + +# move-renewed +# moves renewed certificates to an alternative folder +# allows reissuing certificates with the same name +move_renewed() { + verify_ca_init + + [ -n "$1" ] || die "\ +Error: didn't find a file base name as the first argument. +Run easyrsa without commands for usage and command help." + + crt_in="$EASYRSA_PKI/issued/$1.crt" + key_in="$EASYRSA_PKI/private/$1.key" + req_in="$EASYRSA_PKI/reqs/$1.req" + + verify_file x509 "$crt_in" || die "\ +Unable to move renewed input file. The file is not a valid certificate. Unexpected +input in file: $crt_in" + + if [ -e "$req_in" ] + then + verify_file req "$req_in" || die "\ +Unable to move request. The file is not a valid request. Unexpected +input in file: $req_in" + fi + + # get the serial number of the certificate -> serial=XXXX + cert_serial="$(easyrsa_openssl x509 -in "$crt_in" -noout -serial)" + # remove the serial= part -> we only need the XXXX part + cert_serial=${cert_serial##*=} + + crt_by_serial="$EASYRSA_PKI/certs_by_serial/$cert_serial.pem" + crt_by_serial_renewed="$EASYRSA_PKI/renewed/certs_by_serial/$cert_serial.crt" + key_by_serial_renewed="$EASYRSA_PKI/renewed/private_by_serial/$cert_serial.key" + req_by_serial_renewed="$EASYRSA_PKI/renewed/reqs_by_serial/$cert_serial.req" + + # make sure renewed dirs exist + [ -d "$EASYRSA_PKI/renewed" ] || mkdir "$EASYRSA_PKI/renewed" + [ -d "$EASYRSA_PKI/renewed/certs_by_serial" ] || mkdir "$EASYRSA_PKI/renewed/certs_by_serial" + [ -d "$EASYRSA_PKI/renewed/private_by_serial" ] || mkdir "$EASYRSA_PKI/renewed/private_by_serial" + [ -d "$EASYRSA_PKI/renewed/reqs_by_serial" ] || mkdir "$EASYRSA_PKI/renewed/reqs_by_serial" + + # move crt, key and req file to renewed folders + mv "$crt_in" "$crt_by_serial_renewed" + + # only move the req if we have it + [ -e "$req_in" ] && mv "$req_in" "$req_by_serial_renewed" + + # only move the key if we have it + [ -e "$key_in" ] && mv "$key_in" "$key_by_serial_renewed" + + # move the rest of the files (p12, p7, ...) + # shellcheck disable=SC2231 + for file in $EASYRSA_PKI/private/$1\.??? + do + # get file extension + file_ext="${file##*.}" + + [ -f "$file" ] && mv "$file" "$EASYRSA_PKI/renewed/private_by_serial/$cert_serial.$file_ext" + done + + # remove the duplicate certificate in the certs_by_serial folder + rm "$crt_by_serial" + + return 0 + +} #= move_renewed() + +# gen-crl backend +gen_crl() { + verify_ca_init + + out_file="$EASYRSA_PKI/crl.pem" + out_file_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + easyrsa_openssl ca -utf8 -gencrl -out "$out_file_tmp" ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} || die "\ +CRL Generation failed. +" + mv "$out_file_tmp" "$out_file" + + notice "\ +An updated CRL has been created. +CRL file: $out_file +" + return 0 +} # => gen_crl() + +# import-req backend +import_req() { + verify_pki_init + + # pull passed paths + in_req="$1" short_name="$2" + out_req="$EASYRSA_PKI/reqs/$2.req" + + [ -n "$short_name" ] || die "\ +Unable to import: incorrect command syntax. +Run easyrsa without commands for usage and command help." + + verify_file req "$in_req" || die "\ +The input file does not appear to be a certificate request. Aborting import. +File Path: $in_req" + + # destination must not exist + [ -f "$out_req" ] && die "\ +Unable to import the request as the destination file already exists. +Please choose a different name for your imported request file. +Existing file at: $out_req" + + # now import it + cp "$in_req" "$out_req" + + notice "\ +The request has been successfully imported with a short name of: $short_name +You may now use this name to perform signing operations on this request. +" + return 0 +} # => import_req() + +# export pkcs#12 or pkcs#7 +export_pkcs() { + pkcs_type="$1" + shift + + [ -n "$1" ] || die "\ +Unable to export p12: incorrect command syntax. +Run easyrsa without commands for usage and command help." + + short_name="$1" + crt_in="$EASYRSA_PKI/issued/$1.crt" + key_in="$EASYRSA_PKI/private/$1.key" + crt_ca="$EASYRSA_PKI/ca.crt" + shift + + verify_pki_init + + # opts support + want_ca=1 + want_key=1 + want_pass=1 + while [ -n "$1" ]; do + case "$1" in + noca) want_ca="" ;; + nokey) want_key="" ;; + nopass) want_pass="" ;; + *) warn "Ignoring unknown command option: '$1'" ;; + esac + shift + done + + pkcs_opts= + if [ $want_ca ]; then + verify_file x509 "$crt_ca" || die "\ +Unable to include CA cert in the $pkcs_type output (missing file, or use noca option.) +Missing file expected at: $crt_ca" + pkcs_opts="$pkcs_opts -certfile $crt_ca" + fi + + # input files must exist + verify_file x509 "$crt_in" || die "\ +Unable to export $pkcs_type for short name '$short_name' without the certificate. +Missing cert expected at: $crt_in" + + case "$pkcs_type" in + p12) + pkcs_out="$EASYRSA_PKI/private/$short_name.p12" + + if [ $want_key ]; then + [ -f "$key_in" ] || die "\ +Unable to export p12 for short name '$short_name' without the key +(if you want a p12 without the private key, use nokey option.) +Missing key expected at: $key_in" + else + pkcs_opts="$pkcs_opts -nokeys" + fi + + # export the p12: + # shellcheck disable=SC2086 + easyrsa_openssl pkcs12 -in "$crt_in" -inkey "$key_in" -export \ + -out "$pkcs_out" $pkcs_opts ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} || die "\ +Export of p12 failed: see above for related openssl errors." + ;; + p7) + pkcs_out="$EASYRSA_PKI/issued/$short_name.p7b" + + # export the p7: + # shellcheck disable=SC2086 + easyrsa_openssl crl2pkcs7 -nocrl -certfile "$crt_in" \ + -out "$pkcs_out" $pkcs_opts ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} || die "\ +Export of p7 failed: see above for related openssl errors." + ;; + p8) + if [ -z $want_pass ]; then + pkcs_opts="-nocrypt" + else + pkcs_opts="" + fi + pkcs_out="$EASYRSA_PKI/private/$short_name.p8" + + # export the p8: + # shellcheck disable=SC2086 + easyrsa_openssl pkcs8 -in "$key_in" -topk8 \ + -out "$pkcs_out" $pkcs_opts ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} || die "\ +Export of p8 failed: see above for related openssl errors." + ;; +esac + + notice "\ +Successful export of $pkcs_type file. Your exported file is at the following +location: $pkcs_out +" + return 0 +} # => export_pkcs() + +# set-pass backend +set_pass() { + verify_pki_init + + # key type, supplied internally from frontend command call (rsa/ec) + key_type="$1" + + # values supplied by the user: + raw_file="$2" + file="$EASYRSA_PKI/private/$raw_file.key" + [ -n "$raw_file" ] || die "\ +Missing argument to 'set-$key_type-pass' command: no name/file supplied. +See help output for usage details." + + # parse command options + shift 2 + crypto="-aes256" + while [ -n "$1" ]; do + case "$1" in + nopass) crypto="" ;; + file) file="$raw_file" ;; + *) warn "Ignoring unknown command option: '$1'" ;; + esac + shift + done + + [ -f "$file" ] || die "\ +Missing private key: expected to find the private key component at: +$file" + + notice "\ +If the key is currently encrypted you must supply the decryption passphrase. +${crypto:+You will then enter a new PEM passphrase for this key.$NL}" + + out_key_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + easyrsa_openssl "$key_type" -in "$file" -out "$out_key_tmp" $crypto ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} || die "\ +Failed to change the private key passphrase. See above for possible openssl +error messages." + + mv "$out_key_tmp" "$file" || die "\ +Failed to change the private key passphrase. See above for error messages." + + notice "Key passphrase successfully changed" + + return 0 +} # => set_pass() + +# update-db backend +update_db() { + verify_ca_init + + easyrsa_openssl ca -utf8 -updatedb ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} || die "\ +Failed to perform update-db: see above for related openssl errors." + return 0 +} # => update_db() + +display_san() { + format="$1" path="$2" + + echo "$EASYRSA_EXTRA_EXTS" | grep -q subjectAltName + + if [ $? -eq 0 ]; then + print "$(echo "$EASYRSA_EXTRA_EXTS" | grep subjectAltName | sed 's/^\s*subjectAltName\s*=\s*//')" + else + san=$( + "$EASYRSA_OPENSSL" "$format" -in "$path" -noout -text | + sed -n "/X509v3 Subject Alternative Name:/{n;s/ //g;s/IPAddress:/IP:/g;s/RegisteredID/RID/;p;}" + ) + + [ -n "$san" ] && print "$san" + fi +} + +# display cert DN info on a req/X509, passed by full pathname +display_dn() { + format="$1" path="$2" + print "$("$EASYRSA_OPENSSL" "$format" -in "$path" -noout -subject -nameopt multiline)" + san=$(display_san "$1" "$2") + if [ -n "$san" ]; then + print "" + print "X509v3 Subject Alternative Name:" + print " $san" + fi + +} # => display_dn() + +# generate default SAN from req/X509, passed by full pathname +default_server_san() { + path="$1" + cn=$( + easyrsa_openssl req -in "$path" -noout -subject -nameopt sep_multiline | + awk -F'=' '/^ *CN=/{print $2}' + ) + echo "$cn" | grep -E -q '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$' + #shellcheck disable=SC2181 + if [ $? -eq 0 ]; then + print "subjectAltName = IP:$cn" + else + print "subjectAltName = DNS:$cn" + fi +} # => default_server_san() + +# verify a file seems to be a valid req/X509 +verify_file() { + format="$1" + path="$2" + easyrsa_openssl "$format" -in "$path" -noout 2>/dev/null || return 1 + return 0 +} # => verify_file() + +# show-* command backend +# Prints req/cert details in a readable format +show() { + type="$1" + name="$2" + in_file="" + format="" + [ -n "$name" ] || die "\ +Missing expected filename_base argument. +Run easyrsa without commands for usage help." + shift 2 + + # opts support + opts="-${type}opt no_pubkey,no_sigdump" + while [ -n "$1" ]; do + case "$1" in + full) + opts="" + ;; + *) + warn "Ignoring unknown command option: '$1'" + ;; + esac + shift + done + + # Determine cert/req type + if [ "$type" = "cert" ]; then + verify_ca_init + in_file="$EASYRSA_PKI/issued/${name}.crt" + format="x509" + else + verify_pki_init + in_file="$EASYRSA_PKI/reqs/${name}.req" + format="req" + fi + + # Verify file exists and is of the correct type + [ -f "$in_file" ] || die "\ +No such $type file with a basename of '$name' is present. +Expected to find this file at: +$in_file" + verify_file $format "$in_file" || die "\ +This file is not a valid $type file: +$in_file" + + notice "\ +Showing $type details for '$name'. +This file is stored at: +$in_file +" + easyrsa_openssl $format -in "$in_file" -noout -text\ + -nameopt multiline $opts || die "\ +OpenSSL failure to process the input" +} # => show() + +# show-ca command backend +# Prints CA cert details in a readable format +show_ca() { + # opts support + opts="-certopt no_pubkey,no_sigdump" + while [ -n "$1" ]; do + case "$1" in + full) opts= ;; + *) warn "Ignoring unknown command option: '$1'" ;; + esac + shift + done + + verify_ca_init + in_file="$EASYRSA_PKI/ca.crt" + format="x509" + + # Verify file exists and is of the correct type + [ -f "$in_file" ] || die "\ +No such $type file with a basename of '$name' is present. +Expected to find this file at: +$in_file" + verify_file $format "$in_file" || die "\ +This file is not a valid $type file: +$in_file" + + notice "\ +Showing $type details for 'ca'. +This file is stored at: +$in_file +" + easyrsa_openssl $format -in "$in_file" -noout -text\ + -nameopt multiline $opts || die "\ +OpenSSL failure to process the input" +} # => show_ca() + +# vars setup +# Here sourcing of 'vars' if present occurs. If not present, defaults are used +# to support running without a sourced config format +vars_setup() { + # Try to locate a 'vars' file in order of location preference. + # If one is found, source it + vars= + + # set up program path + prog_file="$0" + prog_file2="$(which -- "$prog_file" 2>/dev/null)" && prog_file="$prog_file2" + prog_file2="$(readlink -f "$prog_file" 2>/dev/null)" && prog_file="$prog_file2" + prog_dir="${prog_file%/*}" + prog_vars="${prog_dir}/vars" + # set up PKI path + pki_vars="${EASYRSA_PKI:-$PWD/pki}/vars" + + # command-line path: + if [ ! -z "$EASYRSA_VARS_FILE" ]; then + if [ ! -f "$EASYRSA_VARS_FILE" ]; then + # If the --vars option does not point to a file, show helpful error. + die "The file '$EASYRSA_VARS_FILE' was not found." + fi + vars="$EASYRSA_VARS_FILE" + # PKI location, if present: + elif [ -f "$pki_vars" ]; then + vars="$pki_vars" + # EASYRSA, if defined: + elif [ -n "$EASYRSA" ] && [ -f "$EASYRSA/vars" ]; then + vars="$EASYRSA/vars" + # program location: + elif [ -f "$prog_vars" ]; then + vars="$prog_vars" + fi + + # If a vars file was located, source it + # If $EASYRSA_NO_VARS is defined (not blank) this is skipped + if [ -z "$EASYRSA_NO_VARS" ] && [ -n "$vars" ]; then + if grep -Eq 'EASYRSA_PASSIN|EASYRSA_PASSOUT' "$vars"; then + die "\ +Variable EASYRSA_PASSIN or EASYRSA_PASSOUT has been found in the configuration \ +file. Storing sensitive information in the configuration file is not \ +recommended - please remove it from there before continuing." + fi + #shellcheck disable=SC2034 + EASYRSA_CALLER=1 + # shellcheck disable=SC1090 + . "$vars" + notice "\ +Note: using Easy-RSA configuration from: $vars" + fi + + # Set defaults, preferring existing env-vars if present + set_var EASYRSA "$prog_dir" + set_var EASYRSA_OPENSSL openssl + set_var EASYRSA_PKI "$PWD/pki" + set_var EASYRSA_DN cn_only + set_var EASYRSA_REQ_COUNTRY "US" + set_var EASYRSA_REQ_PROVINCE "California" + set_var EASYRSA_REQ_CITY "San Francisco" + set_var EASYRSA_REQ_ORG "Copyleft Certificate Co" + set_var EASYRSA_REQ_EMAIL me@example.net + set_var EASYRSA_REQ_OU "My Organizational Unit" + set_var EASYRSA_ALGO rsa + set_var EASYRSA_KEY_SIZE 2048 + set_var EASYRSA_CURVE secp384r1 + set_var EASYRSA_EC_DIR "$EASYRSA_PKI/ecparams" + set_var EASYRSA_CA_EXPIRE 3650 + set_var EASYRSA_CERT_EXPIRE 825 # new default of 36 months + set_var EASYRSA_CERT_RENEW 30 + set_var EASYRSA_CRL_DAYS 180 + set_var EASYRSA_NS_SUPPORT no + set_var EASYRSA_NS_COMMENT "Easy-RSA (3.0.8) Generated Certificate" + set_var EASYRSA_TEMP_DIR "$EASYRSA_PKI" + set_var EASYRSA_REQ_CN ChangeMe + set_var EASYRSA_DIGEST sha256 + set_var EASYRSA_SSL_CONF "$EASYRSA_PKI/openssl-easyrsa.cnf" + set_var EASYRSA_SAFE_CONF "$EASYRSA_PKI/safessl-easyrsa.cnf" + set_var EASYRSA_KDC_REALM "CHANGEME.EXAMPLE.COM" + + # Same as above for the x509-types extensions dir + if [ -d "$EASYRSA_PKI/x509-types" ]; then + set_var EASYRSA_EXT_DIR "$EASYRSA_PKI/x509-types" + else + #TODO: This should be removed. Not really suitable for packaging. + set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types" + fi + + # EASYRSA_ALGO_PARAMS must be set depending on selected algo + if [ "ec" = "$EASYRSA_ALGO" ]; then + EASYRSA_ALGO_PARAMS="$EASYRSA_EC_DIR/${EASYRSA_CURVE}.pem" + elif [ "rsa" = "$EASYRSA_ALGO" ]; then + EASYRSA_ALGO_PARAMS="${EASYRSA_KEY_SIZE}" + elif [ "ed" != "$EASYRSA_ALGO" ]; then + die "Alg '$EASYRSA_ALGO' is invalid: must be 'rsa', 'ec' or 'ed' " + fi + + # Assign value to $EASYRSA_TEMP_DIR_session and work around Windows mktemp bug when parent dir is missing + if [ -z "$EASYRSA_TEMP_DIR_session" ]; then + if [ -d "$EASYRSA_TEMP_DIR" ]; then + EASYRSA_TEMP_DIR_session="$(mktemp -du "$EASYRSA_TEMP_DIR/easy-rsa-$$.XXXXXX")" + else + # If the directory does not exist then we have not run init-pki + mkdir -p "$EASYRSA_TEMP_DIR" || die "Cannot create $EASYRSA_TEMP_DIR (permission?)" + EASYRSA_TEMP_DIR_session="$(mktemp -du "$EASYRSA_TEMP_DIR/easy-rsa-$$.XXXXXX")" + rm -rf "$EASYRSA_TEMP_DIR" + fi + fi + + # Setting OPENSSL_CONF prevents bogus warnings (especially useful on win32) + export OPENSSL_CONF="$EASYRSA_SAFE_CONF" + + # Upgrade to 306: Create $EASYRSA_SSL_CONF if it does not exist but only if $EASYRSA_PKI exists. + if [ ! -f "$EASYRSA_SSL_CONF" ] && [ -f "$EASYRSA/openssl-easyrsa.cnf" ] && [ -d "$EASYRSA_PKI" ]; + then + cp "$EASYRSA/openssl-easyrsa.cnf" "$EASYRSA_SSL_CONF" + easyrsa_openssl makesafeconf + fi + +} # vars_setup() + +# variable assignment by indirection when undefined; merely exports +# the variable when it is already defined (even if currently null) +# Sets $1 as the value contained in $2 and exports (may be blank) +set_var() { + var=$1 + shift + value="$*" + eval "export $var=\"\${$var-$value}\"" +} #=> set_var() + + +############################################################################ +# Upgrade v2 PKI to v3 PKI + +# You can report problems on the normal openvpn support channels: +# -------------------------------------------------------------------------- +# 1. The Openvpn Forum: https://forums.openvpn.net/viewforum.php?f=31 +# 2. The #easyrsa IRC channel at freenode +# 3. Info: https://community.openvpn.net/openvpn/wiki/easyrsa-upgrade +# -------------------------------------------------------------------------- +# + +up23_fail_upgrade () +{ + # Replace die() + unset EASYRSA_BATCH + notice " +============================================================================ +The update has failed but NOTHING has been lost. + +ERROR: $1 +---------------------------------------------------------------------------- + +Further info: +* https://community.openvpn.net/openvpn/wiki/easyrsa-upgrade#ersa-up23-fails + +Easyrsa3 upgrade FAILED +============================================================================ +" + exit 9 +} #=> up23_fail_upgrade () + +up23_verbose () +{ + [ "$VERBOSE" ] || return 0 + printf "%s\n" "$1" +} #=> up23_verbose () + +up23_verify_new_pki () +{ + # Fail now, before any changes are made + + up23_verbose "> Verify DEFAULT NEW PKI does not exist .." + EASYRSA_NEW_PKI="$EASYRSA/pki" + [ -d "$EASYRSA_NEW_PKI" ] \ + && up23_fail_upgrade "DEFAULT NEW PKI exists: $EASYRSA_NEW_PKI" + + up23_verbose "> Verify VERY-SAFE-PKI does not exist .." + EASYRSA_SAFE_PKI="$EASYRSA/VERY-SAFE-PKI" + [ -d "$EASYRSA_SAFE_PKI" ] \ + && up23_fail_upgrade "VERY-SAFE-PKI exists: $EASYRSA_SAFE_PKI" + + up23_verbose "> Verify openssl-easyrsa.cnf does exist .." + EASYRSA_SSL_CNFFILE="$EASYRSA/openssl-easyrsa.cnf" + [ -f "$EASYRSA_SSL_CNFFILE" ] \ + || up23_fail_upgrade "cannot find $EASYRSA_SSL_CNFFILE" + + up23_verbose "> Verify vars.example does exist .." + EASYRSA_VARSV3_EXMP="$EASYRSA/vars.example" + [ -f "$EASYRSA_VARSV3_EXMP" ] \ + || up23_fail_upgrade "cannot find $EASYRSA_VARSV3_EXMP" + + up23_verbose "> OK" + up23_verbose " Initial dirs & files are in a workable state." +} #=> up23_verify_new_pki () + +up23_verify_current_pki () +{ + up23_verbose "> Verify CURRENT PKI vars .." + + # This can probably be improved + EASYRSA_NO_REM="$(grep '^set ' "$EASYRSA_VER2_VARSFILE")" + + # This list may not be complete + # Not required: DH_KEY_SIZE PKCS11_MODULE_PATH PKCS11_PIN + for i in KEY_DIR KEY_SIZE KEY_COUNTRY KEY_PROVINCE \ + KEY_CITY KEY_ORG KEY_EMAIL KEY_CN KEY_NAME KEY_OU + do + # Effectively, source the v2 vars file + UNIQUE="set $i" + KEY_grep="$(printf "%s\n" "$EASYRSA_NO_REM" | grep "$UNIQUE")" + KEY_value="${KEY_grep##*=}" + set_var $i "$KEY_value" + done + + [ -d "$KEY_DIR" ] || up23_fail_upgrade "Cannot find CURRENT PKI KEY_DIR: $KEY_DIR" + + up23_verbose "> OK" + up23_verbose " Current CURRENT PKI vars uses PKI in: $KEY_DIR" +} #=> up23_verify_current_pki () + +up23_verify_current_ca () +{ + up23_verbose "> Find CA .." + # $KEY_DIR is assigned in up23_verify_current_pki () + [ -f "$KEY_DIR/ca.crt" ] \ + || up23_fail_upgrade "Cannot find current ca.crt: $KEY_DIR/ca.crt" + up23_verbose "> OK" + + # If CA is already verified then return + in_file="$KEY_DIR/ca.crt" + [ "$CURRENT_CA_IS_VERIFIED" = "$in_file" ] && return 0 + format="x509" + + # Current CA is unverified + # Extract the current CA details + CA_SUBJECT="$(easyrsa_openssl $format -in "$in_file" -subject -noout -nameopt multiline)" + + # Extract individual elements + CA_countryName="$(printf "%s\n" "$CA_SUBJECT" \ + | grep countryName | sed "s\`^.*=\ \`\`g")" + CA_stateOrProvinceName="$(printf "%s\n" "$CA_SUBJECT" \ + | grep stateOrProvinceName | sed "s\`^.*=\ \`\`g")" + CA_localityName="$(printf "%s\n" "$CA_SUBJECT" \ + | grep localityName | sed "s\`^.*=\ \`\`g")" + CA_organizationName="$(printf "%s\n" "$CA_SUBJECT" \ + | grep organizationName | sed "s\`^.*=\ \`\`g")" + CA_organizationalUnitName="$(printf "%s\n" "$CA_SUBJECT" \ + | grep organizationalUnitName | sed "s\`^.*=\ \`\`g")" + CA_emailAddress="$(printf "%s\n" "$CA_SUBJECT" \ + | grep emailAddress | sed "s\`^.*=\ \`\`g")" + + # Match the current CA elements to the vars file settings + CA_vars_match=1 + [ "$CA_countryName" = "$KEY_COUNTRY" ] || CA_vars_match=0 + [ "$CA_stateOrProvinceName" = "$KEY_PROVINCE" ] || CA_vars_match=0 + [ "$CA_localityName" = "$KEY_CITY" ] || CA_vars_match=0 + [ "$CA_organizationName" = "$KEY_ORG" ] || CA_vars_match=0 + [ "$CA_organizationalUnitName" = "$KEY_OU" ] || CA_vars_match=0 + [ "$CA_emailAddress" = "$KEY_EMAIL" ] || CA_vars_match=0 + + if [ "$CA_vars_match" -eq 1 ] + then + CURRENT_CA_IS_VERIFIED="partially" + else + up23_fail_upgrade "CA certificate does not match vars file settings" + fi + + opts="-certopt no_pubkey,no_sigdump" + if [ ! "$EASYRSA_BATCH" ] + then + up23_show_current_ca + elif [ "$VERBOSE" ] + then + up23_show_current_ca + fi + confirm "* Confirm CA shown above is correct: " "yes" \ + "Found current CA at: $KEY_DIR/ca.crt" + CURRENT_CA_IS_VERIFIED="$in_file" +} #=> up23_verify_current_ca () + +up23_show_current_ca () +{ + printf "%s\n" "-------------------------------------------------------------------------" + # $opts is always set here + # shellcheck disable=SC2086 + easyrsa_openssl $format -in "$in_file" -noout -text\ + -nameopt multiline $opts || die "\ + OpenSSL failure to process the input CA certificate: $in_file" + printf "%s\n" "-------------------------------------------------------------------------" +} #=> up23_show_current_ca () + +up23_backup_current_pki () +{ + up23_verbose "> Backup current PKI .." + + mkdir -p "$EASYRSA_SAFE_PKI" \ + || up23_fail_upgrade "Failed to create safe PKI dir: $EASYRSA_SAFE_PKI" + + cp -r "$KEY_DIR" "$EASYRSA_SAFE_PKI" \ + || up23_fail_upgrade "Failed to copy $KEY_DIR to $EASYRSA_SAFE_PKI" + + # EASYRSA_VER2_VARSFILE is either version 2 *nix ./vars or Win vars.bat + cp "$EASYRSA_VER2_VARSFILE" "$EASYRSA_SAFE_PKI" \ + || up23_fail_upgrade "Failed to copy $EASYRSA_VER2_VARSFILE to EASYRSA_SAFE_PKI" + + up23_verbose "> OK" + up23_verbose " Current PKI backup created in: $EASYRSA_SAFE_PKI" +} #=> up23_backup_current_pki () + +up23_create_new_pki () +{ + # Dirs: renewed and revoked are created when used. + up23_verbose "> Create NEW PKI .." + up23_verbose ">> Create NEW PKI dirs .." + for i in private reqs issued certs_by_serial + do + mkdir -p "$EASYRSA_PKI/$i" \ + || up23_fail_upgrade "Failed to Create NEW PKI dir: $EASYRSA_PKI/$i" + done + up23_verbose ">> OK" + + up23_verbose ">> Copy database to NEW PKI .." + # Failure for these is not optional + # Files ignored: index.txt.old serial.old + for i in index.txt serial ca.crt index.txt.attr + do + cp "$KEY_DIR/$i" "$EASYRSA_PKI" \ + || up23_fail_upgrade "Failed to copy $KEY_DIR/$i to $EASYRSA_PKI" + done + up23_verbose ">> OK" + + up23_verbose ">> Copy current PKI to NEW PKI .." + for i in "csr.reqs" "pem.certs_by_serial" "crt.issued" "key.private" \ + "p12.private" "p8.private" "p7b.issued" + do + FILE_EXT="${i%%.*}" + DEST_DIR="${i##*.}" + if ls "$KEY_DIR/"*".$FILE_EXT" > /dev/null 2>&1; then + cp "$KEY_DIR/"*".$FILE_EXT" "$EASYRSA_PKI/$DEST_DIR" \ + || up23_fail_upgrade "Failed to copy .$FILE_EXT" + else + up23_verbose " Note: No .$FILE_EXT files found" + fi + done + up23_verbose ">> OK" + up23_verbose "> OK" + + # Todo: CRL - Or generate a new CRL on completion + up23_verbose " New PKI created in: $EASYRSA_PKI" +} #=> up23_create_new_pki () + +up23_upgrade_ca () +{ + [ -d "$EASYRSA_PKI" ] || return 0 + up23_verbose "> Confirm that index.txt.attr exists and 'unique_subject = no'" + if [ -f "$EASYRSA_PKI/index.txt.attr" ] + then + if grep -q 'unique_subject = no' "$EASYRSA_PKI/index.txt.attr" + then + # If index.txt.attr exists and "unique_suject = no" then do nothing + return 0 + fi + else + # If index.txt.attr does not exists then do nothing + return 0 + fi + + # Otherwise this is required for all easyrsa v3 + #confirm "Set 'unique_subject = no' in index.txt.attr for your current CA: " \ + #"yes" "This version of easyrsa requires that 'unique_subject = no' is set correctly" + + printf "%s\n" "unique_subject = no" > "$EASYRSA_PKI/index.txt.attr" + up23_verbose "> OK" + up23_verbose " Upgraded index.txt.attr to v306+" +} #=> up23_upgrade_index_txt_attr () + +up23_create_openssl_cnf () +{ + up23_verbose "> OpenSSL config .." + EASYRSA_PKI_SSL_CNFFILE="$EASYRSA_PKI/openssl-easyrsa.cnf" + EASYRSA_PKI_SAFE_CNFFILE="$EASYRSA_PKI/safessl-easyrsa.cnf" + cp "$EASYRSA_SSL_CNFFILE" "$EASYRSA_PKI_SSL_CNFFILE" \ + || up23_fail_upgrade "create $EASYRSA_PKI_SSL_CNFFILE" + up23_verbose "> OK" + up23_verbose " New OpenSSL config file created in: $EASYRSA_PKI_SSL_CNFFILE" + + # Create $EASYRSA_PKI/safessl-easyrsa.cnf + easyrsa_openssl makesafeconf + if [ -f "$EASYRSA_PKI_SAFE_CNFFILE" ] + then + up23_verbose " New SafeSSL config file created in: $EASYRSA_PKI_SAFE_CNFFILE" + else + up23_verbose " FAILED to create New SafeSSL config file in: $EASYRSA_PKI_SAFE_CNFFILE" + fi +} #=> up23_create_openssl_cnf () + +up23_move_easyrsa2_programs () +{ + # These files may not exist here + up23_verbose "> Move easyrsa2 programs to SAFE PKI .." + for i in build-ca build-dh build-inter build-key build-key-pass \ + build-key-pkcs12 build-key-server build-req build-req-pass \ + clean-all inherit-inter list-crl pkitool revoke-full sign-req \ + whichopensslcnf build-ca-pass build-key-server-pass init-config \ + make-crl revoke-crt openssl-0.9.6.cnf openssl-0.9.8.cnf \ + openssl-1.0.0.cnf openssl.cnf README.txt index.txt.start \ + vars.bat.sample serial.start + do + # Although unlikely, both files could exist + # EG: ./build-ca and ./build-ca.bat + NIX_FILE="$EASYRSA/$i" + WIN_FILE="$EASYRSA/$i.bat" + if [ -f "$NIX_FILE" ] + then + cp "$NIX_FILE" "$EASYRSA_SAFE_PKI" \ + || up23_fail_upgrade "copy $NIX_FILE $EASYRSA_SAFE_PKI" + fi + + if [ -f "$WIN_FILE" ] + then + cp "$WIN_FILE" "$EASYRSA_SAFE_PKI" \ + || up23_fail_upgrade "copy $WIN_FILE $EASYRSA_SAFE_PKI" + fi + + if [ ! -f "$NIX_FILE" ] && [ ! -f "$WIN_FILE" ] + then + up23_verbose "File does not exist, ignoring: $i(.bat)" + fi + + # These files are not removed on TEST run + [ "$NOSAVE" -eq 1 ] && rm -f "$NIX_FILE" "$WIN_FILE" + done + + up23_verbose "> OK" + up23_verbose " Easyrsa2 programs successfully moved to: $EASYRSA_SAFE_PKI" +} #=> up23_move_easyrsa2_programs () + +up23_build_v3_vars () +{ + up23_verbose "> Build v3 vars file .." + + EASYRSA_EXT="easyrsa-upgrade-23" + EASYRSA_VARSV2_TMP="$EASYRSA/vars-v2.tmp.$EASYRSA_EXT" + rm -f "$EASYRSA_VARSV2_TMP" + EASYRSA_VARSV3_TMP="$EASYRSA/vars-v3.tmp.$EASYRSA_EXT" + rm -f "$EASYRSA_VARSV3_TMP" + EASYRSA_VARSV3_NEW="$EASYRSA/vars-v3.new.$EASYRSA_EXT" + rm -f "$EASYRSA_VARSV3_NEW" + EASYRSA_VARSV3_WRN="$EASYRSA/vars-v3.wrn.$EASYRSA_EXT" + rm -f "$EASYRSA_VARSV3_WRN" + + printf "%s\n" "\ +########################++++++++++######################### +### ### +### WARNING: THIS FILE WAS AUTOMATICALLY GENERATED ### +### ALL SETTINGS ARE AT THE END OF THE FILE ### +### ### +########################++++++++++######################### + +" > "$EASYRSA_VARSV3_WRN" || up23_fail_upgrade "Failed to create $EASYRSA_VARSV3_WRN" + + # Create vars v3 temp file from sourced vars v2 key variables + { + printf "%s\n" "set_var EASYRSA_KEY_SIZE $KEY_SIZE" + printf "%s\n" "set_var EASYRSA_REQ_COUNTRY \"$KEY_COUNTRY\"" + printf "%s\n" "set_var EASYRSA_REQ_PROVINCE \"$KEY_PROVINCE\"" + printf "%s\n" "set_var EASYRSA_REQ_CITY \"$KEY_CITY\"" + printf "%s\n" "set_var EASYRSA_REQ_ORG \"$KEY_ORG\"" + printf "%s\n" "set_var EASYRSA_REQ_EMAIL \"$KEY_EMAIL\"" + printf "%s\n" "set_var EASYRSA_REQ_OU \"$KEY_OU\"" + printf "%s\n" 'set_var EASYRSA_NS_SUPPORT "yes"' + printf "%s\n" 'set_var EASYRSA_DN "org"' + printf "%s\n" 'set_var EASYRSA_RAND_SN "no"' + printf "%s\n" "" + } > "$EASYRSA_VARSV3_TMP" \ + || up23_fail_upgrade "Failed to create $EASYRSA_VARSV3_TMP" + + # cat temp files into new v3 vars + cat "$EASYRSA_VARSV3_WRN" "$EASYRSA_VARSV3_EXMP" "$EASYRSA_VARSV3_TMP" \ + > "$EASYRSA_VARSV3_NEW" \ + || up23_fail_upgrade "Failed to create $EASYRSA_VARSV3_NEW" + + # This file must be created and restored at the end of TEST + # for the REAL update to to succeed + EASYRSA_VARS_LIVEBKP="$EASYRSA_TARGET_VARSFILE.livebackup" + cp "$EASYRSA_VER2_VARSFILE" "$EASYRSA_VARS_LIVEBKP" \ + || up23_fail_upgrade "Failed to create $EASYRSA_VARS_LIVEBKP" + rm -f "$EASYRSA_VER2_VARSFILE" + + # "$EASYRSA_TARGET_VARSFILE" is always $EASYRSA/vars + cp "$EASYRSA_VARSV3_NEW" "$EASYRSA_TARGET_VARSFILE" \ + || up23_fail_upgrade "copy $EASYRSA_VARSV3_NEW to $EASYRSA_TARGET_VARSFILE" + + # Delete temp files + rm -f "$EASYRSA_VARSV2_TMP" "$EASYRSA_VARSV3_TMP" \ + "$EASYRSA_VARSV3_NEW" "$EASYRSA_VARSV3_WRN" + + up23_verbose "> OK" + up23_verbose " New v3 vars file created in: $EASYRSA_TARGET_VARSFILE" +} #=> up23_build_v3_vars () + +up23_do_upgrade_23 () +{ + up23_verbose "============================================================================" + up23_verbose "Begin ** $1 ** upgrade process .." + up23_verbose "" + up23_verbose "Easyrsa upgrade version: $EASYRSA_UPGRADE_23" + up23_verbose "" + + up23_verify_new_pki + up23_verify_current_pki + up23_verify_current_ca + up23_backup_current_pki + up23_create_new_pki + up23_upgrade_ca + up23_move_easyrsa2_programs + up23_build_v3_vars + up23_create_openssl_cnf + + if [ "$NOSAVE" -eq 0 ] + then + # Must stay in this order + # New created dirs: EASYRSA_NEW_PKI and EASYRSA_SAFE_PKI + rm -rf "$EASYRSA_NEW_PKI" + rm -rf "$EASYRSA_SAFE_PKI" + # EASYRSA_TARGET_VARSFILE is always the new created v3 vars + # Need to know if this fails + rm "$EASYRSA_TARGET_VARSFILE" \ + || up23_fail_upgrade "remove new vars file: $EASYRSA_TARGET_VARSFILE" + # EASYRSA_VER2_VARSFILE is either v2 *nix ./vars or Win vars.bat + # Need this dance because v2 vars is same name as v3 vars above + cp "$EASYRSA_VARS_LIVEBKP" "$EASYRSA_VER2_VARSFILE" + fi + rm -f "$EASYRSA_VARS_LIVEBKP" +} #= up23_do_upgrade_23 () + +up23_manage_upgrade_23 () +{ + EASYRSA_UPGRADE_VERSION="v1.0a (2020/01/08)" + EASYRSA_UPGRADE_TYPE="$1" + EASYRSA_FOUND_VARS=0 + + # Verify all existing versions of vars/vars.bat + if [ -f "$vars" ] + then + if grep -q 'Complain if a user tries to do this:' "$vars" + then + EASYRSA_FOUND_VARS=1 + EASYRSA_VARS_IS_VER3=1 + fi + + # Easyrsa v3 does not use NOR allow use of `export`. + if grep -q 'export' "$vars" + then + EASYRSA_FOUND_VARS=1 + EASYRSA_VARS_IS_VER2=1 + EASYRSA_VER2_VARSFILE="$vars" + EASYRSA_TARGET_VARSFILE="$vars" + fi + fi + + if [ -f "$EASYRSA/vars.bat" ] + then + EASYRSA_FOUND_VARS=1 + EASYRSA_VARS_IS_WIN2=1 + EASYRSA_VER2_VARSFILE="$EASYRSA/vars.bat" + EASYRSA_TARGET_VARSFILE="$EASYRSA/vars" + fi + + if [ $EASYRSA_FOUND_VARS -ne 1 ]; + then + die echo "vars file not found" + fi + + # Only allow specific vars/vars.bat to exist + if [ "$EASYRSA_VARS_IS_VER3" ] && [ "$EASYRSA_VARS_IS_VER2" ] + then + die "Verify your current vars file, v3 cannot use 'export'." + fi + + if [ "$EASYRSA_VARS_IS_VER3" ] && [ "$EASYRSA_VARS_IS_WIN2" ] + then + die "Verify your current vars/vars.bat file, cannot have both." + fi + + if [ "$EASYRSA_VARS_IS_VER2" ] && [ "$EASYRSA_VARS_IS_WIN2" ] + then + die "Verify your current vars/vars.bat file, cannot have both." + fi + + # Die on invalid upgrade type or environment + if [ "$EASYRSA_UPGRADE_TYPE" = "ca" ] + then + if [ "$EASYRSA_VARS_IS_VER3" ] + then + # v3 ensure index.txt.attr "unique_subject = no" + up23_upgrade_ca + unset EASYRSA_BATCH + notice "Your CA is fully up to date." + return 0 + else + die "Only v3 PKI CA can be upgraded." + fi + fi + + if [ "$EASYRSA_UPGRADE_TYPE" = "pki" ] + then + if [ "$EASYRSA_VARS_IS_VER3" ] + then + unset EASYRSA_BATCH + notice "Your PKI is fully up to date." + return 0 + fi + else + die "upgrade type must be 'pki' or 'ca'." + fi + + # PKI is potentially suitable for upgrade + + warn " +========================================================================= + + * WARNING * + +Found settings from EasyRSA-v2 which are not compatible with EasyRSA-v3. +Before you can continue, EasyRSA must upgrade your settings and PKI. +* Found EASYRSA and vars file: + $EASYRSA + $EASYRSA_VER2_VARSFILE : + +Further info: +* https://community.openvpn.net/openvpn/wiki/easyrsa-upgrade + +Easyrsa upgrade version: $EASYRSA_UPGRADE_VERSION +========================================================================= +" + +# Test upgrade + + NOSAVE=0 + + confirm "* EasyRSA **TEST** upgrade (Changes will NOT be written): " "yes" " +This upgrade will TEST that the upgrade works BEFORE making any changes." + + up23_do_upgrade_23 "TEST" + + notice " +========================================================================= + + * NOTICE * + +EasyRSA upgrade **TEST** has successfully completed. +" +# Upgrade for REAL + + NOSAVE=1 + + confirm "* EasyRSA **REAL** upgrade (Changes WILL be written): " "yes" " +========================================================================= + + * WARNING * + +Run REAL upgrade: Answer yes (Once completed you will have a version 3 PKI) +Terminate upgrade: Answer no (No changes have been made to your current PKI) +" + + confirm "* Confirm **REAL** upgrade (Changes will be written): " "yes" " +========================================================================= + + * SECOND WARNING * + +This upgrade will permanently write changes to your PKI ! +(With full backup backout) +" + up23_do_upgrade_23 "REAL" + + notice " +========================================================================= + + * NOTICE * + +Your settings and PKI have been successfully upgraded to EasyRSA version3 + +A backup of your current PKI is here: + $EASYRSA_SAFE_PKI + + * IMPORTANT NOTICE * + +1. YOU MUST VERIFY THAT YOUR NEW ./vars FILE IS SETUP CORRECTLY +2. IF YOU ARE USING WINDOWS YOU MUST ENSURE THAT openssl IS CORRECTLY DEFINED + IN ./vars (example follows) + + # + # This sample is in Windows syntax -- edit it for your path if not using PATH: + # set_var EASYRSA_OPENSSL \"C:/Program Files/OpenSSL-Win32/bin/openssl.exe\" + # + # Alternate location (Note: Forward slash '/' is correct for Windpws): + # set_var EASYRSA_OPENSSL \"C:/Program Files/Openvpn/bin/openssl.exe\" + # + +3. Finally, you can verify that easyrsa works by using these two commands: + ./easyrsa show-ca (Verify that your CA is intact and correct) + ./easyrsa gen-crl ((re)-generate a CRL file) + +Further info: +* https://community.openvpn.net/openvpn/wiki/easyrsa-upgrade" + up23_verbose " + * UPGRADE COMPLETED SUCCESSFULLY * +" + +return 0 + +} # => up23_manage_upgrade_23 () + +print_version() +{ + cat < print_version () + + +######################################## +# Invocation entry point: + +NL=' +' + +# Be secure with a restrictive umask +[ -z "$EASYRSA_NO_UMASK" ] && umask 077 + +# Parse options +while :; do + # Separate option from value: + opt="${1%%=*}" + val="${1#*=}" + empty_ok="" # Empty values are not allowed unless excepted + + case "$opt" in + --days) + export EASYRSA_CERT_EXPIRE="$val" + export EASYRSA_CA_EXPIRE="$val" + export EASYRSA_CRL_DAYS="$val" + ;; + --pki-dir) + export EASYRSA_PKI="$val" ;; + --use-algo) + export EASYRSA_ALGO="$val" ;; + --keysize) + export EASYRSA_KEY_SIZE="$val" ;; + --curve) + export EASYRSA_CURVE="$val" ;; + --dn-mode) + export EASYRSA_DN="$val" ;; + --req-cn) + export EASYRSA_REQ_CN="$val" ;; + --digest) + export EASYRSA_DIGEST="$val" ;; + --req-c) + empty_ok=1 + export EASYRSA_REQ_COUNTRY="$val" ;; + --req-st) + empty_ok=1 + export EASYRSA_REQ_PROVINCE="$val" ;; + --req-city) + empty_ok=1 + export EASYRSA_REQ_CITY="$val" ;; + --req-org) + empty_ok=1 + export EASYRSA_REQ_ORG="$val" ;; + --req-email) + empty_ok=1 + export EASYRSA_REQ_EMAIL="$val" ;; + --req-ou) + empty_ok=1 + export EASYRSA_REQ_OU="$val" ;; + --ns-cert) + export EASYRSA_NS_SUPPORT="$val" ;; + --ns-comment) + empty_ok=1 + export EASYRSA_NS_COMMENT="$val" ;; + --batch) + empty_ok=1 + export EASYRSA_BATCH=1 ;; + --passin) + export EASYRSA_PASSIN="$val";; + --passout) + export EASYRSA_PASSOUT="$val";; + --subca-len) + export EASYRSA_SUBCA_LEN="$val" ;; + --vars) + export EASYRSA_VARS_FILE="$val" ;; + --copy-ext) + empty_ok=1 + export EASYRSA_CP_EXT=1 ;; + --subject-alt-name) + export EASYRSA_EXTRA_EXTS="\ +$EASYRSA_EXTRA_EXTS +subjectAltName = $val" ;; + --version) + print_version + ;; + *) + break ;; + esac + + # fatal error when no value was provided + if [ ! $empty_ok ] && { [ "$val" = "$1" ] || [ -z "$val" ]; }; then + die "Missing value to option: $opt" + fi + + shift +done + +# Intelligent env-var detection and auto-loading: +vars_setup + +# Register cleanup on EXIT +trap "cleanup" EXIT +# When SIGHUP, SIGINT, SIGQUIT, SIGABRT and SIGTERM, +# explicitly exit to signal EXIT (non-bash shells) +trap "exit 1" 1 +trap "exit 2" 2 +trap "exit 3" 3 +trap "exit 6" 6 +trap "exit 14" 15 + +# Upgrade: EasyRSA v2.x to EasyRSA v3.x +# Upgrade: EasyRSA < v3.0.6 to v3.0.6+ +#up23_manage_upgrade_23 + +# determine how we were called, then hand off to the function responsible +cmd="$1" +[ -n "$1" ] && shift # scrape off command +case "$cmd" in + init-pki|clean-all) + init_pki "$@" + ;; + build-ca) + build_ca "$@" + ;; + gen-dh) + gen_dh + ;; + gen-req) + gen_req "$@" + ;; + sign|sign-req) + sign_req "$@" + ;; + build-client-full) + build_full client "$@" + ;; + build-server-full) + build_full server "$@" + ;; + build-serverClient-full) + build_full serverClient "$@" + ;; + gen-crl) + gen_crl + ;; + revoke) + revoke "$@" + ;; + renew) + renew "$@" + ;; + import-req) + import_req "$@" + ;; + export-p12) + export_pkcs p12 "$@" + ;; + export-p7) + export_pkcs p7 "$@" + ;; + export-p8) + export_pkcs p8 "$@" + ;; + set-rsa-pass) + set_pass rsa "$@" + ;; + set-ec-pass) + set_pass ec "$@" + ;; + update-db) + update_db + ;; + show-req) + show req "$@" + ;; + show-cert) + show cert "$@" + ;; + show-ca) + show_ca "$@" + ;; + upgrade) + up23_manage_upgrade_23 "$@" + ;; + ""|help|-h|--help|--usage) + cmd_help "$1" + exit 0 + ;; + version) + print_version + ;; + *) + die "Unknown command '$cmd'. Run without commands for usage help." + ;; +esac + +# vim: ft=sh nu ai sw=8 ts=8 noet diff --git a/OpenVPN/CA Server/easy-rsa/openssl-easyrsa.cnf b/OpenVPN/CA Server/easy-rsa/openssl-easyrsa.cnf new file mode 100644 index 0000000..5c4fc79 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/openssl-easyrsa.cnf @@ -0,0 +1,138 @@ +# For use with Easy-RSA 3.0+ and OpenSSL or LibreSSL + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = $ENV::EASYRSA_PKI # Where everything is kept +certs = $dir # Where the issued certs are kept +crl_dir = $dir # Where the issued crl are kept +database = $dir/index.txt # database index file. +new_certs_dir = $dir/certs_by_serial # default place for new certs. + +certificate = $dir/ca.crt # The CA certificate +serial = $dir/serial # The current serial number +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/ca.key # The private key +RANDFILE = $dir/.rand # private random number file + +x509_extensions = basic_exts # The extensions to add to the cert + +# This allows a V2 CRL. Ancient browsers don't like it, but anything Easy-RSA +# is designed for will. In return, we get the Issuer attached to CRLs. +crl_extensions = crl_ext + +default_days = $ENV::EASYRSA_CERT_EXPIRE # how long to certify for +default_crl_days= $ENV::EASYRSA_CRL_DAYS # how long before next CRL +default_md = $ENV::EASYRSA_DIGEST # use public key default MD +preserve = no # keep passed DN ordering + +# This allows to renew certificates which have not been revoked +unique_subject = no + +# A few different ways of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_anything + +# For the 'anything' policy, which defines allowed DN fields +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +name = optional +emailAddress = optional + +#################################################################### +# Easy-RSA request handling +# We key off $DN_MODE to determine how to format the DN +[ req ] +default_bits = $ENV::EASYRSA_KEY_SIZE +default_keyfile = privkey.pem +default_md = $ENV::EASYRSA_DIGEST +distinguished_name = $ENV::EASYRSA_DN +x509_extensions = easyrsa_ca # The extensions to add to the self signed cert + +# A placeholder to handle the $EXTRA_EXTS feature: +#%EXTRA_EXTS% # Do NOT remove or change this line as $EXTRA_EXTS support requires it + +#################################################################### +# Easy-RSA DN (Subject) handling + +# Easy-RSA DN for cn_only support: +[ cn_only ] +commonName = Common Name (eg: your user, host, or server name) +commonName_max = 64 +commonName_default = $ENV::EASYRSA_REQ_CN + +# Easy-RSA DN for org support: +[ org ] +countryName = Country Name (2 letter code) +countryName_default = $ENV::EASYRSA_REQ_COUNTRY +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = $ENV::EASYRSA_REQ_PROVINCE + +localityName = Locality Name (eg, city) +localityName_default = $ENV::EASYRSA_REQ_CITY + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = $ENV::EASYRSA_REQ_ORG + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = $ENV::EASYRSA_REQ_OU + +commonName = Common Name (eg: your user, host, or server name) +commonName_max = 64 +commonName_default = $ENV::EASYRSA_REQ_CN + +emailAddress = Email Address +emailAddress_default = $ENV::EASYRSA_REQ_EMAIL +emailAddress_max = 64 + +#################################################################### +# Easy-RSA cert extension handling + +# This section is effectively unused as the main script sets extensions +# dynamically. This core section is left to support the odd usecase where +# a user calls openssl directly. +[ basic_exts ] +basicConstraints = CA:FALSE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always + +# The Easy-RSA CA extensions +[ easyrsa_ca ] + +# PKIX recommendations: + +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always + +# This could be marked critical, but it's nice to support reading by any +# broken clients who attempt to do so. +basicConstraints = CA:true + +# Limit key usage to CA tasks. If you really want to use the generated pair as +# a self-signed cert, comment this out. +keyUsage = cRLSign, keyCertSign + +# nsCertType omitted by default. Let's try to let the deprecated stuff die. +# nsCertType = sslCA + +# CRL extensions. +[ crl_ext ] + +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always,issuer:always + diff --git a/OpenVPN/CA Server/easy-rsa/pki/ca.crt b/OpenVPN/CA Server/easy-rsa/pki/ca.crt new file mode 100644 index 0000000..40b2499 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/ca.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRTCCAi2gAwIBAgIUXe37kz2yqgyL2xXfvaGRzlz7ywYwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJSkZfc2VydmVyMB4XDTIzMDIyMDIyMDkyMVoXDTMzMDIx +NzIyMDkyMVowFDESMBAGA1UEAwwJSkZfc2VydmVyMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAnLdVAj0W31TtWGxwdBeqsdIHyUdVAEG8bX+CcNZDP3M3 +R/gJOmenjqsqHYBe5gZcky1hkqWaD7l/LNmyzZDZ1lVEWpcAZqxbsUZKiHU30bxq +84L5qtaAOpwTsumidq2hBqoDBMdBmh18e0QEW624mui7ckXTRRG3PA0ccXtXcTYU +ntmhYtQ2oaPauSmfJZIUfZTfVZbB8FkCgu+zJtCx5hq46vIHm8KX0m1zLIeUtGsI +hkly+5v52f3sEMlddyoZZkfjRddETk2co09q3oNaP1LYxN5G+TvZDhpdE+PrDsNT +wO4uU2d9hVIP3T49heLieZ6KVxyp1FsDYzo0CNlIDwIDAQABo4GOMIGLMB0GA1Ud +DgQWBBSKeJDl8FDnjHXkuMCh6OmbshqdMjBPBgNVHSMESDBGgBSKeJDl8FDnjHXk +uMCh6OmbshqdMqEYpBYwFDESMBAGA1UEAwwJSkZfc2VydmVyghRd7fuTPbKqDIvb +Fd+9oZHOXPvLBjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B +AQsFAAOCAQEARIg2x4Tit/6ZydMlle6ku32t75OMCVQoe7fUkRjNe8pCkZjZXLy9 +QIRwoqW3FRT8+mQjctZk3NsyLStF8Rc/fFvpjGY/hiEQ/RV1K2/IZ9hcswp/LRzQ +ElDwXhe4zlcDT10GjHYYx221SR+ijgicZcaXgb9f3uZKIrPgyb8qB4KCQS8gPtCV +1VmPM5/svVCI93G+xT92XBHa47fgV5GEn7Snah2UgFol5h7/KX/Sa2q0pfBlzqmt +CutfEbYcwSxkoLsEUIW8KMoEAIsO+KIsraS6EXlRdT82Ui+UZWVPZABlzifCl+AV +LzBrLwt2OeoEI1h65EyzzE7gDsjrE3JR/Q== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/227AB3CB8805008CDFAF02BEAF63F959.pem b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/227AB3CB8805008CDFAF02BEAF63F959.pem new file mode 100644 index 0000000..7c6e620 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/227AB3CB8805008CDFAF02BEAF63F959.pem @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 22:7a:b3:cb:88:05:00:8c:df:af:02:be:af:63:f9:59 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Feb 20 22:37:46 2023 GMT + Not After : May 25 22:37:46 2025 GMT + Subject: CN=jf + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:8d:38:ea:4f:29:bd:83:a9:33:a3:1c:33:8a:60: + 8f:fa:19:81:00:73:44:81:98:1e:76:05:ee:f6:46: + d5:25:a8:c5:3b:bd:d6:fa:cf:c6:79:e0:b4:42:27: + 80:e2:96:2d:30:50:c2:f6:9c:2c:13:f8:b9:46:b3: + 0d:96:6c:9b:d2:45:15:a3:f0:4c:bc:6b:51:45:f8: + cb:59:04:b1:d0:47:b9:90:06:71:c7:eb:34:32:e2: + 72:14:84:94:58:e3:34 + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + C5:CE:72:8F:A3:8E:13:57:DD:0E:02:A1:24:F1:56:C3:AE:2F:65:8F + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 3b:e8:1a:3e:ac:17:17:49:7c:4d:73:55:39:e9:1b:e4:d6:7f: + 6d:6d:43:6c:e2:79:41:f4:26:a4:2d:18:59:24:a0:b1:e0:db: + 03:07:f9:fb:24:f6:be:ed:8c:31:3e:c7:bb:74:b6:87:ba:43: + fc:d6:fb:2f:9f:1c:eb:d1:27:ad:60:eb:ab:87:c7:46:fe:22: + 75:c1:bb:fb:23:ad:ba:1d:ab:41:45:29:d6:c4:89:99:94:40: + 06:c7:3a:08:fe:d3:b5:f4:e7:52:57:aa:d1:a8:ec:74:e6:c9: + ec:9e:80:e0:ba:92:92:95:55:2e:d7:b2:d8:09:ee:72:fd:12: + ac:0a:0d:dc:ba:ac:4e:34:8c:37:19:76:60:7c:bd:ba:99:b7: + e5:47:c3:4b:67:2f:a9:5c:89:95:70:2d:2c:97:45:04:64:15: + 47:04:d1:48:7d:d8:40:63:6c:05:8b:dc:ed:0f:a3:ae:3a:e8: + 6f:49:34:54:de:99:4b:aa:28:6d:c9:3d:db:43:60:14:40:d5: + 09:87:a8:b2:88:11:4c:8c:00:71:b1:38:25:91:5f:2f:93:7b: + 42:64:38:db:d2:59:48:e8:ed:2e:92:69:4e:d4:2a:3b:e3:03: + 94:2c:fc:ac:bc:ff:a9:b4:1e:ca:d3:d2:b5:fd:bf:33:bd:55: + 12:75:db:f1 +-----BEGIN CERTIFICATE----- +MIICnjCCAYagAwIBAgIQInqzy4gFAIzfrwK+r2P5WTANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjMwMjIwMjIzNzQ2WhcNMjUwNTI1MjIz +NzQ2WjANMQswCQYDVQQDDAJqZjB2MBAGByqGSM49AgEGBSuBBAAiA2IABI046k8p +vYOpM6McM4pgj/oZgQBzRIGYHnYF7vZG1SWoxTu91vrPxnngtEIngOKWLTBQwvac +LBP4uUazDZZsm9JFFaPwTLxrUUX4y1kEsdBHuZAGccfrNDLichSElFjjNKOBoDCB +nTAJBgNVHRMEAjAAMB0GA1UdDgQWBBTFznKPo44TV90OAqEk8VbDri9ljzBPBgNV +HSMESDBGgBSKeJDl8FDnjHXkuMCh6OmbshqdMqEYpBYwFDESMBAGA1UEAwwJSkZf +c2VydmVyghRd7fuTPbKqDIvbFd+9oZHOXPvLBjATBgNVHSUEDDAKBggrBgEFBQcD +AjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBADvoGj6sFxdJfE1zVTnp +G+TWf21tQ2zieUH0JqQtGFkkoLHg2wMH+fsk9r7tjDE+x7t0toe6Q/zW+y+fHOvR +J61g66uHx0b+InXBu/sjrbodq0FFKdbEiZmUQAbHOgj+07X051JXqtGo7HTmyeye +gOC6kpKVVS7XstgJ7nL9EqwKDdy6rE40jDcZdmB8vbqZt+VHw0tnL6lciZVwLSyX +RQRkFUcE0Uh92EBjbAWL3O0Po6466G9JNFTemUuqKG3JPdtDYBRA1QmHqLKIEUyM +AHGxOCWRXy+Te0JkONvSWUjo7S6SaU7UKjvjA5Qs/Ky8/6m0HsrT0rX9vzO9VRJ1 +2/E= +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/2A951944ADF0A2C8E81A4C541C1899E5.pem b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/2A951944ADF0A2C8E81A4C541C1899E5.pem new file mode 100644 index 0000000..838ccfa --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/2A951944ADF0A2C8E81A4C541C1899E5.pem @@ -0,0 +1,73 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 2a:95:19:44:ad:f0:a2:c8:e8:1a:4c:54:1c:18:99:e5 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Mar 17 18:35:11 2023 GMT + Not After : Jun 19 18:35:11 2025 GMT + Subject: CN=pascal + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:bd:c5:d0:8f:66:db:14:de:04:ca:5c:46:2b:39: + 24:d2:17:c2:43:cc:c5:b1:37:e9:b8:3f:bb:25:ef: + be:9e:1c:bc:a7:60:e0:15:f7:87:10:97:90:79:c6: + 4b:fa:46:16:9f:d7:6a:0a:96:d0:73:04:ef:f1:f4: + b6:14:2a:d4:d1:14:27:48:fa:74:89:92:4d:5b:87: + f7:3b:ce:ee:00:f5:be:15:8f:4d:de:65:b0:fb:70: + e2:27:c4:d6:7c:ed:5d + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 4D:A1:0A:C4:75:0C:FF:5A:3F:0A:0B:49:A7:19:48:B2:61:54:F0:CB + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Key Usage: + Digital Signature, Key Encipherment + X509v3 Subject Alternative Name: + DNS:pascal + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 57:3b:5a:bb:47:77:8f:dd:fd:9c:6d:68:ad:12:29:c0:7b:66: + 2e:56:cc:13:64:5b:8f:e8:98:71:43:ab:76:0c:46:d1:a7:af: + b5:3a:c8:81:03:57:7e:cb:05:12:05:fb:e6:e2:4b:9c:09:93: + e7:1f:5d:35:b6:5d:e4:cd:58:ca:47:f4:10:9e:3e:64:22:14: + b5:49:d5:be:5b:7b:ed:3e:f2:a4:f9:13:65:58:69:5d:ec:3b: + f2:f6:c5:5e:8c:80:42:82:95:0e:5c:32:52:7b:80:c8:8d:8b: + fe:73:7e:15:f8:28:7c:81:d7:5f:85:61:ea:de:50:d4:ba:12: + 8e:88:93:dc:5d:d2:c7:41:15:f8:f4:50:64:b4:56:2d:01:b8: + ee:ad:8f:7e:71:80:c7:97:fd:57:a5:c7:33:3a:8a:b0:bf:fb: + 3c:36:d0:3b:92:03:e7:78:20:04:4a:f1:a9:82:63:8d:33:13: + 1f:ba:cd:56:99:79:c5:5d:53:f9:c9:36:7b:26:ff:4f:cd:58: + 39:35:02:b4:68:59:c3:a2:44:98:e3:47:44:92:9d:51:1e:60: + 9a:84:2d:dc:f3:ad:7e:fa:ac:31:bf:8b:02:cf:cf:f7:f8:f8: + 77:6d:ac:4d:8f:5c:91:8c:b6:77:4b:86:80:6d:ce:f1:10:22: + 50:af:47:93 +-----BEGIN CERTIFICATE----- +MIICtTCCAZ2gAwIBAgIQKpUZRK3wosjoGkxUHBiZ5TANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjMwMzE3MTgzNTExWhcNMjUwNjE5MTgz +NTExWjARMQ8wDQYDVQQDDAZwYXNjYWwwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAS9 +xdCPZtsU3gTKXEYrOSTSF8JDzMWxN+m4P7sl776eHLynYOAV94cQl5B5xkv6Rhaf +12oKltBzBO/x9LYUKtTRFCdI+nSJkk1bh/c7zu4A9b4Vj03eZbD7cOInxNZ87V2j +gbMwgbAwCQYDVR0TBAIwADAdBgNVHQ4EFgQUTaEKxHUM/1o/CgtJpxlIsmFU8Msw +TwYDVR0jBEgwRoAUiniQ5fBQ54x15LjAoejpm7IanTKhGKQWMBQxEjAQBgNVBAMM +CUpGX3NlcnZlcoIUXe37kz2yqgyL2xXfvaGRzlz7ywYwEwYDVR0lBAwwCgYIKwYB +BQUHAwEwCwYDVR0PBAQDAgWgMBEGA1UdEQQKMAiCBnBhc2NhbDANBgkqhkiG9w0B +AQsFAAOCAQEAVztau0d3j939nG1orRIpwHtmLlbME2Rbj+iYcUOrdgxG0aevtTrI +gQNXfssFEgX75uJLnAmT5x9dNbZd5M1Yykf0EJ4+ZCIUtUnVvlt77T7ypPkTZVhp +Xew78vbFXoyAQoKVDlwyUnuAyI2L/nN+FfgofIHXX4Vh6t5Q1LoSjoiT3F3Sx0EV ++PRQZLRWLQG47q2PfnGAx5f9V6XHMzqKsL/7PDbQO5ID53ggBErxqYJjjTMTH7rN +Vpl5xV1T+ck2eyb/T81YOTUCtGhZw6JEmONHRJKdUR5gmoQt3POtfvqsMb+LAs/P +9/j4d22sTY9ckYy2d0uGgG3O8RAiUK9Hkw== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/3509162241A87805B57226316EC39402.pem b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/3509162241A87805B57226316EC39402.pem new file mode 100644 index 0000000..76e8338 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/3509162241A87805B57226316EC39402.pem @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 35:09:16:22:41:a8:78:05:b5:72:26:31:6e:c3:94:02 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Jul 3 19:11:30 2023 GMT + Not After : Oct 5 19:11:30 2025 GMT + Subject: CN=edgerouterchambly + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:0e:fd:1c:60:83:5f:a7:64:79:a0:35:74:df:c0: + 63:68:c5:3c:b1:02:95:a9:73:58:a9:a3:74:cc:d8: + 5b:d8:7a:ab:aa:d3:1f:41:2d:68:86:bd:2f:e3:6c: + 73:b5:e8:01:73:b4:12:f4:71:dd:dd:cb:9b:4e:b0: + f1:d4:04:00:d1:60:cf:fe:ea:3c:a5:f2:ae:ee:aa: + 45:a3:21:71:e5:d2:b7:f0:22:30:c4:d4:27:58:79: + 96:6c:f0:5c:ba:96:19 + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + C1:2A:D4:21:E9:F3:08:CB:87:23:CC:2D:52:A3:DF:8F:BB:CF:BB:5A + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 2e:c6:3c:76:fd:64:a8:ab:c7:02:86:e8:80:d5:a6:8b:2f:ed: + be:70:cd:96:23:a5:86:1f:19:0c:72:7b:0b:ec:d2:58:ad:39: + 1d:ee:63:52:55:a3:f2:47:87:12:56:ad:cd:a1:ed:0d:ed:27: + 55:4c:9b:47:cf:e8:d7:a2:70:d7:8a:d2:60:7e:57:b4:02:0d: + 96:46:57:9d:f9:05:cf:f1:91:5c:1e:e2:a7:79:e1:5b:fe:46: + 7a:1b:ab:bb:c0:0a:a5:70:68:83:88:1a:62:8a:36:4c:98:9c: + 85:31:40:6b:ad:a7:11:d3:a3:cb:d9:8a:f3:e8:d4:2c:bd:8a: + 66:57:ca:bb:ad:d9:b1:cf:6a:83:88:e3:5e:a4:2e:5b:7e:50: + 26:16:5c:34:cd:6c:9b:35:d9:61:ef:63:87:7c:2a:2d:f0:dd: + ce:ab:9d:7e:14:46:98:d9:cb:9a:68:91:fb:a3:59:85:91:d5: + 4f:0c:ee:e3:47:df:7c:93:f8:05:ec:0a:d1:84:dc:21:0f:8e: + 6d:b5:14:e8:a3:bd:ea:21:1c:d1:5a:95:36:95:98:20:f0:0e: + 07:54:56:27:d9:6d:cc:c6:09:f1:98:1c:69:d7:1b:52:0c:54: + 38:32:fe:c6:50:07:74:ef:8c:05:03:bf:55:e0:c7:3b:e5:20: + f2:84:3e:9f +-----BEGIN CERTIFICATE----- +MIICrTCCAZWgAwIBAgIQNQkWIkGoeAW1ciYxbsOUAjANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjMwNzAzMTkxMTMwWhcNMjUxMDA1MTkx +MTMwWjAcMRowGAYDVQQDDBFlZGdlcm91dGVyY2hhbWJseTB2MBAGByqGSM49AgEG +BSuBBAAiA2IABA79HGCDX6dkeaA1dN/AY2jFPLEClalzWKmjdMzYW9h6q6rTH0Et +aIa9L+Nsc7XoAXO0EvRx3d3Lm06w8dQEANFgz/7qPKXyru6qRaMhceXSt/AiMMTU +J1h5lmzwXLqWGaOBoDCBnTAJBgNVHRMEAjAAMB0GA1UdDgQWBBTBKtQh6fMIy4cj +zC1So9+Pu8+7WjBPBgNVHSMESDBGgBSKeJDl8FDnjHXkuMCh6OmbshqdMqEYpBYw +FDESMBAGA1UEAwwJSkZfc2VydmVyghRd7fuTPbKqDIvbFd+9oZHOXPvLBjATBgNV +HSUEDDAKBggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEB +AC7GPHb9ZKirxwKG6IDVposv7b5wzZYjpYYfGQxyewvs0litOR3uY1JVo/JHhxJW +rc2h7Q3tJ1VMm0fP6NeicNeK0mB+V7QCDZZGV535Bc/xkVwe4qd54Vv+Rnobq7vA +CqVwaIOIGmKKNkyYnIUxQGutpxHTo8vZivPo1Cy9imZXyrut2bHPaoOI416kLlt+ +UCYWXDTNbJs12WHvY4d8Ki3w3c6rnX4URpjZy5pokfujWYWR1U8M7uNH33yT+AXs +CtGE3CEPjm21FOijveohHNFalTaVmCDwDgdUVifZbczGCfGYHGnXG1IMVDgy/sZQ +B3TvjAUDv1XgxzvlIPKEPp8= +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/35F253A0DF2EA1227A3926855218BBD5.pem b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/35F253A0DF2EA1227A3926855218BBD5.pem new file mode 100644 index 0000000..f93142c --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/35F253A0DF2EA1227A3926855218BBD5.pem @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 35:f2:53:a0:df:2e:a1:22:7a:39:26:85:52:18:bb:d5 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Mar 17 19:08:30 2023 GMT + Not After : Jun 19 19:08:30 2025 GMT + Subject: CN=pascal + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:bd:c5:d0:8f:66:db:14:de:04:ca:5c:46:2b:39: + 24:d2:17:c2:43:cc:c5:b1:37:e9:b8:3f:bb:25:ef: + be:9e:1c:bc:a7:60:e0:15:f7:87:10:97:90:79:c6: + 4b:fa:46:16:9f:d7:6a:0a:96:d0:73:04:ef:f1:f4: + b6:14:2a:d4:d1:14:27:48:fa:74:89:92:4d:5b:87: + f7:3b:ce:ee:00:f5:be:15:8f:4d:de:65:b0:fb:70: + e2:27:c4:d6:7c:ed:5d + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 4D:A1:0A:C4:75:0C:FF:5A:3F:0A:0B:49:A7:19:48:B2:61:54:F0:CB + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 90:1a:f6:1b:27:2f:bb:fb:e7:69:da:e2:9d:3d:1b:59:67:a0: + 77:8d:a3:79:cd:1b:e9:6a:f1:22:17:a9:58:58:3f:b9:b6:66: + 1d:43:d7:b7:2a:35:1d:ae:6b:f8:8e:a0:04:06:08:cf:f2:2f: + d8:cd:9f:dd:8c:8c:5e:dd:46:ee:19:95:a7:4e:f2:81:d7:b1: + b6:92:51:43:2e:6a:0b:b9:55:8b:9e:90:08:3f:2f:bc:7f:ff: + 2d:a1:09:92:95:dd:ef:40:14:84:51:f4:a5:9b:7f:85:fc:bf: + 7d:d3:a4:14:2c:94:72:6e:17:6d:79:9c:52:67:4b:fb:86:55: + 02:fe:43:4c:77:4d:68:e0:84:d5:4b:64:c7:e8:30:fd:51:3d: + 1f:0d:ad:a3:f1:bc:bb:fb:11:aa:5b:2d:18:61:9a:f8:9b:35: + d9:5e:a2:45:5c:a7:d6:79:0d:1c:3a:ad:b9:eb:cb:46:f4:b9: + 2b:cf:41:da:15:d0:bf:49:a7:cc:c1:7d:f6:68:0a:60:76:54: + 2b:d3:df:1c:88:77:7e:fb:19:86:d1:f4:a3:e7:3d:f6:17:8d: + 84:27:aa:63:04:26:de:26:13:c3:9f:ce:61:6c:ee:6c:ff:76: + fb:8d:bf:e8:1d:34:1a:c4:29:f6:5f:b1:5d:46:24:40:1e:68: + c7:8f:18:49 +-----BEGIN CERTIFICATE----- +MIICojCCAYqgAwIBAgIQNfJToN8uoSJ6OSaFUhi71TANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjMwMzE3MTkwODMwWhcNMjUwNjE5MTkw +ODMwWjARMQ8wDQYDVQQDDAZwYXNjYWwwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAS9 +xdCPZtsU3gTKXEYrOSTSF8JDzMWxN+m4P7sl776eHLynYOAV94cQl5B5xkv6Rhaf +12oKltBzBO/x9LYUKtTRFCdI+nSJkk1bh/c7zu4A9b4Vj03eZbD7cOInxNZ87V2j +gaAwgZ0wCQYDVR0TBAIwADAdBgNVHQ4EFgQUTaEKxHUM/1o/CgtJpxlIsmFU8Msw +TwYDVR0jBEgwRoAUiniQ5fBQ54x15LjAoejpm7IanTKhGKQWMBQxEjAQBgNVBAMM +CUpGX3NlcnZlcoIUXe37kz2yqgyL2xXfvaGRzlz7ywYwEwYDVR0lBAwwCgYIKwYB +BQUHAwIwCwYDVR0PBAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IBAQCQGvYbJy+7++dp +2uKdPRtZZ6B3jaN5zRvpavEiF6lYWD+5tmYdQ9e3KjUdrmv4jqAEBgjP8i/YzZ/d +jIxe3UbuGZWnTvKB17G2klFDLmoLuVWLnpAIPy+8f/8toQmSld3vQBSEUfSlm3+F +/L9906QULJRybhdteZxSZ0v7hlUC/kNMd01o4ITVS2TH6DD9UT0fDa2j8by7+xGq +Wy0YYZr4mzXZXqJFXKfWeQ0cOq2568tG9Lkrz0HaFdC/SafMwX32aApgdlQr098c +iHd++xmG0fSj5z32F42EJ6pjBCbeJhPDn85hbO5s/3b7jb/oHTQaxCn2X7FdRiRA +HmjHjxhJ +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/44E31288C38E1632F41EBB13CA4D4C8D.pem b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/44E31288C38E1632F41EBB13CA4D4C8D.pem new file mode 100644 index 0000000..7c28581 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/44E31288C38E1632F41EBB13CA4D4C8D.pem @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 44:e3:12:88:c3:8e:16:32:f4:1e:bb:13:ca:4d:4c:8d + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Jan 18 20:53:00 2025 GMT + Not After : Apr 23 20:53:00 2027 GMT + Subject: CN=Otarcik202501 + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:40:90:47:89:d8:ec:72:20:95:c0:fb:8d:b7:10: + fc:52:1d:9b:ad:c1:65:91:e4:45:d5:0f:02:b0:31: + 8e:55:b7:fa:31:9a:a6:5a:1f:e0:85:cd:e2:21:9d: + 3c:95:7f:ad:80:f2:d1:63:e7:41:7d:e4:87:97:7e: + a4:d1:e7:d2:c9:3d:3b:66:9f:52:fe:11:72:d3:d7: + de:b9:f7:41:d5:7b:32:2b:01:94:4c:71:cb:ff:65: + 76:67:3e:ae:1a:4e:4f + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 27:9B:8A:B2:AB:54:28:C6:F2:23:81:99:3D:AB:D5:4C:25:8D:95:0B + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 5a:57:76:c3:9d:0e:55:d1:61:1d:43:2b:21:7c:ec:59:c0:07: + bf:76:f1:e6:c4:1b:3d:19:82:b0:b2:02:74:4c:d5:f2:7c:ba: + 33:f4:24:d8:68:6f:29:fe:85:f9:be:ee:90:42:04:c5:25:15: + 78:7e:8f:86:ef:ea:4d:15:d1:a5:dc:29:a4:50:99:74:a4:74: + 53:ee:3f:6c:c3:a9:b9:af:e0:a3:e2:33:6a:4a:aa:20:21:92: + bc:e5:57:86:5b:53:c7:68:b8:05:43:c8:10:d7:06:68:58:9f: + c4:2a:51:50:f5:dd:7c:ae:e4:80:59:5a:55:83:e4:88:58:be: + be:8d:68:fe:7a:7a:95:fe:7d:67:f6:03:d5:09:4d:3d:11:24: + 6d:03:33:40:5e:65:a2:c6:77:28:a0:60:aa:ea:df:08:31:7f: + d8:1f:94:8a:4e:2c:80:bc:8f:70:40:d3:14:72:a9:cd:9c:1f: + ef:b4:5d:a9:e6:65:49:fb:f7:e2:b3:ea:ce:59:c3:45:7d:05: + ca:16:fc:2b:ff:d9:fc:2d:c9:75:36:d4:60:a3:b7:03:5b:92: + 85:0a:3a:e1:50:8a:39:6b:d3:d5:4b:61:58:c6:2d:fe:96:b0: + 9d:26:6b:6d:d7:20:af:91:47:27:1f:13:61:34:33:f7:8a:16: + bd:da:ee:44 +-----BEGIN CERTIFICATE----- +MIICqTCCAZGgAwIBAgIQROMSiMOOFjL0HrsTyk1MjTANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjUwMTE4MjA1MzAwWhcNMjcwNDIzMjA1 +MzAwWjAYMRYwFAYDVQQDDA1PdGFyY2lrMjAyNTAxMHYwEAYHKoZIzj0CAQYFK4EE +ACIDYgAEQJBHidjsciCVwPuNtxD8Uh2brcFlkeRF1Q8CsDGOVbf6MZqmWh/ghc3i +IZ08lX+tgPLRY+dBfeSHl36k0efSyT07Zp9S/hFy09feufdB1XsyKwGUTHHL/2V2 +Zz6uGk5Po4GgMIGdMAkGA1UdEwQCMAAwHQYDVR0OBBYEFCebirKrVCjG8iOBmT2r +1UwljZULME8GA1UdIwRIMEaAFIp4kOXwUOeMdeS4wKHo6ZuyGp0yoRikFjAUMRIw +EAYDVQQDDAlKRl9zZXJ2ZXKCFF3t+5M9sqoMi9sV372hkc5c+8sGMBMGA1UdJQQM +MAoGCCsGAQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAWld2 +w50OVdFhHUMrIXzsWcAHv3bx5sQbPRmCsLICdEzV8ny6M/Qk2GhvKf6F+b7ukEIE +xSUVeH6Phu/qTRXRpdwppFCZdKR0U+4/bMOpua/go+IzakqqICGSvOVXhltTx2i4 +BUPIENcGaFifxCpRUPXdfK7kgFlaVYPkiFi+vo1o/np6lf59Z/YD1QlNPREkbQMz +QF5losZ3KKBgqurfCDF/2B+Uik4sgLyPcEDTFHKpzZwf77RdqeZlSfv34rPqzlnD +RX0Fyhb8K//Z/C3JdTbUYKO3A1uShQo64VCKOWvT1UthWMYt/pawnSZrbdcgr5FH +Jx8TYTQz94oWvdruRA== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/785E579993BEF247DACC6C8E0D713DF8.pem b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/785E579993BEF247DACC6C8E0D713DF8.pem new file mode 100644 index 0000000..2260c91 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/785E579993BEF247DACC6C8E0D713DF8.pem @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 78:5e:57:99:93:be:f2:47:da:cc:6c:8e:0d:71:3d:f8 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: May 5 13:33:22 2024 GMT + Not After : Aug 8 13:33:22 2026 GMT + Subject: CN=stationKA2401 + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:8f:4f:26:6b:af:cb:49:0b:74:3e:65:aa:0e:9a: + 9a:57:99:b1:f6:bf:dc:74:ae:d6:72:ed:d3:a8:04: + 2f:a8:a0:43:63:f6:c8:e2:cd:dc:d8:fd:bf:69:93: + 09:d7:bd:11:ab:d9:c5:ae:20:bc:00:ac:d7:ad:ea: + fb:c0:1e:44:6f:ba:20:63:9d:32:f7:38:8f:c0:d7: + bf:b4:23:15:16:4d:84:59:13:d5:4b:de:9e:7b:46: + d3:ce:ba:5d:d9:53:c4 + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 68:18:F5:54:75:30:27:4D:B5:96:D3:34:8E:1C:3B:58:1E:BC:1B:78 + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 67:97:34:79:07:29:c3:cd:a6:7c:86:82:aa:94:0b:ca:69:ef: + 79:5e:a6:35:97:c3:31:07:9f:cd:aa:89:95:e3:b1:26:4b:e9: + 88:50:1f:3e:10:eb:d2:82:c5:6e:56:18:1e:ff:72:60:c1:de: + 11:af:b8:e6:b6:bb:de:7d:52:f5:ba:1b:9b:4e:49:b2:05:25: + 0a:e9:8a:f8:85:f7:0e:c8:db:fd:c4:b9:e9:a9:6f:85:0a:cb: + 63:a3:d0:a7:77:e0:7f:ff:34:29:90:80:66:a7:8d:80:6a:bf: + 23:74:80:77:ad:53:2d:5e:f6:02:d1:05:3f:9f:fa:17:11:8f: + 7f:b4:a5:44:74:2b:57:1e:4b:7e:29:c8:95:48:a6:3a:fc:ae: + 82:c2:7b:b2:26:4f:92:d5:af:73:71:30:8e:b6:b9:6a:f2:b0: + 00:df:44:a2:3f:cd:4a:45:7e:ed:43:4b:d4:0e:07:25:94:37: + e0:5d:8d:0b:1b:fb:76:07:d0:41:da:c9:f3:19:fa:28:8b:46: + df:5a:19:82:ee:1e:e0:1a:be:39:c1:a9:65:b1:02:92:32:96: + 2c:7e:3f:4e:ce:9e:b0:66:57:b4:74:2c:98:de:13:da:b2:27: + e5:7a:5b:30:df:3e:46:1b:6c:92:53:6f:c6:0e:88:6f:0d:ae: + 89:ca:ea:ea +-----BEGIN CERTIFICATE----- +MIICqTCCAZGgAwIBAgIQeF5XmZO+8kfazGyODXE9+DANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjQwNTA1MTMzMzIyWhcNMjYwODA4MTMz +MzIyWjAYMRYwFAYDVQQDDA1zdGF0aW9uS0EyNDAxMHYwEAYHKoZIzj0CAQYFK4EE +ACIDYgAEj08ma6/LSQt0PmWqDpqaV5mx9r/cdK7Wcu3TqAQvqKBDY/bI4s3c2P2/ +aZMJ170Rq9nFriC8AKzXrer7wB5Eb7ogY50y9ziPwNe/tCMVFk2EWRPVS96ee0bT +zrpd2VPEo4GgMIGdMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGgY9VR1MCdNtZbTNI4c +O1gevBt4ME8GA1UdIwRIMEaAFIp4kOXwUOeMdeS4wKHo6ZuyGp0yoRikFjAUMRIw +EAYDVQQDDAlKRl9zZXJ2ZXKCFF3t+5M9sqoMi9sV372hkc5c+8sGMBMGA1UdJQQM +MAoGCCsGAQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAZ5c0 +eQcpw82mfIaCqpQLymnveV6mNZfDMQefzaqJleOxJkvpiFAfPhDr0oLFblYYHv9y +YMHeEa+45ra73n1S9bobm05JsgUlCumK+IX3Dsjb/cS56alvhQrLY6PQp3fgf/80 +KZCAZqeNgGq/I3SAd61TLV72AtEFP5/6FxGPf7SlRHQrVx5LfinIlUimOvyugsJ7 +siZPktWvc3Ewjra5avKwAN9Eoj/NSkV+7UNL1A4HJZQ34F2NCxv7dgfQQdrJ8xn6 +KItG31oZgu4e4Bq+OcGpZbECkjKWLH4/Ts6esGZXtHQsmN4T2rIn5XpbMN8+Rhts +klNvxg6Ibw2uicrq6g== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/7A066FB2ED7056F494707BB17BDCBE73.pem b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/7A066FB2ED7056F494707BB17BDCBE73.pem new file mode 100644 index 0000000..c923f63 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/7A066FB2ED7056F494707BB17BDCBE73.pem @@ -0,0 +1,73 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 7a:06:6f:b2:ed:70:56:f4:94:70:7b:b1:7b:dc:be:73 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Feb 20 22:27:55 2023 GMT + Not After : May 25 22:27:55 2025 GMT + Subject: CN=DO_server + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:2e:0a:88:e2:03:ad:14:3a:ee:00:51:96:3e:f5: + ec:24:cb:d6:5b:8d:d6:5d:0f:df:92:08:97:19:db: + b0:8d:c2:9d:d6:c6:a2:59:2e:94:d4:d9:d0:10:f8: + cd:d9:3c:90:80:e8:61:88:9a:be:ac:f8:ce:d2:44: + 7f:21:98:ff:d7:53:48:26:d6:18:6f:8f:0d:61:d3: + 36:f6:20:30:18:67:66:61:f7:25:da:ee:76:f5:ab: + 16:cb:fd:40:52:95:3c + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + DF:EE:7B:FF:0B:6D:D0:D9:44:84:A9:FA:00:F6:A6:AB:D9:A4:D2:4F + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Key Usage: + Digital Signature, Key Encipherment + X509v3 Subject Alternative Name: + DNS:DO_server + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 2f:00:b3:78:70:fe:01:fc:cb:49:5d:8c:94:0a:fa:ed:91:63: + 28:cc:a0:27:09:11:fd:ed:31:50:ef:d4:01:ba:1c:29:77:60: + 01:2d:dd:7a:cd:ee:26:a1:1d:35:c9:08:b6:39:73:64:30:f7: + c0:21:8d:d3:36:28:7d:47:e4:92:8a:c4:23:a1:50:97:e3:2e: + 5b:6c:a5:ce:87:80:c5:6e:a3:d0:56:79:2e:e8:c1:50:e2:28: + ec:31:14:fc:a4:82:29:9a:78:56:d2:07:7f:f9:7f:78:59:01: + 74:ce:0e:49:cc:cb:8b:43:6b:50:d4:79:b2:9b:8d:d7:49:ac: + a4:63:e1:3b:2f:e7:41:89:b8:fe:65:84:f7:f3:bf:77:55:78: + c1:66:ac:27:d5:42:54:3b:a2:c3:ff:5d:1a:f5:db:8b:f0:3b: + 23:05:23:c5:79:d7:00:db:60:03:51:60:79:4d:72:81:78:55: + 11:55:95:9b:44:a0:21:b9:f4:85:2f:83:ce:03:67:ba:d3:80: + 45:7e:cd:c5:0c:51:f4:03:56:30:cf:d7:e6:1f:ec:1f:8c:38: + 29:cf:94:39:f7:c2:f6:21:0b:cf:33:3b:ba:05:5f:74:34:20: + da:e3:ec:50:f9:d4:3a:55:7e:cd:91:f2:bf:4e:fd:50:40:f3: + 89:10:37:20 +-----BEGIN CERTIFICATE----- +MIICuzCCAaOgAwIBAgIQegZvsu1wVvSUcHuxe9y+czANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjMwMjIwMjIyNzU1WhcNMjUwNTI1MjIy +NzU1WjAUMRIwEAYDVQQDDAlET19zZXJ2ZXIwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQuCojiA60UOu4AUZY+9ewky9ZbjdZdD9+SCJcZ27CNwp3WxqJZLpTU2dAQ+M3Z +PJCA6GGImr6s+M7SRH8hmP/XU0gm1hhvjw1h0zb2IDAYZ2Zh9yXa7nb1qxbL/UBS +lTyjgbYwgbMwCQYDVR0TBAIwADAdBgNVHQ4EFgQU3+57/wtt0NlEhKn6APamq9mk +0k8wTwYDVR0jBEgwRoAUiniQ5fBQ54x15LjAoejpm7IanTKhGKQWMBQxEjAQBgNV +BAMMCUpGX3NlcnZlcoIUXe37kz2yqgyL2xXfvaGRzlz7ywYwEwYDVR0lBAwwCgYI +KwYBBQUHAwEwCwYDVR0PBAQDAgWgMBQGA1UdEQQNMAuCCURPX3NlcnZlcjANBgkq +hkiG9w0BAQsFAAOCAQEALwCzeHD+AfzLSV2MlAr67ZFjKMygJwkR/e0xUO/UAboc +KXdgAS3des3uJqEdNckItjlzZDD3wCGN0zYofUfkkorEI6FQl+MuW2ylzoeAxW6j +0FZ5LujBUOIo7DEU/KSCKZp4VtIHf/l/eFkBdM4OSczLi0NrUNR5spuN10mspGPh +Oy/nQYm4/mWE9/O/d1V4wWasJ9VCVDuiw/9dGvXbi/A7IwUjxXnXANtgA1FgeU1y +gXhVEVWVm0SgIbn0hS+DzgNnutOARX7NxQxR9ANWMM/X5h/sH4w4Kc+UOffC9iEL +zzM7ugVfdDQg2uPsUPnUOlV+zZHyv079UEDziRA3IA== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/A67F642294224A39B948259B999DAEA7.pem b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/A67F642294224A39B948259B999DAEA7.pem new file mode 100644 index 0000000..5730b5c --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/A67F642294224A39B948259B999DAEA7.pem @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + a6:7f:64:22:94:22:4a:39:b9:48:25:9b:99:9d:ae:a7 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Mar 17 19:30:32 2023 GMT + Not After : Jun 19 19:30:32 2025 GMT + Subject: CN=pascal + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:6e:d7:fc:29:a8:23:70:28:49:70:82:f4:1a:4f: + fc:e8:5a:d3:10:84:ef:0a:59:d9:3e:31:2e:5f:91: + 8b:97:7e:32:c5:e4:9a:b1:df:8b:66:82:f7:a5:5a: + 6d:90:ba:4d:4b:75:4e:1b:09:37:3b:23:5b:df:b8: + 08:89:c7:a0:d6:3b:fa:3e:f8:b1:08:18:a6:ee:25: + 02:25:b2:c5:43:ee:f5:03:82:9e:39:a0:82:d0:23: + 49:eb:fe:be:3e:8f:7a + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 8E:E1:F2:13:12:D0:E0:C4:29:EA:29:E4:3D:94:2B:EC:0D:04:8F:BC + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 7d:0b:3f:f6:58:09:f2:8a:8d:0e:1e:50:c9:e8:31:f0:8f:0a: + f5:65:66:55:d3:dd:2c:5d:42:d4:0f:a5:02:ed:6a:77:e1:1d: + 39:c5:46:1c:a5:38:17:89:13:f1:cd:eb:ff:b8:a5:3d:e9:85: + 6f:d2:96:9b:f4:a1:09:6c:1b:84:40:70:19:2b:e1:ac:91:c2: + df:bf:09:a4:4f:c4:31:44:fe:2b:a5:60:38:97:a8:b3:01:aa: + 39:43:74:90:b5:c6:fc:85:63:26:9f:7f:54:ba:de:4a:b1:ae: + 6d:85:00:35:4d:15:9f:9d:10:f4:bf:bb:67:45:7e:c6:ab:ee: + 7e:ad:92:4a:b4:e8:76:65:be:94:40:5a:67:83:ab:6c:d9:f9: + 7d:40:bd:70:87:1f:14:4d:eb:56:50:a5:c3:7e:4a:b3:42:b5: + 95:fe:f8:7f:9b:c6:c0:81:04:62:fd:94:ef:da:dd:17:01:a0: + 93:14:80:31:5a:a2:fa:c7:8c:2d:7c:df:8b:40:d5:5c:ce:5f: + a8:9f:9f:48:4f:49:49:dc:cc:37:7e:f7:55:84:74:8a:cd:68: + 15:60:8b:e8:4a:75:3e:83:cb:33:be:45:e1:a1:76:52:1a:b9: + 09:34:38:af:6e:af:98:e3:6d:ed:c2:24:97:de:08:83:6b:d5: + 45:9e:91:3a +-----BEGIN CERTIFICATE----- +MIICozCCAYugAwIBAgIRAKZ/ZCKUIko5uUglm5mdrqcwDQYJKoZIhvcNAQELBQAw +FDESMBAGA1UEAwwJSkZfc2VydmVyMB4XDTIzMDMxNzE5MzAzMloXDTI1MDYxOTE5 +MzAzMlowETEPMA0GA1UEAwwGcGFzY2FsMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE +btf8KagjcChJcIL0Gk/86FrTEITvClnZPjEuX5GLl34yxeSasd+LZoL3pVptkLpN +S3VOGwk3OyNb37gIiceg1jv6PvixCBim7iUCJbLFQ+71A4KeOaCC0CNJ6/6+Po96 +o4GgMIGdMAkGA1UdEwQCMAAwHQYDVR0OBBYEFI7h8hMS0ODEKeop5D2UK+wNBI+8 +ME8GA1UdIwRIMEaAFIp4kOXwUOeMdeS4wKHo6ZuyGp0yoRikFjAUMRIwEAYDVQQD +DAlKRl9zZXJ2ZXKCFF3t+5M9sqoMi9sV372hkc5c+8sGMBMGA1UdJQQMMAoGCCsG +AQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAfQs/9lgJ8oqN +Dh5Qyegx8I8K9WVmVdPdLF1C1A+lAu1qd+EdOcVGHKU4F4kT8c3r/7ilPemFb9KW +m/ShCWwbhEBwGSvhrJHC378JpE/EMUT+K6VgOJeoswGqOUN0kLXG/IVjJp9/VLre +SrGubYUANU0Vn50Q9L+7Z0V+xqvufq2SSrTodmW+lEBaZ4OrbNn5fUC9cIcfFE3r +VlClw35Ks0K1lf74f5vGwIEEYv2U79rdFwGgkxSAMVqi+seMLXzfi0DVXM5fqJ+f +SE9JSdzMN373VYR0is1oFWCL6Ep1PoPLM75F4aF2Uhq5CTQ4r26vmONt7cIkl94I +g2vVRZ6ROg== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/ABBA5527AA06497B13DDF25BAE2708FE.pem b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/ABBA5527AA06497B13DDF25BAE2708FE.pem new file mode 100644 index 0000000..96b815d --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/ABBA5527AA06497B13DDF25BAE2708FE.pem @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + ab:ba:55:27:aa:06:49:7b:13:dd:f2:5b:ae:27:08:fe + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Jun 1 18:17:32 2023 GMT + Not After : Sep 3 18:17:32 2025 GMT + Subject: CN=fred + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:3e:78:ef:26:d9:87:bb:8b:08:47:fe:15:ad:96: + ae:f4:93:f1:d8:ce:e3:05:d2:96:46:fc:f6:47:c9: + ac:41:f5:01:1b:e3:25:61:f4:ee:6f:8d:13:dd:ab: + 1b:d8:02:85:a3:fb:52:3d:02:d8:ad:0b:ed:e3:02: + 88:c7:eb:06:52:ca:25:ac:8b:ac:eb:52:4c:43:52: + f9:c0:8c:f4:48:ea:72:a6:26:f7:5f:02:96:97:ad: + 10:ac:6d:c8:d3:b1:28 + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 3C:F6:00:C3:CF:A4:BB:8D:F1:1B:AB:A1:6F:24:44:2A:73:95:EB:46 + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 10:9c:49:d0:09:dc:52:df:2b:e1:ce:59:ef:f7:a0:96:13:05: + 7e:30:ba:4b:6d:17:62:ed:89:39:cb:0e:c5:cc:df:0c:5a:68: + e7:0f:bc:c2:67:e0:b2:72:b6:9f:e7:9f:1f:4c:e5:da:d9:5c: + d8:53:44:ef:47:ea:47:9d:d7:1d:12:ab:75:c3:1f:c4:d8:ae: + 65:7e:39:9d:98:f1:02:df:03:77:1e:7b:88:24:5f:7e:51:5c: + f2:9c:b8:1f:84:71:4b:f9:5a:6d:06:63:4d:e9:ab:27:f5:99: + fa:ac:25:7a:e2:a7:ba:94:a7:44:8b:2f:21:73:c1:db:1a:37: + 38:d6:46:4a:a5:65:f7:24:35:08:40:9a:8e:d6:22:56:20:c9: + 7b:52:b3:8f:ea:53:bf:00:bd:6a:23:bd:07:fe:af:2e:20:ee: + 71:69:f8:66:b0:f3:00:5e:8d:2f:2a:37:b9:14:a6:bf:c8:25: + 2e:1b:f4:86:58:94:33:2b:85:f9:08:3a:48:9e:49:42:66:5a: + 37:10:10:5b:50:2e:f6:06:d0:fe:86:17:0d:9d:f5:dd:cb:ab: + 92:39:de:d8:57:9d:0d:7e:14:b7:61:e5:bc:dc:62:00:22:8c: + 23:df:90:d4:38:01:18:23:96:c6:7e:e8:c8:5e:c8:fd:a4:b2: + 47:87:02:4f +-----BEGIN CERTIFICATE----- +MIICoTCCAYmgAwIBAgIRAKu6VSeqBkl7E93yW64nCP4wDQYJKoZIhvcNAQELBQAw +FDESMBAGA1UEAwwJSkZfc2VydmVyMB4XDTIzMDYwMTE4MTczMloXDTI1MDkwMzE4 +MTczMlowDzENMAsGA1UEAwwEZnJlZDB2MBAGByqGSM49AgEGBSuBBAAiA2IABD54 +7ybZh7uLCEf+Fa2WrvST8djO4wXSlkb89kfJrEH1ARvjJWH07m+NE92rG9gChaP7 +Uj0C2K0L7eMCiMfrBlLKJayLrOtSTENS+cCM9EjqcqYm918ClpetEKxtyNOxKKOB +oDCBnTAJBgNVHRMEAjAAMB0GA1UdDgQWBBQ89gDDz6S7jfEbq6FvJEQqc5XrRjBP +BgNVHSMESDBGgBSKeJDl8FDnjHXkuMCh6OmbshqdMqEYpBYwFDESMBAGA1UEAwwJ +SkZfc2VydmVyghRd7fuTPbKqDIvbFd+9oZHOXPvLBjATBgNVHSUEDDAKBggrBgEF +BQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBABCcSdAJ3FLfK+HO +We/3oJYTBX4wukttF2LtiTnLDsXM3wxaaOcPvMJn4LJytp/nnx9M5drZXNhTRO9H +6ked1x0Sq3XDH8TYrmV+OZ2Y8QLfA3cee4gkX35RXPKcuB+EcUv5Wm0GY03pqyf1 +mfqsJXrip7qUp0SLLyFzwdsaNzjWRkqlZfckNQhAmo7WIlYgyXtSs4/qU78AvWoj +vQf+ry4g7nFp+Gaw8wBejS8qN7kUpr/IJS4b9IZYlDMrhfkIOkieSUJmWjcQEFtQ +LvYG0P6GFw2d9d3Lq5I53thXnQ1+FLdh5bzcYgAijCPfkNQ4ARgjlsZ+6MheyP2k +skeHAk8= +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/D1AE61458E84E38E5B923FAABB819D59.pem b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/D1AE61458E84E38E5B923FAABB819D59.pem new file mode 100644 index 0000000..ed70cba --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/certs_by_serial/D1AE61458E84E38E5B923FAABB819D59.pem @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + d1:ae:61:45:8e:84:e3:8e:5b:92:3f:aa:bb:81:9d:59 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Feb 23 20:30:31 2023 GMT + Not After : May 28 20:30:31 2025 GMT + Subject: CN=remoteclient + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:65:e9:86:35:01:c3:d7:0e:16:3d:89:90:3c:cb: + a0:5f:d2:04:f7:b6:32:84:1e:a0:dc:6a:1d:16:a0: + 6f:47:a3:b5:7d:4c:39:bd:d0:70:18:34:e8:16:67: + d4:5b:4c:ca:ce:ea:f0:75:5f:55:72:09:4b:f5:dd: + 80:f1:d5:db:e6:26:09:e4:34:3b:ca:89:f3:3a:40: + 91:31:14:c6:ff:06:8d:8e:f9:ba:8f:47:df:40:41: + f4:6b:84:f8:e5:e8:70 + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 23:F8:BF:EB:8E:A3:77:B3:2B:6A:FA:16:7A:39:B2:C2:47:31:9F:76 + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 27:af:ff:e0:98:8e:d1:6c:39:d7:40:97:df:ea:5a:fc:57:31: + a2:92:0c:d3:4c:4b:74:22:9e:47:01:9b:0f:e0:a4:6c:dc:ef: + 14:b7:93:0f:99:93:ec:c9:96:dc:51:58:d3:ac:eb:f1:10:48: + ba:96:54:25:32:2a:89:66:cb:ca:13:b4:75:cc:4e:2a:5d:7c: + bb:b9:15:28:c0:32:59:f0:66:e5:fe:d8:14:14:2c:fb:df:6e: + 1e:b6:53:c9:f0:77:68:54:b9:21:4b:0c:a4:d6:bc:4d:c2:a3: + de:d0:9f:ef:67:68:3e:c6:d4:da:d5:6c:92:80:cf:2e:8d:04: + 59:c8:39:9f:22:4a:04:28:3e:e8:cf:02:73:73:a6:59:d4:e5: + 9c:77:55:41:00:5c:c2:23:61:df:44:5c:ad:a8:bc:15:57:2d: + ae:89:99:a7:33:8f:d3:75:02:21:91:f6:38:34:23:68:70:8f: + 99:0f:53:27:6d:52:9a:9b:f3:62:cf:20:bc:f5:91:41:78:fc: + 92:09:2f:3e:bb:2d:9b:69:39:7f:c4:b1:a8:62:64:27:3f:27: + 2d:16:c4:3e:0d:51:c9:f7:4f:40:f0:fd:55:a9:44:36:31:59: + b7:08:6a:3c:28:31:8a:43:c0:b9:05:44:75:48:6d:94:24:c6: + b2:fc:f7:33 +-----BEGIN CERTIFICATE----- +MIICqTCCAZGgAwIBAgIRANGuYUWOhOOOW5I/qruBnVkwDQYJKoZIhvcNAQELBQAw +FDESMBAGA1UEAwwJSkZfc2VydmVyMB4XDTIzMDIyMzIwMzAzMVoXDTI1MDUyODIw +MzAzMVowFzEVMBMGA1UEAwwMcmVtb3RlY2xpZW50MHYwEAYHKoZIzj0CAQYFK4EE +ACIDYgAEZemGNQHD1w4WPYmQPMugX9IE97YyhB6g3GodFqBvR6O1fUw5vdBwGDTo +FmfUW0zKzurwdV9VcglL9d2A8dXb5iYJ5DQ7yonzOkCRMRTG/waNjvm6j0ffQEH0 +a4T45ehwo4GgMIGdMAkGA1UdEwQCMAAwHQYDVR0OBBYEFCP4v+uOo3ezK2r6Fno5 +ssJHMZ92ME8GA1UdIwRIMEaAFIp4kOXwUOeMdeS4wKHo6ZuyGp0yoRikFjAUMRIw +EAYDVQQDDAlKRl9zZXJ2ZXKCFF3t+5M9sqoMi9sV372hkc5c+8sGMBMGA1UdJQQM +MAoGCCsGAQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAJ6// +4JiO0Ww510CX3+pa/FcxopIM00xLdCKeRwGbD+CkbNzvFLeTD5mT7MmW3FFY06zr +8RBIupZUJTIqiWbLyhO0dcxOKl18u7kVKMAyWfBm5f7YFBQs+99uHrZTyfB3aFS5 +IUsMpNa8TcKj3tCf72doPsbU2tVskoDPLo0EWcg5nyJKBCg+6M8Cc3OmWdTlnHdV +QQBcwiNh30Rcrai8FVctromZpzOP03UCIZH2ODQjaHCPmQ9TJ21SmpvzYs8gvPWR +QXj8kgkvPrstm2k5f8SxqGJkJz8nLRbEPg1RyfdPQPD9ValENjFZtwhqPCgxikPA +uQVEdUhtlCTGsvz3Mw== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/index.txt b/OpenVPN/CA Server/easy-rsa/pki/index.txt new file mode 100644 index 0000000..6327943 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/index.txt @@ -0,0 +1,10 @@ +V 250525222755Z 7A066FB2ED7056F494707BB17BDCBE73 unknown /CN=DO_server +V 250525223746Z 227AB3CB8805008CDFAF02BEAF63F959 unknown /CN=jf +V 250528203031Z D1AE61458E84E38E5B923FAABB819D59 unknown /CN=remoteclient +V 250619183511Z 2A951944ADF0A2C8E81A4C541C1899E5 unknown /CN=pascal +V 250619190830Z 35F253A0DF2EA1227A3926855218BBD5 unknown /CN=pascal +V 250619193032Z A67F642294224A39B948259B999DAEA7 unknown /CN=pascal +V 250903181732Z ABBA5527AA06497B13DDF25BAE2708FE unknown /CN=fred +V 251005191130Z 3509162241A87805B57226316EC39402 unknown /CN=edgerouterchambly +V 260808133322Z 785E579993BEF247DACC6C8E0D713DF8 unknown /CN=stationKA2401 +V 270423205300Z 44E31288C38E1632F41EBB13CA4D4C8D unknown /CN=Otarcik202501 diff --git a/OpenVPN/CA Server/easy-rsa/pki/index.txt.attr b/OpenVPN/CA Server/easy-rsa/pki/index.txt.attr new file mode 100644 index 0000000..3a7e39e --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/index.txt.attr @@ -0,0 +1 @@ +unique_subject = no diff --git a/OpenVPN/CA Server/easy-rsa/pki/index.txt.attr.old b/OpenVPN/CA Server/easy-rsa/pki/index.txt.attr.old new file mode 100644 index 0000000..3a7e39e --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/index.txt.attr.old @@ -0,0 +1 @@ +unique_subject = no diff --git a/OpenVPN/CA Server/easy-rsa/pki/index.txt.old b/OpenVPN/CA Server/easy-rsa/pki/index.txt.old new file mode 100644 index 0000000..5295ec4 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/index.txt.old @@ -0,0 +1,9 @@ +V 250525222755Z 7A066FB2ED7056F494707BB17BDCBE73 unknown /CN=DO_server +V 250525223746Z 227AB3CB8805008CDFAF02BEAF63F959 unknown /CN=jf +V 250528203031Z D1AE61458E84E38E5B923FAABB819D59 unknown /CN=remoteclient +V 250619183511Z 2A951944ADF0A2C8E81A4C541C1899E5 unknown /CN=pascal +V 250619190830Z 35F253A0DF2EA1227A3926855218BBD5 unknown /CN=pascal +V 250619193032Z A67F642294224A39B948259B999DAEA7 unknown /CN=pascal +V 250903181732Z ABBA5527AA06497B13DDF25BAE2708FE unknown /CN=fred +V 251005191130Z 3509162241A87805B57226316EC39402 unknown /CN=edgerouterchambly +V 260808133322Z 785E579993BEF247DACC6C8E0D713DF8 unknown /CN=stationKA2401 diff --git a/OpenVPN/CA Server/easy-rsa/pki/issued/DO_server.crt b/OpenVPN/CA Server/easy-rsa/pki/issued/DO_server.crt new file mode 100644 index 0000000..c923f63 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/issued/DO_server.crt @@ -0,0 +1,73 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 7a:06:6f:b2:ed:70:56:f4:94:70:7b:b1:7b:dc:be:73 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Feb 20 22:27:55 2023 GMT + Not After : May 25 22:27:55 2025 GMT + Subject: CN=DO_server + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:2e:0a:88:e2:03:ad:14:3a:ee:00:51:96:3e:f5: + ec:24:cb:d6:5b:8d:d6:5d:0f:df:92:08:97:19:db: + b0:8d:c2:9d:d6:c6:a2:59:2e:94:d4:d9:d0:10:f8: + cd:d9:3c:90:80:e8:61:88:9a:be:ac:f8:ce:d2:44: + 7f:21:98:ff:d7:53:48:26:d6:18:6f:8f:0d:61:d3: + 36:f6:20:30:18:67:66:61:f7:25:da:ee:76:f5:ab: + 16:cb:fd:40:52:95:3c + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + DF:EE:7B:FF:0B:6D:D0:D9:44:84:A9:FA:00:F6:A6:AB:D9:A4:D2:4F + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Key Usage: + Digital Signature, Key Encipherment + X509v3 Subject Alternative Name: + DNS:DO_server + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 2f:00:b3:78:70:fe:01:fc:cb:49:5d:8c:94:0a:fa:ed:91:63: + 28:cc:a0:27:09:11:fd:ed:31:50:ef:d4:01:ba:1c:29:77:60: + 01:2d:dd:7a:cd:ee:26:a1:1d:35:c9:08:b6:39:73:64:30:f7: + c0:21:8d:d3:36:28:7d:47:e4:92:8a:c4:23:a1:50:97:e3:2e: + 5b:6c:a5:ce:87:80:c5:6e:a3:d0:56:79:2e:e8:c1:50:e2:28: + ec:31:14:fc:a4:82:29:9a:78:56:d2:07:7f:f9:7f:78:59:01: + 74:ce:0e:49:cc:cb:8b:43:6b:50:d4:79:b2:9b:8d:d7:49:ac: + a4:63:e1:3b:2f:e7:41:89:b8:fe:65:84:f7:f3:bf:77:55:78: + c1:66:ac:27:d5:42:54:3b:a2:c3:ff:5d:1a:f5:db:8b:f0:3b: + 23:05:23:c5:79:d7:00:db:60:03:51:60:79:4d:72:81:78:55: + 11:55:95:9b:44:a0:21:b9:f4:85:2f:83:ce:03:67:ba:d3:80: + 45:7e:cd:c5:0c:51:f4:03:56:30:cf:d7:e6:1f:ec:1f:8c:38: + 29:cf:94:39:f7:c2:f6:21:0b:cf:33:3b:ba:05:5f:74:34:20: + da:e3:ec:50:f9:d4:3a:55:7e:cd:91:f2:bf:4e:fd:50:40:f3: + 89:10:37:20 +-----BEGIN CERTIFICATE----- +MIICuzCCAaOgAwIBAgIQegZvsu1wVvSUcHuxe9y+czANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjMwMjIwMjIyNzU1WhcNMjUwNTI1MjIy +NzU1WjAUMRIwEAYDVQQDDAlET19zZXJ2ZXIwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQuCojiA60UOu4AUZY+9ewky9ZbjdZdD9+SCJcZ27CNwp3WxqJZLpTU2dAQ+M3Z +PJCA6GGImr6s+M7SRH8hmP/XU0gm1hhvjw1h0zb2IDAYZ2Zh9yXa7nb1qxbL/UBS +lTyjgbYwgbMwCQYDVR0TBAIwADAdBgNVHQ4EFgQU3+57/wtt0NlEhKn6APamq9mk +0k8wTwYDVR0jBEgwRoAUiniQ5fBQ54x15LjAoejpm7IanTKhGKQWMBQxEjAQBgNV +BAMMCUpGX3NlcnZlcoIUXe37kz2yqgyL2xXfvaGRzlz7ywYwEwYDVR0lBAwwCgYI +KwYBBQUHAwEwCwYDVR0PBAQDAgWgMBQGA1UdEQQNMAuCCURPX3NlcnZlcjANBgkq +hkiG9w0BAQsFAAOCAQEALwCzeHD+AfzLSV2MlAr67ZFjKMygJwkR/e0xUO/UAboc +KXdgAS3des3uJqEdNckItjlzZDD3wCGN0zYofUfkkorEI6FQl+MuW2ylzoeAxW6j +0FZ5LujBUOIo7DEU/KSCKZp4VtIHf/l/eFkBdM4OSczLi0NrUNR5spuN10mspGPh +Oy/nQYm4/mWE9/O/d1V4wWasJ9VCVDuiw/9dGvXbi/A7IwUjxXnXANtgA1FgeU1y +gXhVEVWVm0SgIbn0hS+DzgNnutOARX7NxQxR9ANWMM/X5h/sH4w4Kc+UOffC9iEL +zzM7ugVfdDQg2uPsUPnUOlV+zZHyv079UEDziRA3IA== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/issued/Otarcik202501.crt b/OpenVPN/CA Server/easy-rsa/pki/issued/Otarcik202501.crt new file mode 100644 index 0000000..7c28581 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/issued/Otarcik202501.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 44:e3:12:88:c3:8e:16:32:f4:1e:bb:13:ca:4d:4c:8d + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Jan 18 20:53:00 2025 GMT + Not After : Apr 23 20:53:00 2027 GMT + Subject: CN=Otarcik202501 + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:40:90:47:89:d8:ec:72:20:95:c0:fb:8d:b7:10: + fc:52:1d:9b:ad:c1:65:91:e4:45:d5:0f:02:b0:31: + 8e:55:b7:fa:31:9a:a6:5a:1f:e0:85:cd:e2:21:9d: + 3c:95:7f:ad:80:f2:d1:63:e7:41:7d:e4:87:97:7e: + a4:d1:e7:d2:c9:3d:3b:66:9f:52:fe:11:72:d3:d7: + de:b9:f7:41:d5:7b:32:2b:01:94:4c:71:cb:ff:65: + 76:67:3e:ae:1a:4e:4f + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 27:9B:8A:B2:AB:54:28:C6:F2:23:81:99:3D:AB:D5:4C:25:8D:95:0B + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 5a:57:76:c3:9d:0e:55:d1:61:1d:43:2b:21:7c:ec:59:c0:07: + bf:76:f1:e6:c4:1b:3d:19:82:b0:b2:02:74:4c:d5:f2:7c:ba: + 33:f4:24:d8:68:6f:29:fe:85:f9:be:ee:90:42:04:c5:25:15: + 78:7e:8f:86:ef:ea:4d:15:d1:a5:dc:29:a4:50:99:74:a4:74: + 53:ee:3f:6c:c3:a9:b9:af:e0:a3:e2:33:6a:4a:aa:20:21:92: + bc:e5:57:86:5b:53:c7:68:b8:05:43:c8:10:d7:06:68:58:9f: + c4:2a:51:50:f5:dd:7c:ae:e4:80:59:5a:55:83:e4:88:58:be: + be:8d:68:fe:7a:7a:95:fe:7d:67:f6:03:d5:09:4d:3d:11:24: + 6d:03:33:40:5e:65:a2:c6:77:28:a0:60:aa:ea:df:08:31:7f: + d8:1f:94:8a:4e:2c:80:bc:8f:70:40:d3:14:72:a9:cd:9c:1f: + ef:b4:5d:a9:e6:65:49:fb:f7:e2:b3:ea:ce:59:c3:45:7d:05: + ca:16:fc:2b:ff:d9:fc:2d:c9:75:36:d4:60:a3:b7:03:5b:92: + 85:0a:3a:e1:50:8a:39:6b:d3:d5:4b:61:58:c6:2d:fe:96:b0: + 9d:26:6b:6d:d7:20:af:91:47:27:1f:13:61:34:33:f7:8a:16: + bd:da:ee:44 +-----BEGIN CERTIFICATE----- +MIICqTCCAZGgAwIBAgIQROMSiMOOFjL0HrsTyk1MjTANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjUwMTE4MjA1MzAwWhcNMjcwNDIzMjA1 +MzAwWjAYMRYwFAYDVQQDDA1PdGFyY2lrMjAyNTAxMHYwEAYHKoZIzj0CAQYFK4EE +ACIDYgAEQJBHidjsciCVwPuNtxD8Uh2brcFlkeRF1Q8CsDGOVbf6MZqmWh/ghc3i +IZ08lX+tgPLRY+dBfeSHl36k0efSyT07Zp9S/hFy09feufdB1XsyKwGUTHHL/2V2 +Zz6uGk5Po4GgMIGdMAkGA1UdEwQCMAAwHQYDVR0OBBYEFCebirKrVCjG8iOBmT2r +1UwljZULME8GA1UdIwRIMEaAFIp4kOXwUOeMdeS4wKHo6ZuyGp0yoRikFjAUMRIw +EAYDVQQDDAlKRl9zZXJ2ZXKCFF3t+5M9sqoMi9sV372hkc5c+8sGMBMGA1UdJQQM +MAoGCCsGAQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAWld2 +w50OVdFhHUMrIXzsWcAHv3bx5sQbPRmCsLICdEzV8ny6M/Qk2GhvKf6F+b7ukEIE +xSUVeH6Phu/qTRXRpdwppFCZdKR0U+4/bMOpua/go+IzakqqICGSvOVXhltTx2i4 +BUPIENcGaFifxCpRUPXdfK7kgFlaVYPkiFi+vo1o/np6lf59Z/YD1QlNPREkbQMz +QF5losZ3KKBgqurfCDF/2B+Uik4sgLyPcEDTFHKpzZwf77RdqeZlSfv34rPqzlnD +RX0Fyhb8K//Z/C3JdTbUYKO3A1uShQo64VCKOWvT1UthWMYt/pawnSZrbdcgr5FH +Jx8TYTQz94oWvdruRA== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/issued/easyrsa b/OpenVPN/CA Server/easy-rsa/pki/issued/easyrsa new file mode 100644 index 0000000..408caf0 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/issued/easyrsa @@ -0,0 +1,4095 @@ +#!/bin/sh + +# Easy-RSA 3 -- A Shell-based CA Utility +# +# Copyright (C) 2018 by the Open-Source OpenVPN development community. +# A full list of contributors can be found on Github at: +# https://github.com/OpenVPN/easy-rsa/graphs/contributors +# +# This code released under version 2 of the GNU GPL; see COPYING and the +# Licensing/ directory of this project for full licensing details. + +# Help/usage output to stdout +usage() { + # command help: + print " +Easy-RSA 3 usage and overview + +USAGE: easyrsa [options] COMMAND [command-options] + +A list of commands is shown below. To get detailed usage and help for a +command, run: + ./easyrsa help COMMAND + +For a listing of options that can be supplied before the command, use: + ./easyrsa help options + +Here is the list of commands available with a short syntax reminder. Use the +'help' command above to get full usage details. + + init-pki [ cmd-opts ] + build-ca [ cmd-opts ] + gen-dh + gen-req [ cmd-opts ] + sign-req + build-client-full [ cmd-opts ] + build-server-full [ cmd-opts ] + build-serverClient-full [ cmd-opts ] + revoke [cmd-opts] + revoke-renewed [cmd-opts] + renew [cmd-opts] + renewable [ ] + gen-crl + update-db + show-req [ cmd-opts ] + show-cert [ cmd-opts ] + show-ca [ cmd-opts ] + show-crl + show-expire + show-revoke + show-renew + verify + import-req + export-p1 [ cmd-opts ] + export-p7 [ cmd-opts ] + export-p8 [ cmd-opts ] + export-p12 [ cmd-opts ] + set-rsa-pass [ cmd-opts ] + set-ec-pass [ cmd-opts ] + upgrade +" + + # collect/show dir status: + err_source="Not defined: vars autodetect failed and no value provided" + work_dir="${EASYRSA:-$err_source}" + pki_dir="${EASYRSA_PKI:-$err_source}" + print "\ +DIRECTORY STATUS (commands would take effect on these locations) + EASYRSA: $work_dir + PKI: $pki_dir +" +} # => usage() + +# Detailed command help +# When called with no args, calls usage(), otherwise shows help for a command +cmd_help() { + text="" + opts="" + case "$1" in + init-pki|clean-all) text=" + init-pki [ cmd-opts ] + Removes & re-initializes the PKI dir for a clean PKI" + opts=" + hard-reset - Recursively deletes the PKI directory if it exists. + soft-reset - Keeps the vars file and the PKI directory itself intact." ;; + build-ca) text=" + build-ca [ cmd-opts ] + Creates a new CA" + opts=" + nopass - do not encrypt the CA key (default is encrypted) + subca - create an intermediate CA keypair and request (default is a root CA) + intca - alias to the above" ;; + gen-dh) text=" + gen-dh + Generates DH (Diffie-Hellman) parameters" ;; + gen-req) text=" + gen-req [ cmd-opts ] + Generate a standalone keypair and request (CSR) + + This request is suitable for sending to a remote CA for signing." + opts=" + text - Include certificate text in request + nopass - do not encrypt the private key (default is encrypted)" ;; + sign|sign-req) text=" + sign-req + Sign a certificate request of the defined type. must be a known + type such as 'client', 'server', 'serverClient', or 'ca' (or a user-added type.) + + This request file must exist in the reqs/ dir and have a .req file + extension. See import-req below for importing reqs from other sources." ;; + build|build-client-full|build-server-full|build-serverClient-full) text=" + build-client-full [ cmd-opts ] + build-server-full [ cmd-opts ] + build-serverClient-full [ cmd-opts ] + Generate a keypair and sign locally for a client and/or server + + This mode uses the as the X509 CN." + opts=" + nopass - do not encrypt the private key (default is encrypted) + inline - create an inline credentials file for this node" ;; + revoke) text=" + revoke [reason] + Revoke a certificate specified by the filename_base, with an optional + revocation reason that is one of: + unspecified + keyCompromise + CACompromise + affiliationChanged + superseded + cessationOfOperation + certificateHold";; + revoke-renewed) text=" + revoke-renewed [reason] + Revoke a renewed certificate specified by the filename_base, with an optional + revocation reason that is one of: + unspecified + keyCompromise + CACompromise + affiliationChanged + superseded + cessationOfOperation + certificateHold";; + renew) text=" + renew [ cmd-opts ] + Renew a certificate specified by the filename_base" + opts=" + nopass - do not encrypt the private key (default is encrypted)" ;; + renewable) text=" + renewable [ ] + Check which certificates can be renewed" ;; + gen-crl) text=" + gen-crl + Generate a CRL" ;; + update-db) text=" + update-db + Update the index.txt database + + This command will use the system time to update the status of issued + certificates." ;; + show-req|show-cert) text=" + show-req [ cmd-opts ] + show-cert [ cmd-opts ] + Shows details of the req or cert referenced by filename_base + + Human-readable output is shown, including any requested cert options when + showing a request." + opts=" + full - show full req/cert info, including pubkey/sig data" ;; + show-ca) text=" + show-ca [ cmd-opts ] + Shows details of the CA cert + + Human-readable output is shown." + opts=" + full - show full cert info, including pubkey/sig data" ;; + show-crl) text=" + show-crl + Shows details of the current certificate revocation list (CRL) + + Human-readable output is shown." ;; + show-expire) text=" + show-expire [ cmd-opts ] + Shows details of expiring certificates + + Human-readable output is shown." ;; + show-revoke) text=" + show-revoke [ cmd-opts ] + Shows details of revoked certificates + + Human-readable output is shown." ;; + show-renew) text=" + show-renew [ cmd-opts ] + Shows details of renewed certificates, which have not been revoked + + Human-readable output is shown." ;; + verify) text=" + verify [ cmd-opts ] + Verify certificate against CA" + opts=" + batch - On failure to verify, return error (1) to calling program" ;; + import-req) text=" + import-req + Import a certificate request from a file + + This will copy the specified file into the reqs/ dir in + preparation for signing. + The is the filename base to create. + + Example usage: + import-req /some/where/bob_request.req bob" ;; + export-p12) text=" + export-p12 [ cmd-opts ] + Export a PKCS#12 file with the keypair specified by " + opts=" + nopass - use no password and leave the key unencrypted + noca - do not include the ca.crt file in the PKCS12 output + nokey - do not include the private key in the PKCS12 output + usefn - use as friendly name" ;; + export-p7) text=" + export-p7 [ cmd-opts ] + Export a PKCS#7 file with the pubkey specified by " + opts=" + noca - do not include the ca.crt file in the PKCS7 output" ;; + export-p8) text=" + export-p8 [ cmd-opts ] + Export a PKCS#8 file with the private key specified by " + opts=" + nopass - do not encrypt the private key (default is encrypted)" ;; + export-p1) text=" + export-p1 [ cmd-opts ] + Export a PKCS#1 (RSA format) file with the pubkey specified by " + opts=" + nopass - do not encrypt the private key (default is encrypted)" ;; + set-rsa-pass|set-ec-pass) text=" + set-rsa-pass [ cmd-opts ] + set-ec-pass [ cmd-opts ] + Set a new passphrase on an RSA or EC key for the listed ." + opts=" + nopass - use no password and leave the key unencrypted + file - (advanced) treat the file as a raw path, not a short-name" ;; + upgrade) text=" + upgrade + Upgrade EasyRSA PKI and/or CA. must be one of: + pki - Upgrade EasyRSA v2.x PKI to EasyRSA v3.x PKI (includes CA below) + ca - Upgrade EasyRSA v3.0.5 CA or older to EasyRSA v3.0.6 CA or later." ;; + altname|subjectaltname|san) text=" + --subject-alt-name=SAN_FORMAT_STRING + This global option adds a subjectAltName to the request or issued + certificate. It MUST be in a valid format accepted by openssl or + req/cert generation will fail. Note that including multiple such names + requires them to be comma-separated; further invocations of this + option will REPLACE the value. + + Examples of the SAN_FORMAT_STRING shown below: + DNS:alternate.example.net + DNS:primary.example.net,DNS:alternate.example.net + IP:203.0.113.29 + email:alternate@example.net" ;; + options) + opt_usage ;; + "") + usage ;; + *) text=" + Unknown command: '$1' (try without commands for a list of commands)" + esac + + # display the help text + [ "$text" ] && print "$text" + [ -n "$opts" ] && print " + cmd-opts is an optional set of command options from this list: +$opts +" +} # => cmd_help() + +# Options usage +opt_usage() { + print " +Easy-RSA Global Option Flags + +The following options may be provided before the command. Options specified +at runtime override env-vars and any 'vars' file in use. Unless noted, +non-empty values to options are mandatory. + +General options: + +--batch : set automatic (no-prompts when possible) mode +--silent : Disable all Warnings and Notices +--sbatch : Combined --silent and --batch operating mode + +--passin=ARG : set -passin ARG for openssl +--passout=ARG : set -passout ARG for openssl +--ssl-conf=FILE : define a specific OpenSSL config file for Easy-RSA to use + +--vars=FILE : define a specific 'vars' file to use for Easy-RSA config + Can be used with everything, except 'init-pki' +--pki-dir=DIR : declare the PKI directory + Use this for 'init-pki', not '--vars' above. + +--tmp-dir=DIR : declare the temporary directory +--version : prints EasyRSA version and build information, then exits + +Certificate & Request options: (these impact cert/req field values) + +--days=# : sets the signing validity to the specified number of days +--renew-days=# : Number of days grace period before allowing renewal +--fix-offset=# : Generate certificate with fixed start and end dates. + : Range 1 to 365 + : start date: 01 January 00:00:00 of the current year + : end date: off-set days 01:00:00 of the final year + : Final year is configured via --days (Default: 825 days, 2 years) + +--digest=ALG : digest to use in the requests & certificates +--dn-mode=MODE : DN mode to use (cn_only or org) +--keysize=# : size in bits of keypair to generate +--req-cn=NAME : default CN to use +--subca-len=# : path length of signed intermediate CA certs; must be >= 0 if used +--subject-alt-name +--san : Add a subjectAltName. + : For more info and syntax, see: 'easyrsa help altname' +--use-algo=ALG : crypto alg to use: choose rsa (default), ec or ed +--curve=NAME : for elliptic curve, sets the named curve to use +--copy-ext : Copy included request X509 extensions (namely subjAltName) + +Organizational DN options: (only used with the 'org' DN mode) + (values may be blank for org DN options) + +--req-c=CC : country code (2-letters) +--req-st=NAME : State/Province +--req-city=NAME : City/Locality +--req-org=NAME : Organization +--req-email=NAME : Email addresses +--req-ou=NAME : Organizational Unit + +Deprecated features: + +--ns-cert=YES/NO : yes or no to including deprecated NS extensions +--ns-comment=COMMENT : NS comment to include (value may be blank) +" +} # => opt_usage() + +# Wrapper around printf - clobber print since it's not POSIX anyway +# print() is used internally, so MUST NOT be silenced. +# shellcheck disable=SC1117 +print() { printf "%s\n" "$*" || exit 1; } + +# Exit fatally with a message to stderr +# present even with EASYRSA_BATCH as these are fatal problems +die() { + # If renew failed then restore cert, key and req. Otherwise, issue a warning + # If *restore* fails then at least the file-names are not serial-numbers + [ "$restore_failed_renew" ] && renew_restore_move + print " +Easy-RSA error: + +$1" 1>&2 + + print " +Host: $host_out${EASYRSA_DEBUG+ +*** Disable EASYRSA_DEBUG mode ***}" + + exit "${2:-1}" +} # => die() + +# non-fatal warning output +warn() { + [ "$EASYRSA_SILENT" ] && return + print "* WARNING: + +$1 +" 1>&2 +} # => warn() + +# informational notices to stdout +notice() { + [ "$EASYRSA_SILENT" ] && return + [ "$EASYRSA_BATCH" ] && return + print "* Notice: +$1 +" +} # => notice() + +# yes/no case-insensitive match (operates on stdin pipe) +# Returns 0 when input contains yes, 1 for no, 2 for no match +# If both strings are present, returns 1; first matching line returns. +awk_yesno() { + # shellcheck disable=SC2016 # vars don't expand in single quotes + awkscript=' +BEGIN {IGNORECASE=1; r=2} +{ if(match($0,"no")) {r=1; exit} + if(match($0,"yes")) {r=0; exit} +} END {exit r}' + awk "$awkscript" +} # => awk_yesno() + +# intent confirmation helper func +# returns without prompting in EASYRSA_BATCH +confirm() { + [ "$EASYRSA_BATCH" ] && return + prompt="$1" + value="$2" + msg="$3" + input="" + print " +$msg + +Type the word '$value' to continue, or any other input to abort." + printf %s " $prompt" + # shellcheck disable=SC2162 # read without -r will mangle backslashes + read input + printf '\n' + [ "$input" = "$value" ] && return + notice "Aborting without confirmation." + exit 9 +} # => confirm() + +# Create session directory atomically or fail +secure_session() { + # Session is already defined + [ "$EASYRSA_TEMP_DIR_session" ] && die "session overload" + + # temporary directory must exist + if [ "$EASYRSA_TEMP_DIR" ] && [ -d "$EASYRSA_TEMP_DIR" ]; then + : # ok + else + die "Non-existant temporary directory: $EASYRSA_TEMP_DIR" + fi + + for i in 1 2 3; do + # Always use openssl directly for rand + rand="$( + "$EASYRSA_OPENSSL" rand -hex 4 + )" || die "secure_session - rand '$rand'" + + mkdir "${EASYRSA_TEMP_DIR}/${rand}" || continue + EASYRSA_TEMP_DIR_session="${EASYRSA_TEMP_DIR}/${rand}" + return + done + return 1 +} # => secure_session() + +# Create tempfile atomically or fail +easyrsa_mktemp() { + # session directory must exist + if [ "$EASYRSA_TEMP_DIR_session" ] && [ -d "$EASYRSA_TEMP_DIR_session" ]; then + : # ok + else + die "Non-existant temporary session: $EASYRSA_TEMP_DIR_session" + fi + + for i in 1 2 3; do + # Always use openssl directly for rand + rand="$( + "$EASYRSA_OPENSSL" rand -hex 4 + )" || die "easyrsa_mktemp - rand '$rand'" + + shotfile="${EASYRSA_TEMP_DIR_session}/shot.$rand" + if [ -e "$shotfile" ]; then + continue + else + printf "" > "$shotfile" || continue + fi + + tempfile="${EASYRSA_TEMP_DIR_session}/temp.$rand" + mv "$shotfile" "$tempfile" || continue + printf '%s\n' "$tempfile" || die "easyrsa_mktemp - write temp" + return + done + return 1 +} # => easyrsa_mktemp() + +# remove temp files and do terminal cleanups +cleanup() { + if [ "${EASYRSA_TEMP_DIR_session%/*}" ] && [ -d "$EASYRSA_TEMP_DIR_session" ] + then + rm -rf "$EASYRSA_TEMP_DIR_session" + fi + + if [ "${EASYRSA_EC_DIR%/*}" ] && [ -d "$EASYRSA_EC_DIR" ] + then + rm -rf "$EASYRSA_EC_DIR" + fi + + # shellcheck disable=SC3040 # In POSIX sh, set option [name] is undefined + case "$easyrsa_host_os" in + nix) [ -t 1 ] && stty echo ;; + win) + if [ "$easyrsa_win_git_bash" ]; then + [ -t 1 ] && stty echo + else + set -o echo + fi + ;; + *) warn "Host OS undefined." + esac + + # Exit with error 1, if an error ocured... + if [ "$easyrsa_error_exit" ]; then + # Set by verify_cert() for full error-out + exit 1 + elif [ "$1" = ok ]; then + # if there is no error then 'cleanup ok' is called + exit 0 + else + # if 'cleanup' is called without 'ok' then an error occurred + [ "$EASYRSA_SILENT" ] || echo "" # just to get a clean line + exit 1 + fi +} # => cleanup() + +# Easy-RSA meta-wrapper for SSL +easyrsa_openssl() { + openssl_command="$1"; shift + + # Do not allow 'rand' here because it interferes with EASYRSA_DEBUG + case "$openssl_command" in + rand) die "easyrsa_openssl: Illegal SSL command: rand" ;; + makesafeconf) has_config=1 ;; + ca|req|srp|ts) has_config=1 ;; + *) unset -v has_config + esac + + # OpenSSL 1x genpkey does not support -config - Not as documented: + # https://www.openssl.org/docs/manmaster/man1/openssl-genpkey.html + if [ "$osslv_major" = 3 ] && [ "$openssl_command" = genpkey ]; then + has_config=1 + fi + + if [ "$has_config" ]; then + # Make LibreSSL safe config file from OpenSSL config file + + # Do not use easyrsa_mktemp() for init-pki + # LibreSSL cannot generate random without a PKI and safe-conf + if [ "$no_pki_required" ]; then + # for init-pki $EASYRSA_SAFE_CONF is always set in the PKI, use it. + easyrsa_openssl_conf="${EASYRSA_SAFE_CONF}.init-tmp" + else + easyrsa_openssl_conf="$(easyrsa_mktemp)" || \ + die "easyrsa_openssl - Failed to create temporary file" + fi + + # OpenSSL does not require a safe config, so skip to the copy + # require_safe_ssl_conf is set by verify_ssl_lib() + if [ "$require_safe_ssl_conf" ]; then + # Make a safe SSL config file + sed \ + -e "s\`ENV::EASYRSA\`EASYRSA\`g" \ + -e "s\`\$dir\`$EASYRSA_PKI\`g" \ + -e "s\`\$EASYRSA_PKI\`$EASYRSA_PKI\`g" \ + -e "s\`\$EASYRSA_CERT_EXPIRE\`$EASYRSA_CERT_EXPIRE\`g" \ + -e "s\`\$EASYRSA_CRL_DAYS\`$EASYRSA_CRL_DAYS\`g" \ + -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \ + -e "s\`\$EASYRSA_KEY_SIZE\`$EASYRSA_KEY_SIZE\`g" \ + -e "s\`\$EASYRSA_DN\`$EASYRSA_DN\`g" \ + -e "s\`\$EASYRSA_REQ_COUNTRY\`$EASYRSA_REQ_COUNTRY\`g" \ + -e "s\`\$EASYRSA_REQ_PROVINCE\`$EASYRSA_REQ_PROVINCE\`g" \ + -e "s\`\$EASYRSA_REQ_CITY\`$EASYRSA_REQ_CITY\`g" \ + -e "s\`\$EASYRSA_REQ_ORG\`$EASYRSA_REQ_ORG\`g" \ + -e "s\`\$EASYRSA_REQ_OU\`$EASYRSA_REQ_OU\`g" \ + -e "s\`\$EASYRSA_REQ_CN\`$EASYRSA_REQ_CN\`g" \ + -e "s\`\$EASYRSA_REQ_EMAIL\`$EASYRSA_REQ_EMAIL\`g" \ + "$EASYRSA_SSL_CONF" > "$easyrsa_openssl_conf" || \ + die "easyrsa_openssl - Failed to make temporary config" + else + # Do NOT Make a safe SSL config file + cp -f "$EASYRSA_SSL_CONF" "$easyrsa_openssl_conf" || \ + die "easyrsa_openssl - Failed to copy temporary config" + fi + + if [ "$openssl_command" = "makesafeconf" ]; then + # move temp file to safessl-easyrsa.cnf + mv -f "$easyrsa_openssl_conf" "$EASYRSA_SAFE_CONF" || \ + die "easyrsa_openssl - makesafeconf failed" + else + # debug log on + if [ "$EASYRSA_DEBUG" ]; then set -x; fi + + # Exec SSL with -config temp-file + "$EASYRSA_OPENSSL" "$openssl_command" \ + -config "$easyrsa_openssl_conf" "$@" || return + + # debug log off + if [ "$EASYRSA_DEBUG" ]; then set +x; fi + fi + else + # debug log on + if [ "$EASYRSA_DEBUG" ]; then set -x; fi + + # Exec SSL without -config temp-file + "$EASYRSA_OPENSSL" "$openssl_command" "$@" || return + + # debug log off + if [ "$EASYRSA_DEBUG" ]; then set +x; fi + fi +} # => easyrsa_openssl() + +# Verify the SSL library is functional and establish version dependencies +verify_ssl_lib() { + if [ -z "$EASYRSA_SSL_OK" ]; then + val="$("$EASYRSA_OPENSSL" version)" + case "${val%% *}" in + # OpenSSL does not require a safe config-file + OpenSSL) unset -v require_safe_ssl_conf ;; + LibreSSL) require_safe_ssl_conf=1 ;; + *) die "\ +Missing or invalid OpenSSL +Expected to find openssl command at: $EASYRSA_OPENSSL" + esac + + # Set SSL version dependent $no_password option + osslv_major="${val#* }" + osslv_major="${osslv_major%%.*}" + case "$osslv_major" in + 1) no_password='-nodes' ;; + 2) no_password='-nodes' ;; # LibreSSL Only + 3) no_password='-noenc' ;; + *) die "Unsupported SSL library: $osslv_major" + esac + notice "Using SSL: $EASYRSA_OPENSSL $val" + EASYRSA_SSL_OK=1 + fi + + # Verify EASYRSA_SSL_CONF file exists + [ -f "$EASYRSA_SSL_CONF" ] || die "\ +The OpenSSL config file cannot be found. +Expected location: $EASYRSA_SSL_CONF" +} # => verify_ssl_lib() + +# Basic sanity-check of PKI init and complain if missing +verify_pki_init() { + help_note="Run easyrsa without commands for usage and command help." + + # Check for defined EASYRSA_PKI + [ -n "$EASYRSA_PKI" ] || die "\ +EASYRSA_PKI env-var undefined" + + # check that the pki dir exists + [ -d "$EASYRSA_PKI" ] || die "\ +EASYRSA_PKI does not exist (perhaps you need to run init-pki)? +Expected to find the EASYRSA_PKI at: $EASYRSA_PKI +$help_note" + + # verify expected dirs present: + for i in private reqs; do + [ -d "$EASYRSA_PKI/$i" ] || die "\ +Missing expected directory: $i (perhaps you need to run init-pki?) +$help_note" + done + + # verify ssl lib + verify_ssl_lib + unset -v help_note +} # => verify_pki_init() + +# Verify core CA files present +verify_ca_init() { + # First check the PKI has been initialized + verify_pki_init + + help_note="Run without commands for usage and command help." + + # Verify expected files are present. Allow files to be regular files + # (or symlinks), but also pipes, for flexibility with ca.key + for i in serial index.txt index.txt.attr ca.crt private/ca.key; do + if [ ! -f "$EASYRSA_PKI/$i" ] && [ ! -p "$EASYRSA_PKI/$i" ]; then + [ "$1" = "test" ] && return 1 + die "\ +Missing expected CA file: $i (perhaps you need to run build-ca?) +$help_note" + fi + done + + # When operating in 'test' mode, return success. + # test callers don't care about CA-specific dir structure + [ "$1" = "test" ] && return 0 + + # verify expected CA-specific dirs: + for i in issued certs_by_serial + do + [ -d "$EASYRSA_PKI/$i" ] || die "\ +Missing expected CA dir: $i (perhaps you need to run build-ca?) +$help_note" + done + + # explicitly return success for callers + unset -v help_note + return 0 +} # => verify_ca_init() + +# init-pki backend: +init_pki() { + # Process command options + reset="hard" + while [ -n "$1" ]; do + case "$1" in + hard-reset|hard) reset="hard" ;; + soft-reset|soft) reset="soft" ;; + *) warn "Ignoring unknown command option: '$1'" + esac + shift + done + + # If EASYRSA_PKI exists, confirm before we rm -rf (skipped with EASYRSA_BATCH) + if [ -e "$EASYRSA_PKI" ]; then + confirm "Confirm removal: " "yes" "\ +WARNING!!! + +You are about to remove the EASYRSA_PKI at: +* $EASYRSA_PKI + +and initialize a fresh PKI here." + # now remove it: + case "$reset" in + hard) + rm -rf "$EASYRSA_PKI" || \ + die "Removal of PKI dir failed. Check/correct errors above" + ;; + soft) + for i in ca.crt certs_by_serial ecparams index.txt index.txt.attr \ + index.txt.old issued private reqs serial serial.old; do + rm -rf "${EASYRSA_PKI:?}/$i" || \ + die "Removal of PKI dir failed. Check/correct errors above" + done + ;; + # More modes could be added here, e.g. only remove + # issued certs (and clean database), but keep CA intact. + *) + die "Removal of PKI dir failed. Unknown reset type: $reset" + esac + fi + + # new dirs: + for i in private reqs; do + mkdir -p "$EASYRSA_PKI/$i" || \ + die "Failed to create PKI file structure (permissions?)" + done + + # Install data-files into ALL new PKIs + install_data_to_pki init-pki || \ + warn "Failed to install required data-files to PKI. (init)" + + # Verify that $EASYRSA_SAFE_CONF exists ($OPENSSL_CONF) + # Prevents bogus warnings (especially useful on win32) + if [ -n "$EASYRSA_SAFE_CONF" ] && [ -e "$EASYRSA_SAFE_CONF" ]; then + : # ok + else + die "init-pki failed to create safe SSL conf: $EASYRSA_SAFE_CONF" + fi + + notice "\ + + init-pki complete; you may now create a CA or requests. + + Your newly created PKI dir is: + * $EASYRSA_PKI" + + if [ "$user_vars_true" ]; then + : # ok - No message required + else + notice "\ + IMPORTANT: Easy-RSA 'vars' file has now been moved to your PKI above." + fi +} # => init_pki() + +# Copy data-files from various sources +install_data_to_pki () { +# +# This function will explicitly find and optionally copy data-files to the PKI. +# During 'init-pki' this is the new default. +# During all other functions these requirements are tested for and +# files will be copied to the PKI, if they do not already exist there. +# +# One of the reasons for this change is to make packaging EasyRSA work. +# +# First: search favoured and then common 'areas' for the EasyRSA data-files(A): +# * 'openssl-easyrsa.cnf' and 'x509-types' (folder). +# +# These files MUST be found in at least one location. +# * 'openssl-easyrsa.cnf' will be copied to the PKI. +# A warning will be issued if this file cannot be found. +# +# * 'x509-types' will set EASYRSA_EXT_DIR to the found location. +# If x509-types cannot be found then that is a FATAL error. +# +# Other EasyRSA data-files(B): it is not crucial that these are found +# but if they are then they are copied to the PKI. (Note: 1) +# * 'vars' and 'vars.example' +# +# Note 1: For 'vars' consideration must be given to: +# "Where the user expects to find vars!" +# +# Currently, *if* 'vars' is copied to the PKI then the PKI 'vars' will take +# priority over './vars'. But it will not be updated if './vars' is changed. +# +# Copying 'vars' to the PKI is complicated, code is included but DISABLED. + + context="$1" + shift + + # Set required sources + vars_file='vars' + vars_file_example='vars.example' + ssl_cnf_file='openssl-easyrsa.cnf' + x509_types_dir='x509-types' + + # PWD - Covers EasyRSA-Windows installed by OpenVPN, and git forks + # "prog_dir" - Old way (Who installs data files in /usr/bin ?) + # /etc/easy-rsa - possible default + # /usr/share/easy-rsa - usr + # /usr/local/share/easy-rsa - usr/local + + # Find and copy data-files, in specific order + for area in \ + "$PWD" \ + "${0%/*}" \ + '/etc/easy-rsa' \ + '/usr/share/easy-rsa' \ + '/usr/local/share/easy-rsa' \ + # EOL - # Add more distros here + do + # Omitting "$vars_file" + for source in \ + "$vars_file_example" \ + "$ssl_cnf_file" \ + # EOL - Do x509-types separately + do + # Find each item + [ -e "${area}/${source}" ] || continue + + # If the item does not exist in the PKI then copy it. + if [ -e "${EASYRSA_PKI}/${source}" ]; then + continue + else + cp "${area}/${source}" "$EASYRSA_PKI" || return + fi + done + + # Find x509-types + [ -e "${area}/${x509_types_dir}" ] || continue + + # Declare in preferred order, first wins, beaten by command line. + # Only set if not in PKI; Same condition made in vars_setup() + if [ ! -d "$EASYRSA_PKI/x509-types" ]; then + set_var EASYRSA_EXT_DIR "${area}/${x509_types_dir}" + fi + done + + # if PKI/x509-types exists then it wins, except command line + # Same condition made in vars_setup() + if [ -d "$EASYRSA_PKI/x509-types" ]; then + set_var EASYRSA_EXT_DIR "$EASYRSA_PKI/x509-types" + fi + + # Create PKI/vars from PKI/example + case "$context" in + init-pki) + if [ -e "${EASYRSA_PKI}/${vars_file_example}" ]; then + [ -e "${EASYRSA_PKI}/${vars_file}" ] || \ + cp "${EASYRSA_PKI}/${vars_file_example}" \ + "${EASYRSA_PKI}/${vars_file}" || : + fi + ;; + vars-setup) + if [ "$found_vars" ]; then + : # ok - Do not make a PKI/vars if another vars exists + else + if [ -e "${EASYRSA_PKI}/${vars_file_example}" ]; then + [ -e "${EASYRSA_PKI}/${vars_file}" ] || \ + cp "${EASYRSA_PKI}/${vars_file_example}" \ + "${EASYRSA_PKI}/${vars_file}" || : + fi + fi + ;; + '') + die "install_data_to_pki - unspecified context" ;; + *) + die "install_data_to_pki - unknown context: $context" + esac + + # Check PKI is updated - Omit unnecessary checks + #[ -e "${EASYRSA_PKI}/${vars_file}" ] || return + #[ -e "${EASYRSA_PKI}/${vars_file_example}" ] || return + [ -e "${EASYRSA_PKI}/${ssl_cnf_file}" ] || return + #[ -e "${EASYRSA_PKI}/${x509_types_dir}" ] || return + + # EASYRSA_EXT_DIR must be found! No exceptions! + # The shellcheck warning 2015 is valid, however, this code works correctly. + # Note that A && B || C is not if-then-else. C may run when A is true + # shellcheck disable=SC2015 + [ -n "$EASYRSA_EXT_DIR" ] && [ -e "$EASYRSA_EXT_DIR" ] || \ + die "x509-types folder cannot be found: $EASYRSA_EXT_DIR" + + # Complete or error + [ -e "$EASYRSA_SAFE_CONF" ] || easyrsa_openssl makesafeconf +} # => install_data_to_pki () + +# Disable terminal echo, if possible, otherwise warn +hide_read_pass() +{ + # 3040 - In POSIX sh, set option [name] is undefined + # 3045 - In POSIX sh, some-command-with-flag is undefined + # shellcheck disable=SC3040,SC3045 + if stty -echo 2>/dev/null; then + read -r "$@" + stty echo + elif (set +o echo 2>/dev/null); then + set +o echo + read -r "$@" + set -o echo + elif (echo | read -r -s 2>/dev/null) ; then + read -r -s "$@" + else + warn "Could not disable echo. Password will be shown on screen!" + read -r "$@" + fi +} # => hide_read_pass() + +# build-ca backend: +build_ca() { + cipher="-aes256" + unset -v nopass sub_ca ssl_batch date_stamp x509 + while [ -n "$1" ]; do + case "$1" in + intca) sub_ca=1 ;; + subca) sub_ca=1 ;; + nopass) nopass=1 ;; + *) warn "Ignoring unknown command option: '$1'" + esac + shift + done + + verify_pki_init + + out_key="$EASYRSA_PKI/private/ca.key" + # setup for an intermediate CA + if [ "$sub_ca" ]; then + # Gerate a CSR + out_file="$EASYRSA_PKI/reqs/ca.req" + else + # Gerate a certificate + out_file="$EASYRSA_PKI/ca.crt" + date_stamp=1 + x509=1 + fi + + # If encrypted then create the CA key using AES256 cipher + if [ "$nopass" ]; then + unset -v cipher + else + unset -v no_password + fi + + # Test for existing CA, and complain if already present + if verify_ca_init test; then + die "\ +Unable to create a CA as you already seem to have one set up. +If you intended to start a new CA, run init-pki first." + fi + + # If a private key exists here, a intermediate ca was created but not signed. + # Notify the user and require a signed ca.crt or a init-pki: + [ -f "$out_key" ] && \ + die "\ +A CA private key exists but no ca.crt is found in your PKI dir of: +$EASYRSA_PKI +Refusing to create a new CA keypair as this operation would overwrite your +current CA keypair. If you intended to start a new CA, run init-pki first." + + # create necessary files and dirs: + err_file="Unable to create necessary PKI files (permissions?)" + for i in issued certs_by_serial \ + revoked/certs_by_serial revoked/private_by_serial revoked/reqs_by_serial; + do + mkdir -p "$EASYRSA_PKI/$i" || die "$err_file" + done + printf "" > "$EASYRSA_PKI/index.txt" || die "$err_file" + printf "" > "$EASYRSA_PKI/index.txt.attr" || die "$err_file" + printf '%s\n' "01" > "$EASYRSA_PKI/serial" || die "$err_file" + + # Default CN only when not in global EASYRSA_BATCH mode: + [ "$EASYRSA_BATCH" ] && ssl_batch=1 + [ "$EASYRSA_REQ_CN" = ChangeMe ] && export EASYRSA_REQ_CN="Easy-RSA CA" + + out_key_tmp="$(easyrsa_mktemp)" || die "Failed to create temp-key file" + out_file_tmp="$(easyrsa_mktemp)" || die "Failed to create temp-cert file" + + # Get password from user if necessary + if [ -z "$nopass" ] && { + [ -z "$EASYRSA_PASSOUT" ] || [ -z "$EASYRSA_PASSIN" ] + } + then + out_key_pass_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + echo + printf "Enter New CA Key Passphrase: " + hide_read_pass kpass + echo + printf "Re-Enter New CA Key Passphrase: " + hide_read_pass kpass2 + echo + # shellcheck disable=2154 # var is referenced but not assigned + if [ "$kpass" = "$kpass2" ]; then + printf "%s" "$kpass" > "$out_key_pass_tmp" + else + die "Passphrases do not match." + fi + fi + + # Insert x509-types COMMON and 'ca' and EASYRSA_EXTRA_EXTS, if defined. + # shellcheck disable=SC2016 # vars don't expand in single quote + awkscript=' +{if ( match($0, "^#%CA_X509_TYPES_EXTRA_EXTS%") ) + { while ( getline<"/dev/stdin" ) {print} next } + {print} +}' + + conf_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + { + cat "$EASYRSA_EXT_DIR/ca" "$EASYRSA_EXT_DIR/COMMON" + [ "$EASYRSA_EXTRA_EXTS" ] && print "$EASYRSA_EXTRA_EXTS" + } | \ + awk "$awkscript" "$EASYRSA_SSL_CONF" \ + > "$conf_tmp" \ + || die "Copying X509_TYPES to config file failed" + # Use this new SSL config for the rest of this function + EASYRSA_SSL_CONF="$conf_tmp" + + # Choose SSL Library version (1, 2(LibreSSL) or 3) and build CA + case "$osslv_major" in + + # Version agnostic CA generation + # The only remaining option which is version dependent is -nodes/-noenc + 1|2|3) + # Generate CA Key + case "$EASYRSA_ALGO" in + rsa) + easyrsa_openssl genpkey -algorithm "$EASYRSA_ALGO" \ + -pkeyopt rsa_keygen_bits:"$EASYRSA_ALGO_PARAMS" \ + -out "$out_key_tmp" \ + ${cipher+ "$cipher"} \ + ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \ + ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ + || die "Failed create CA private key" + ;; + ec) + easyrsa_openssl genpkey -paramfile "$EASYRSA_ALGO_PARAMS" \ + -out "$out_key_tmp" \ + ${cipher+ "$cipher"} \ + ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \ + ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ + || die "Failed create CA private key" + ;; + ed) + easyrsa_openssl genpkey -algorithm "$EASYRSA_CURVE" \ + -out "$out_key_tmp" \ + ${cipher+ "$cipher"} \ + ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \ + ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ + || die "Failed create CA private key" + ;; + *) die "Unknown algorithm: $EASYRSA_ALGO" + esac + + # Generate the CA keypair: + # shellcheck disable=SC2086 # Double quote to prevent .. + easyrsa_openssl req -utf8 -new \ + -key "$out_key_tmp" -keyout "$out_key_tmp" \ + -out "$out_file_tmp" \ + ${ssl_batch+ -batch} \ + ${x509+ -x509} \ + ${date_stamp+ -days "$EASYRSA_CA_EXPIRE"} \ + ${EASYRSA_DIGEST+ -"$EASYRSA_DIGEST"} \ + ${no_password+ "$no_password"} \ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \ + ${out_key_pass_tmp:+ -passin file:"$out_key_pass_tmp"} \ + || die "Failed to build the CA" + ;; + *) die "build-ca ssl lib: $osslv_major" + esac + + mv "$out_key_tmp" "$out_key" + mv "$out_file_tmp" "$out_file" + [ -f "$out_key_pass_tmp" ] && rm "$out_key_pass_tmp" + + # Success messages + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + if [ -n "$sub_ca" ]; then + notice "\ + +NOTE: Your intermediate CA request is at $out_file +and now must be sent to your parent CA for signing. Place your resulting cert +at $EASYRSA_PKI/ca.crt prior to signing operations." + else + notice "\ + +CA creation complete and you may now import and sign cert requests. +Your new CA certificate file for publishing is at: +$out_file" + fi +} # => build_ca() + +# gen-dh backend: +gen_dh() { + verify_pki_init + + out_file="$EASYRSA_PKI/dh.pem" + + # check to see if we already have a dh parameters file + if [ -e "$EASYRSA_PKI/dh.pem" ]; then + if [ "$EASYRSA_BATCH" ]; then + # if batch is enabled, die + die "file $EASYRSA_PKI/dh.pem already exists!" + else + # warn the user, give them a chance to force overwrite + confirm "Overwrite? " "yes" "*** File $EASYRSA_PKI/dh.pem already exists! ***" + fi + fi + + "$EASYRSA_OPENSSL" dhparam -out "$out_file" "$EASYRSA_KEY_SIZE" || \ + die "Failed to build DH params" + + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + notice "\ + +DH parameters of size $EASYRSA_KEY_SIZE created at $out_file" + return 0 +} # => gen_dh() + +# gen-req backend: +gen_req() { + # pull filename base and use as default interactive CommonName: + [ -n "$1" ] || die "\ +Error: gen-req must have a file base as the first argument. +Run easyrsa without commands for usage and commands." + key_out="$EASYRSA_PKI/private/$1.key" + req_out="$EASYRSA_PKI/reqs/$1.req" + + # Set the request commonName + EASYRSA_REQ_CN="$1" + shift + + # Require SSL Lib version for 'nopass' -> $no_password + verify_pki_init + + # function opts support + unset -v text nopass ssl_batch + while [ -n "$1" ]; do + case "$1" in + text) text=1 ;; + nopass) nopass=1 ;; + # batch flag supports internal callers needing silent operation + batch) ssl_batch=1 ;; + *) warn "Ignoring unknown command option: '$1'" + esac + shift + done + + # don't wipe out an existing private key without confirmation + [ -f "$key_out" ] && confirm "Confirm key overwrite: " "yes" "\ + +WARNING!!! + +An existing private key was found at $key_out +Continuing with key generation will replace this key." + + # When EASYRSA_EXTRA_EXTS is defined, append it to openssl's [req] section: + if [ -n "$EASYRSA_EXTRA_EXTS" ]; then + # Setup & insert the extra ext data keyed by a magic line + extra_exts=" +req_extensions = req_extra +[ req_extra ] +$EASYRSA_EXTRA_EXTS" + # shellcheck disable=SC2016 # vars don't expand in single quote + awkscript=' +{if ( match($0, "^#%EXTRA_EXTS%") ) + { while ( getline<"/dev/stdin" ) {print} next } + {print} +}' + conf_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + print "$extra_exts" | \ + awk "$awkscript" "$EASYRSA_SSL_CONF" \ + > "$conf_tmp" \ + || die "Copying SSL config to temp file failed" + # Use this new SSL config for the rest of this function + EASYRSA_SSL_CONF="$conf_tmp" + fi + + # Name temp files + key_out_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + req_out_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + + # Set SSL non-interactive mode, otherwise allow full user interaction + if [ "$EASYRSA_BATCH" ] || [ "$ssl_batch" ]; then + ssl_batch=1 + fi + + # Set Edwards curve name or elliptic curve parameters file + algo_opts="" + if [ "ed" = "$EASYRSA_ALGO" ]; then + algo_opts="$EASYRSA_CURVE" + else + algo_opts="$EASYRSA_ALGO:$EASYRSA_ALGO_PARAMS" + fi + + # Generate request + easyrsa_openssl req -utf8 -new -newkey "$algo_opts" \ + -keyout "$key_out_tmp" -out "$req_out_tmp" \ + ${nopass+ "$no_password"} \ + ${text+ -text} \ + ${ssl_batch+ -batch} \ + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \ + || die "Failed to generate request" + mv "$key_out_tmp" "$key_out" + mv "$req_out_tmp" "$req_out" + + notice "\ + +Keypair and certificate request completed. Your files are: +req: $req_out +key: $key_out" + + return 0 +} # => gen_req() + +# common signing backend +sign_req() { + crt_type="$1" + req_in="$EASYRSA_PKI/reqs/$2.req" + crt_out="$EASYRSA_PKI/issued/$2.crt" + + # Get fixed dates by --fix-offset + cert_dates + + # Randomize Serial number + if [ "$EASYRSA_RAND_SN" != "no" ]; + then + i="" + serial="" + check_serial="" + for i in 1 2 3 4 5; do + # Always use openssl directly for rand + "$EASYRSA_OPENSSL" rand -hex -out "$EASYRSA_PKI/serial" 16 \ + || die "sign_req - rand" + + serial="$(cat "$EASYRSA_PKI/serial")" + + # Calls LibreSSL directly with a broken config and still works + check_serial="$( + "$EASYRSA_OPENSSL" ca -config "$EASYRSA_SSL_CONF" \ + -status "$serial" 2>&1 + )" + + case "$check_serial" in + *"not present in db"*) break ;; + *) continue + esac + done + fi + + # Support batch by internal caller: + [ "$3" = "batch" ] && EASYRSA_BATCH=1 + + verify_ca_init + + # Check argument sanity: + [ -n "$2" ] || die "\ +Incorrect number of arguments provided to sign-req: +expected 2, got $# (see command help for usage)" + + # Cert type must exist under the EASYRSA_EXT_DIR + [ -r "$EASYRSA_EXT_DIR/$crt_type" ] || die "\ +Unknown cert type '$crt_type'" + + # Request file must exist + [ -f "$req_in" ] || die "\ +No request found for the input: '$2' +Expected to find the request at: $req_in" + + # Confirm input is a cert req + verify_file req "$req_in" || die "\ +The certificate request file is not in a valid X509 request format. +File Path: $req_in" + + # Display the request subject in an easy-to-read format + # Confirm the user wishes to sign this request + confirm "Confirm request details: " "yes" "\ +You are about to sign the following certificate. +Please check over the details shown below for accuracy. Note that this request +has not been cryptographically verified. Please be sure it came from a trusted +source or that you have verified the request checksum with the sender. + +Request subject, to be signed as a $crt_type certificate for $EASYRSA_CERT_EXPIRE days: + +$(display_dn req "$req_in") +" # => confirm end + + # When EASYRSA_CP_EXT is defined, adjust openssl's [default_ca] section: + if [ -n "$EASYRSA_CP_EXT" ]; then + # Setup & insert the copy_extensions data keyed by a magic line + copy_exts="copy_extensions = copy" + # shellcheck disable=SC2016 # vars don't expand in single quote + awkscript=' +{if ( match($0, "^#%COPY_EXTS%") ) + { while ( getline<"/dev/stdin" ) {print} next } + {print} +}' + conf_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + print "$copy_exts" | \ + awk "$awkscript" "$EASYRSA_SSL_CONF" \ + > "$conf_tmp" \ + || die "Copying SSL config to temp file failed" + # Use this new SSL config for the rest of this function + EASYRSA_SSL_CONF="$conf_tmp" + fi + + # Generate the extensions file for this cert: + ext_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + { + # Append first any COMMON file (if present) then the cert-type extensions + cat "$EASYRSA_EXT_DIR/COMMON" + cat "$EASYRSA_EXT_DIR/$crt_type" + + # Support a dynamic CA path length when present: + [ "$crt_type" = "ca" ] && [ -n "$EASYRSA_SUBCA_LEN" ] && \ + print "basicConstraints = CA:TRUE, pathlen:$EASYRSA_SUBCA_LEN" + + # Deprecated Netscape extension support, if enabled + if print "$EASYRSA_NS_SUPPORT" | awk_yesno; then + [ -n "$EASYRSA_NS_COMMENT" ] && \ + print "nsComment = \"$EASYRSA_NS_COMMENT\"" + case "$crt_type" in + serverClient) print "nsCertType = serverClient" ;; + server) print "nsCertType = server" ;; + client) print "nsCertType = client" ;; + ca) print "nsCertType = sslCA" ;; + *) die "Unknown certificate type: $crt_type" + esac + fi + + # Add user SAN from --subject-alt-name + if [ "$user_san_true" ]; then + print "$EASYRSA_EXTRA_EXTS" + else + # or default server SAN + # If type is server and no subjectAltName was requested, + # add one to the extensions file + if [ "$crt_type" = 'server' ] || [ "$crt_type" = 'serverClient' ]; + then + # req san or default server SAN + san="$(display_san req "$req_in")" + if [ "$san" ]; then + print "subjectAltName = $san" + else + default_server_san "$req_in" + fi + fi + # or externally set EASYRSA_EXTRA_EXTS + # Add any advanced extensions supplied by env-var: + [ -z "$EASYRSA_EXTRA_EXTS" ] || print "$EASYRSA_EXTRA_EXTS" + fi + } > "$ext_tmp" || die "\ +Failed to create temp extension file (bad permissions?) at: +$ext_tmp" + + # sign request + crt_out_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + easyrsa_openssl ca -utf8 -in "$req_in" -out "$crt_out_tmp" \ + -extfile "$ext_tmp" -days "$EASYRSA_CERT_EXPIRE" -batch \ + ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} \ + ${EASYRSA_FIX_OFFSET:+ -startdate "$start_fixdate"} \ + ${EASYRSA_FIX_OFFSET:+ -enddate "$end_fixdate"} \ + || die "signing failed (openssl output above may have more detail)" + + mv "$crt_out_tmp" "$crt_out" + rm -f "$ext_tmp" + + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + unset -v EASYRSA_BATCH # This is why batch mode should not silence output + notice "\ +Certificate created at: $crt_out" + + return 0 +} # => sign_req() + +# common build backend +# used to generate+sign in 1 step +build_full() { + verify_ca_init + + # pull filename base: + [ -n "$2" ] || die "\ +Error: didn't find a file base name as the first argument. +Run easyrsa without commands for usage and commands." + crt_type="$1" name="$2" + req_out="$EASYRSA_PKI/reqs/$2.req" + key_out="$EASYRSA_PKI/private/$2.key" + crt_out="$EASYRSA_PKI/issued/$2.crt" + shift 2 + + # function opts support + while [ -n "$1" ]; do + case "$1" in + nopass) nopass=1 ;; + inline) EASYRSA_INLINE=1 ;; + *) warn "Ignoring unknown command option: '$1'" + esac + shift + done + + # abort on existing req/key/crt files + err_exists="\ +file already exists. Aborting build to avoid overwriting this file. +If you wish to continue, please use a different name or remove the file. +Matching file found at: " + [ -f "$req_out" ] && die "Request $err_exists $req_out" + [ -f "$key_out" ] && die "Key $err_exists $key_out" + [ -f "$crt_out" ] && die "Certificate $err_exists $crt_out" + + # create request + EASYRSA_REQ_CN="$name" + gen_req "$name" batch ${nopass+ nopass} + + # Sign it + ( sign_req "$crt_type" "$name" batch ) || { + rm -f "$req_out" "$key_out" + die "Failed to sign '$name' - See error messages above for details." + } + + # inline it + if [ "$EASYRSA_INLINE" ]; then + inline_file="$EASYRSA_PKI/$EASYRSA_REQ_CN.creds" + if [ -f "$inline_file" ]; then + warn "Inline file exists not over-writing: $inline_file" + else + inline_creds || die "Failed to write inline file: $inline_file" + notice "\ +Inline file created: $inline_file" + fi + fi +} # => build_full() + +# Create inline credentials file for this node +inline_creds () +{ + { + printf "%s\n" "# $crt_type: $EASYRSA_REQ_CN" + printf "%s\n" "" + printf "%s\n" "" + cat "$EASYRSA_PKI/ca.crt" + printf "%s\n" "" + printf "%s\n" "" + printf "%s\n" "" + cat "$crt_out" + printf "%s\n" "" + printf "%s\n" "" + printf "%s\n" "" + cat "$key_out" + printf "%s\n" "" + printf "%s\n" "" + } > "$inline_file" +} # => inline_creds () + +# revoke backend +revoke() { + # pull filename base: + [ "$1" ] || die "\ +Error: didn't find a file base name as the first argument. +Run easyrsa without commands for usage and command help." + + verify_ca_init + + # Assign file_name_base and dust off! + file_name_base="$1" + shift + + in_dir="$EASYRSA_PKI" + crt_in="$in_dir/issued/$file_name_base.crt" + key_in="$in_dir/private/$file_name_base.key" + req_in="$in_dir/reqs/$file_name_base.req" + creds_in="$in_dir/$file_name_base.creds" + + # Assign possible "crl_reason" + if [ "$1" ]; then + crl_reason="$1" + shift + + case "$crl_reason" in + unspecified) : ;; + keyCompromise) : ;; + CACompromise) : ;; + affiliationChanged) : ;; + superseded) : ;; + cessationOfOperation) : ;; + certificateHold) : ;; + *) die "Illegal reason: $crl_reason" + esac + else + unset -v crl_reason + fi + + # Enforce syntax + if [ "$1" ]; then + die "Syntax error: $1" + fi + + # referenced cert must exist: + [ -f "$crt_in" ] || die "\ +Unable to revoke as no certificate was found. Certificate was expected +at: $crt_in" + + # Verify certificate + verify_file x509 "$crt_in" || die "\ +Unable to revoke as the input file is not a valid certificate. Unexpected +input in file: $crt_in" + + # Verify request + if [ -e "$req_in" ] + then + verify_file req "$req_in" || die "\ +Unable to move request. The file is not a valid request. +Unexpected input in file: $req_in" + fi + + # get the serial number of the certificate -> serial=XXXX + cert_serial="$(easyrsa_openssl x509 -in "$crt_in" -noout -serial)" + # remove the serial= part -> we only need the XXXX part + cert_serial="${cert_serial##*=}" + duplicate_crt_by_serial="$EASYRSA_PKI/certs_by_serial/$cert_serial.pem" + + # Set out_dir + out_dir="$EASYRSA_PKI/revoked" + crt_out="$out_dir/certs_by_serial/$cert_serial.crt" + key_out="$out_dir/private_by_serial/$cert_serial.key" + req_out="$out_dir/reqs_by_serial/$cert_serial.req" + + # NEVER over-write a revoked cert, serial number must be unique + deny_msg="\ +Cannot revoke this certificate because a conflicting file exists. +*" + [ -e "$crt_out" ] && die "$deny_msg certificate: $crt_out" + [ -e "$key_out" ] && die "$deny_msg private key: $key_out" + [ -e "$req_out" ] && die "$deny_msg request : $req_out" + unset -v deny_msg + + # confirm operation by displaying DN: + confirm " Continue with revocation: " "yes" "\ + Please confirm you wish to revoke the certificate + with the following subject: + + $(display_dn x509 "$crt_in") + + serial-number: $cert_serial +" # => confirm end + + # Revoke certificate + easyrsa_openssl ca -utf8 -revoke "$crt_in" \ + ${crl_reason+ -crl_reason "$crl_reason"} \ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + || die "Failed to revoke certificate: revocation command failed." + + # move revoked files so we can reissue certificates with the same name + revoke_move + + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + notice "\ + +IMPORTANT!!! + +Revocation was successful. You must run gen-crl and upload a CRL to your +infrastructure in order to prevent the revoked cert from being accepted." + + return 0 +} # => revoke() + +# move-revoked +# moves revoked certificates to the 'revoked' folder +# allows reissuing certificates with the same name +revoke_move() { + # make sure revoked dirs exist + if [ ! -d "$out_dir" ]; then + mkdir -p "$out_dir" || die "Failed to mkdir: $out_dir" + fi + for target in certs_by_serial private_by_serial reqs_by_serial; do + [ -d "$out_dir/$target" ] && continue + mkdir -p "$out_dir/$target" \ + || die "Failed to mkdir: $out_dir/$target" + done + + # move crt, key and req file to renewed_then_revoked folders + mv "$crt_in" "$crt_out" || die "Failed to move: $crt_in" + + # only move the key if we have it + if [ -e "$key_in" ]; then + mv "$key_in" "$key_out" || die "Failed to move: $key_in" + fi + + # only move the req if we have it + if [ -e "$req_in" ]; then + mv "$req_in" "$req_out" || die "Failed to move: $req_in" + fi + + # move any pkcs files + for pkcs in p12 p7b p8 p1; do + if [ -e "$in_dir/issued/$file_name_base.$pkcs" ]; then + # issued + mv "$in_dir/issued/$file_name_base.$pkcs" \ + "$out_dir/certs_by_serial/$cert_serial.$pkcs" \ + || die "Failed to move: $file_name_base.$pkcs" + + elif [ -e "$in_dir/private/$file_name_base.$pkcs" ]; then + # private + mv "$in_dir/private/$file_name_base.$pkcs" \ + "$out_dir/private_by_serial/$cert_serial.$pkcs" \ + || die "Failed to move: $file_name_base.$pkcs" + else + : # ok + fi + done + + # remove the duplicate certificate in the certs_by_serial folder + rm "$duplicate_crt_by_serial" || warn \ + "Failed to remove the duplicate certificate in the certs_by_serial folder" + + # remove credentials file (if exists) + if [ -e "$creds_in" ]; then + confirm "Remove inline file ? " "yes" "An inline file exists. $creds_in" + rm "$creds_in" || warn "Failed to remove the inline file." + fi + + return 0 +} # => move_revoked() + +# renew backend +renew() { + # pull filename base: + [ "$1" ] || die "\ +Error: didn't find a file base name as the first argument. +Run easyrsa without commands for usage and command help." + + verify_ca_init + + # Assign file_name_base and dust off! + file_name_base="$1" + shift + + in_dir="$EASYRSA_PKI" + crt_in="$in_dir/issued/$file_name_base.crt" + key_in="$in_dir/private/$file_name_base.key" + req_in="$in_dir/reqs/$file_name_base.req" + creds_in="$in_dir/$file_name_base.creds" + + # Upgrade CA index.txt.attr - unique_subject = no + up23_upgrade_ca || die "Failed to upgrade CA to support renewal." + + # Set 'nopass' + opt_nopass="" + if [ "$1" ]; then + opt_nopass="$1" + shift + fi + + # Enforce syntax + if [ "$1" ]; then + die "Syntax error: $1" + fi + + # referenced cert must exist: + [ -f "$crt_in" ] || die "\ +Unable to renew as no certificate was found. Certificate was expected +at: $crt_in" + + # Verify certificate + verify_file x509 "$crt_in" || die "\ +Unable to renew as the input file is not a valid certificate. Unexpected +input in file: $crt_in" + + # Verify request + if [ -e "$req_in" ] + then + verify_file req "$req_in" || die "\ +Unable to move request. The file is not a valid request. +Unexpected input in file: $req_in" + fi + + # get the serial number of the certificate -> serial=XXXX + cert_serial="$(easyrsa_openssl x509 -in "$crt_in" -noout -serial)" + # remove the serial= part -> we only need the XXXX part + cert_serial="${cert_serial##*=}" + duplicate_crt_by_serial="$EASYRSA_PKI/certs_by_serial/$cert_serial.pem" + + # Set out_dir + out_dir="$EASYRSA_PKI/renewed" + crt_out="$out_dir/issued/$file_name_base.crt" + key_out="$out_dir/private/$file_name_base.key" + req_out="$out_dir/reqs/$file_name_base.req" + + # NEVER over-write a renewed cert, revoke it first + deny_msg="\ +Cannot renew this certificate because a conflicting file exists. +*" + [ -e "$crt_out" ] && die "$deny_msg certificate: $crt_out" + [ -e "$key_out" ] && die "$deny_msg private key: $key_out" + [ -e "$req_out" ] && die "$deny_msg request : $req_out" + unset -v deny_msg + + # Check if old cert is expired or expires within 30 + cert_dates "$crt_in" + + [ "$expire_date_s" -lt "$allow_renew_date_s" ] || die "\ +Certificate expires in more than $EASYRSA_CERT_RENEW days. +Renewal not allowed." + + # Extract certificate usage from old cert + cert_ext_key_usage="$( + easyrsa_openssl x509 -in "$crt_in" -noout -text | + sed -n "/X509v3 Extended Key Usage:/{n;s/^ *//g;p;}" + )" + + case "$cert_ext_key_usage" in + "TLS Web Client Authentication") + cert_type=client + ;; + "TLS Web Server Authentication") + cert_type=server + ;; + "TLS Web Server Authentication, TLS Web Client Authentication") + cert_type=serverClient + ;; + *) die "Unknown key usage: $cert_ext_key_usage" + esac + + # Use SAN from --subject-alt-name if set else use SAN from old cert + if echo "$EASYRSA_EXTRA_EXTS" | grep -q subjectAltName; then + : # ok - Use current subjectAltName + else + san="$( + easyrsa_openssl x509 -in "$crt_in" -noout -text | sed -n \ + "/X509v3 Subject Alternative Name:/{n;s/IP Address:/IP:/g;s/ //g;p;}" + )" + + [ -n "$san" ] && export EASYRSA_EXTRA_EXTS="\ +$EASYRSA_EXTRA_EXTS +subjectAltName = $san" + fi + + # confirm operation by displaying DN: + confirm " Continue with renewal: " "yes" "\ + Please confirm you wish to renew the certificate + with the following subject: + + $(display_dn x509 "$crt_in") + + serial-number: $cert_serial +" # => confirm end + + # move renewed files so we can reissue certificate with the same name + renew_move + + # Set restore on error flag + restore_failed_renew=1 + + # renew certificate + build_full "$cert_type" "$file_name_base" "$opt_nopass" || die "\ +Failed to renew certificate: renew command failed." + + # Success messages + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + notice "\ + +IMPORTANT!!! + +Renew was successful: + To revoke the old certificate once the new one has been deployed, + use: 'easyrsa revoke-renewed $file_name_base'" + + return 0 +} # => renew() + +# Restore files on failure to renew +renew_restore_move() { + unset -v restore_failed_renew rrm_err + # restore crt, key and req file to PKI folders + if ! mv "$restore_crt_out" "$restore_crt_in"; then + warn "Failed to restore: $restore_crt_out" + rrm_err=1 + fi + + # only restore the key if we have it + if [ -e "$restore_key_out" ]; then + if ! mv "$restore_key_out" "$restore_key_in"; then + warn "Failed to restore: $restore_key_out" + rrm_err=1 + fi + fi + + # only restore the req if we have it + if [ -e "$restore_req_out" ]; then + if ! mv "$restore_req_out" "$restore_req_in"; then + warn "Failed to restore: $restore_req_out" + rrm_err=1 + fi + fi + + # messages + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + if [ "$rrm_err" ]; then + warn "Failed to restore renewed files." + else + notice "Renewed files have been restored." + fi +} # => renew_restore_move() + +# renew_move +# moves renewed certificates to the 'renewed' folder +# allows reissuing certificates with the same name +renew_move() { + # make sure renewed dirs exist + if [ ! -d "$out_dir" ]; then + mkdir -p "$out_dir" || die "Failed to mkdir: $out_dir" + fi + for target in issued private reqs; do + [ -d "$out_dir/$target" ] && continue + mkdir -p "$out_dir/$target" \ + || die "Failed to mkdir: $out_dir/$target" + done + + # move crt, key and req file to renewed folders + restore_crt_in="$crt_in" + restore_crt_out="$crt_out" + mv "$crt_in" "$crt_out" || die "Failed to move: $crt_in" + + # only move the key if we have it + restore_key_in="$key_in" + restore_key_out="$key_out" + if [ -e "$key_in" ]; then + mv "$key_in" "$key_out" || die "Failed to move: $key_in" + fi + + # only move the req if we have it + restore_req_in="$req_in" + restore_req_out="$req_out" + if [ -e "$req_in" ]; then + mv "$req_in" "$req_out" || die "Failed to move: $req_in" + fi + + # remove any pkcs files + for pkcs in p12 p7b p8 p1; do + if [ -e "$in_dir/issued/$file_name_base.$pkcs" ]; then + # issued + rm "$in_dir/issued/$file_name_base.$pkcs" \ + || die "Failed to remove: $file_name_base.$pkcs" + + elif [ -e "$in_dir/private/$file_name_base.$pkcs" ]; then + # private + rm "$in_dir/private/$file_name_base.$pkcs" \ + || die "Failed to remove: $file_name_base.$pkcs" + else + : # ok + fi + done + + # remove the duplicate certificate in the certs_by_serial folder + if [ -e "$duplicate_crt_by_serial" ]; then + rm "$duplicate_crt_by_serial" || warn \ + "Failed to remove the duplicate certificate in the certs_by_serial folder" + fi + + # remove credentials file (if exists) + if [ -e "$creds_in" ]; then + confirm "Remove inline file ? " "yes" "An inline file exists. $creds_in" + rm "$creds_in" || warn "Failed to remove the inline file." + fi + + return 0 +} # => renew_move() + +# revoke-renewed backend +revoke_renewed() { + # pull filename base: + [ "$1" ] || die "\ +Error: didn't find a file base name as the first argument. +Run easyrsa without commands for usage and command help." + + verify_ca_init + + # Assign file_name_base and dust off! + file_name_base="$1" + shift + + in_dir="$EASYRSA_PKI/renewed" + crt_in="$in_dir/issued/$file_name_base.crt" + key_in="$in_dir/private/$file_name_base.key" + req_in="$in_dir/reqs/$file_name_base.req" + #creds_in="$EASYRSA_PKI/$file_name_base.creds" + + # Assign possible "crl_reason" + if [ "$1" ]; then + crl_reason="$1" + shift + + case "$crl_reason" in + unspecified) : ;; + keyCompromise) : ;; + CACompromise) : ;; + affiliationChanged) : ;; + superseded) : ;; + cessationOfOperation) : ;; + certificateHold) : ;; + *) die "Illegal reason: $crl_reason" + esac + else + unset -v crl_reason + fi + + # Enforce syntax + if [ "$1" ]; then + die "Syntax error: $1" + fi + + # referenced cert must exist: + [ -f "$crt_in" ] || die "\ +Unable to revoke as no renewed certificate was found. +Certificate was expected at: $crt_in" + + # Verify certificate + verify_file x509 "$crt_in" || die "\ +Unable to revoke as the input file is not a valid certificate. Unexpected +input in file: $crt_in" + + # Verify request + if [ -e "$req_in" ] + then + verify_file req "$req_in" || die "\ +Unable to move request. The file is not a valid request. +Unexpected input in file: $req_in" + fi + + # get the serial number of the certificate -> serial=XXXX + cert_serial="$(easyrsa_openssl x509 -in "$crt_in" -noout -serial)" \ + || die "renew-revoked - Failed to retrieve certificate serial number" + # remove the serial= part -> we only need the XXXX part + cert_serial="${cert_serial##*=}" + + # output + out_dir="$EASYRSA_PKI/revoked" + crt_out="$out_dir/certs_by_serial/$cert_serial.crt" + key_out="$out_dir/private_by_serial/$cert_serial.key" + req_out="$out_dir/reqs_by_serial/$cert_serial.req" + + # NEVER over-write a revoked cert, serial number must be unique + deny_msg="\ +Cannot revoke this certificate because a conflicting file exists. +*" + [ -e "$crt_out" ] && die "$deny_msg certificate: $crt_out" + [ -e "$key_out" ] && die "$deny_msg private key: $key_out" + [ -e "$req_out" ] && die "$deny_msg request : $req_out" + unset -v deny_msg + + # confirm operation by displaying DN: + confirm " Continue with revocation: " "yes" "\ + Please confirm you wish to revoke the renewed certificate + with the following subject: + + $(display_dn x509 "$crt_in") + + serial-number: $cert_serial +" # => confirm end + + # Revoke the old (already renewed) certificate + easyrsa_openssl ca -utf8 -revoke "$crt_in" \ + ${crl_reason:+ -crl_reason "$crl_reason"} \ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + || die "Failed to revoke renewed certificate: revocation command failed." + + # move revoked files + revoke_renewed_move + + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + notice "\ + +IMPORTANT!!! + +Revocation was successful. You must run gen-crl and upload a CRL to your +infrastructure in order to prevent the revoked renewed cert from being accepted. +" # => notice end + + return 0 +} # => revoke_renewed() + +# move-renewed-revoked +# moves renewed then revoked certificates to the 'revoked' folder +revoke_renewed_move() { + # make sure revoked dirs exist + if [ ! -d "$out_dir" ]; then + mkdir -p "$out_dir" || die "Failed to mkdir: $out_dir" + fi + for target in certs_by_serial private_by_serial reqs_by_serial; do + [ -d "$out_dir/$target" ] && continue + mkdir -p "$out_dir/$target" \ + || die "Failed to mkdir: $out_dir/$target" + done + + # move crt, key and req file to renewed_then_revoked folders + mv "$crt_in" "$crt_out" || die "Failed to move: $crt_in" + + # only move the key if we have it + if [ -e "$key_in" ]; then + mv "$key_in" "$key_out" || die "Failed to move: $key_in" + fi + + # only move the req if we have it + if [ -e "$req_in" ]; then + mv "$req_in" "$req_out" || die "Failed to move: $req_in" + fi + + # move any pkcs files + for pkcs in p12 p7b p8 p1; do + if [ -e "$in_dir/issued/$file_name_base.$pkcs" ]; then + # issued + mv "$in_dir/issued/$file_name_base.$pkcs" \ + "$out_dir/certs_by_serial/$cert_serial.$pkcs" \ + || die "Failed to move: $file_name_base.$pkcs" + + elif [ -e "$in_dir/private/$file_name_base.$pkcs" ]; then + # private + mv "$in_dir/private/$file_name_base.$pkcs" \ + "$out_dir/private_by_serial/$cert_serial.$pkcs" \ + || die "Failed to move: $file_name_base.$pkcs" + else + : # ok + fi + done + + return 0 +} # => revoke_renewed_move() + +# renewable backend +renewable() { + verify_ca_init + + in_dir="$EASYRSA_PKI" + MATCH=$(echo "$*" | sed -re 's/\s+/|/g') + DATE=$(date --date \ + "+${EASYRSA_CERT_RENEW} days" \ + +"%y%m%d%H%M%S") + { awkscript=$(cat) ; } < renewable + +# Set certificate expire date, renew date and variables needed for fixdate +cert_dates() { + if [ -e "$1" ]; then + # Required for renewal + # Call openssl directly, otherwise this is not debug compatible + crt_not_before="$("$EASYRSA_OPENSSL" x509 -in "$1" -noout -startdate 2>&1)" \ + || die "cert_dates - crt_not_before: $crt_not_before" + crt_not_before="${crt_not_before#*=}" + crt_not_after="$("$EASYRSA_OPENSSL" x509 -in "$1" -noout -enddate 2>&1)" \ + || die "cert_dates - crt_not_after: $crt_not_after" + crt_not_after="${crt_not_after#*=}" + shift + elif [ "$1" ]; then + # Required for status + crt_not_after="$1" + else + # Required for --fix-offset + # This is a fake date to satisfy the 'if expire_date_s' command test + crt_not_after="Jun 12 02:02:02 1999 GMT" + fi + + # Set fixed dates for new certificate + case "$EASYRSA_FIX_OFFSET" in + '') : ;; # empty ok + *[!1234567890]*|0*) die "\ +Non-decimal value for EASYRSA_FIX_OFFSET: '$EASYRSA_FIX_OFFSET'" + ;; + *) + # Check offset range + if [ 1 -gt "$EASYRSA_FIX_OFFSET" ] || [ 365 -lt "$EASYRSA_FIX_OFFSET" ] + then + die "Fixed off-set out of range [1-365 days]: $EASYRSA_FIX_OFFSET" + fi + + # initialise fixed dates + unset -v start_fixdate end_fixdate + + # Number of years from default (2 years) plus fixed offset + fix_days="$(( (EASYRSA_CERT_EXPIRE / 365) * 365 + EASYRSA_FIX_OFFSET ))" + + # Current Year and seconds + this_year="$(date +%Y)" || die "cert_dates - this_year" + now_sec="$(date +%s)" || die "cert_dates - now_sec" + esac + + # OS dependencies + case "$easyrsa_uname" in + "Darwin"|*"BSD") + now_sec="$(date -j +%s)" + expire_date="$(date -j -f '%b %d %T %Y %Z' "$crt_not_after")" + expire_date_s="$(date -j -f '%b %d %T %Y %Z' "$crt_not_after" +%s)" + allow_renew_date_s="$(( now_sec + EASYRSA_CERT_RENEW * 86400 ))" + + if [ "$EASYRSA_FIX_OFFSET" ]; then + start_fix_sec="$( + date -j -f '%Y%m%d%H%M%S' "${this_year}0101000000" +%s + )" + end_fix_sec="$(( start_fix_sec + fix_days * 86400 ))" + # Convert to date-stamps for SSL input + start_fixdate="$(date -j -r "$start_fix_sec" +%Y%m%d%H%M%SZ)" + end_fixdate="$(date -j -r "$end_fix_sec" +%Y%m%d%H%M%SZ)" + fi + ;; + *) + # Linux and Windows (FTR: date.exe does not support format +%s as input) + if expire_date_s="$(date -d "$crt_not_after" +%s)" + then + # Note: date.exe is Year 2038 end 32bit + expire_date="$(date -d "$crt_not_after")" + allow_renew_date_s="$(date -d "+${EASYRSA_CERT_RENEW}day" +%s)" + + if [ "$EASYRSA_FIX_OFFSET" ]; then + # New Years Day, this year + New_Year_day="$( + date -d "${this_year}-01-01 00:00:00Z" '+%Y-%m-%d %H:%M:%SZ' + )" + # Convert to date-stamps for SSL input + start_fixdate="$( + date -d "$New_Year_day" +%Y%m%d%H%M%SZ + )" + end_fixdate="$( + date -d "$New_Year_day +${fix_days}days" +%Y%m%d%H%M%SZ + )" + end_fix_sec="$( + date -d "$New_Year_day +${fix_days}days" +%s + )" + fi + + # Alpine Linux and busybox + elif expire_date_s="$(date -D "%b %e %H:%M:%S %Y" -d "$crt_not_after" +%s)" + then + expire_date="$(date -D "%b %e %H:%M:%S %Y" -d "$crt_not_after")" + allow_renew_date_s="$(( now_sec + EASYRSA_CERT_RENEW * 86400 ))" + + if [ "$EASYRSA_FIX_OFFSET" ]; then + start_fix_sec="$(date -d "${this_year}01010000.00" +%s)" + end_fix_sec="$(( start_fix_sec + fix_days * 86400 ))" + # Convert to date-stamps for SSL input + start_fixdate="$(date -d @"$start_fix_sec" +%Y%m%d%H%M%SZ)" + end_fixdate="$(date -d @"$end_fix_sec" +%Y%m%d%H%M%SZ)" + fi + + # Something else + else + die "Date failed" + fi + esac + + # Do not generate an expired, fixed date certificate + if [ "$EASYRSA_FIX_OFFSET" ]; then + for date_stamp in "${now_sec}" "${end_fix_sec}"; do + case "${date_stamp}" in + ''|*[!1234567890]*|0*) + die "Undefined: '$now_sec', '$end_fix_sec'" + ;; + *) + [ "${#date_stamp}" -eq 10 ] \ + || die "Undefined: $now_sec, $end_fix_sec" + esac + done + [ "$now_sec" -lt "$end_fix_sec" ] || die "\ +The lifetime of the certificate will expire before the date today." + [ "$start_fixdate" ] || die "Undefined: start_fixdate" + [ "$end_fixdate" ] || die "Undefined: end_fixdate" + unset -v crt_not_after + fi +} # => cert_dates() + +# gen-crl backend +gen_crl() { + verify_ca_init + + out_file="$EASYRSA_PKI/crl.pem" + out_file_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + + easyrsa_openssl ca -utf8 -gencrl -out "$out_file_tmp" \ + ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} || die "\ +CRL Generation failed." + + mv "$out_file_tmp" "$out_file" + + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + notice "\ + +An updated CRL has been created. +CRL file: $out_file" + + return 0 +} # => gen_crl() + +# import-req backend +import_req() { + verify_pki_init + + # pull passed paths + in_req="$1" short_name="$2" + out_req="$EASYRSA_PKI/reqs/$2.req" + + [ -n "$short_name" ] || die "\ +Unable to import: incorrect command syntax. +Run easyrsa without commands for usage and command help." + + verify_file req "$in_req" || die "\ +The input file does not appear to be a certificate request. Aborting import. +File Path: $in_req" + + # destination must not exist + [ -f "$out_req" ] && die "\ +Unable to import the request as the destination file already exists. +Please choose a different name for your imported request file. +Existing file at: $out_req" + + # now import it + cp "$in_req" "$out_req" + + notice "\ + +The request has been successfully imported with a short name of: $short_name +You may now use this name to perform signing operations on this request." + + return 0 +} # => import_req() + +# export pkcs#12, pkcs#7, pkcs#8 or pkcs#1 +export_pkcs() { + pkcs_type="$1" + shift + + [ -n "$1" ] || die "\ +Unable to export p12: incorrect command syntax. +Run easyrsa without commands for usage and command help." + + short_name="$1" + crt_in="$EASYRSA_PKI/issued/$1.crt" + key_in="$EASYRSA_PKI/private/$1.key" + crt_ca="$EASYRSA_PKI/ca.crt" + shift + + verify_pki_init + + # opts support + cipher=-aes256 + want_ca=1 + want_key=1 + want_pass=1 + unset -v pkcs_friendly_name + while [ -n "$1" ]; do + case "$1" in + noca) want_ca="" ;; + nokey) want_key="" ;; + nopass) want_pass="" ;; + usefn) pkcs_friendly_name="$short_name" ;; + *) warn "Ignoring unknown command option: '$1'" + esac + shift + done + + pkcs_certfile_path= + if [ "$want_ca" ]; then + verify_file x509 "$crt_ca" || die "\ +Unable to include CA cert in the $pkcs_type output (missing file, or use noca option.) +Missing file expected at: $crt_ca" + pkcs_certfile_path="$crt_ca" + fi + + # input files must exist + verify_file x509 "$crt_in" || die "\ +Unable to export $pkcs_type for short name '$short_name' without the certificate. +Missing cert expected at: $crt_in" + + # For 'nopass' PKCS requires an explicit empty password 'pass:' + if [ -z "$want_pass" ]; then + EASYRSA_PASSIN=pass: + EASYRSA_PASSOUT=pass: + unset -v cipher # pkcs#1 only + fi + + case "$pkcs_type" in + p12) + pkcs_out="$EASYRSA_PKI/private/$short_name.p12" + + if [ "$want_key" ]; then + [ -f "$key_in" ] || die "\ +Unable to export p12 for short name '$short_name' without the key +(if you want a p12 without the private key, use nokey option.) +Missing key expected at: $key_in" + else + nokeys=1 + fi + + # export the p12: + easyrsa_openssl pkcs12 -in "$crt_in" -inkey "$key_in" -export \ + -out "$pkcs_out" \ + ${nokeys:+ -nokeys} \ + ${pkcs_certfile_path:+ -certfile "$pkcs_certfile_path"} \ + ${pkcs_friendly_name:+ -name "$pkcs_friendly_name"} \ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \ + || die "Failed to export PKCS#12" + ;; + p7) + pkcs_out="$EASYRSA_PKI/issued/$short_name.p7b" + + # export the p7: + easyrsa_openssl crl2pkcs7 -nocrl -certfile "$crt_in" \ + -out "$pkcs_out" \ + ${pkcs_certfile_path:+ -certfile "$pkcs_certfile_path"} \ + || die "Failed to export PKCS#7" + ;; + p8) + pkcs_out="$EASYRSA_PKI/private/$short_name.p8" + + # export the p8: + easyrsa_openssl pkcs8 -in "$key_in" -topk8 \ + -out "$pkcs_out" \ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \ + || die "Failed to export PKCS#8" + ;; + p1) + pkcs_out="$EASYRSA_PKI/private/$short_name.p1" + + # export the p1: + easyrsa_openssl rsa -in "$key_in" \ + -out "$pkcs_out" \ + ${cipher:+ "$cipher"} \ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \ + || die "Failed to export PKCS#1" + ;; + *) die "Unknown PKCS type: $pkcs_type" + esac + + notice "\ + +Successful export of $pkcs_type file. Your exported file is at the following +location: $pkcs_out" + + return 0 +} # => export_pkcs() + +# set-pass backend +set_pass() { + verify_pki_init + + # key type, supplied internally from frontend command call (rsa/ec) + key_type="$1" + + # values supplied by the user: + raw_file="$2" + file="$EASYRSA_PKI/private/$raw_file.key" + [ -n "$raw_file" ] || die "\ +Missing argument to 'set-$key_type-pass' command: no name/file supplied. +See help output for usage details." + + # parse command options + shift 2 + cipher="-aes256" + unset nopass + while [ -n "$1" ]; do + case "$1" in + nopass) nopass=1 ;; + file) file="$raw_file" ;; + *) warn "Ignoring unknown command option: '$1'" + esac + shift + done + + # If nopass then do not encrypt else encrypt with password. + if [ "$nopass" ]; then + unset -v cipher + else + unset -v no_password + fi + + [ -f "$file" ] || die "\ +Missing private key: expected to find the private key component at: +$file" + + notice "\ +If the key is currently encrypted you must supply the decryption passphrase. +${crypto:+You will then enter a new PEM passphrase for this key.$NL}" + + # Set password + out_key_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + easyrsa_openssl "$key_type" -in "$file" -out "$out_key_tmp" \ + ${cipher:+ "$cipher"} \ + ${no_password:+ "$no_password"} \ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} || die "\ +Failed to change the private key passphrase. See above for possible openssl +error messages." + + mv "$out_key_tmp" "$file" || die "\ +Failed to change the private key passphrase. See above for error messages." + + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + notice "Key passphrase successfully changed" + + return 0 +} # => set_pass() + +# update-db backend +update_db() { + verify_ca_init + + easyrsa_openssl ca -utf8 -updatedb \ + ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} || die "\ +Failed to perform update-db: see above for related openssl errors." + + return 0 +} # => update_db() + +# Display subjectAltName +display_san() { + format="$1" path="$2" + + if echo "$EASYRSA_EXTRA_EXTS" | grep -q subjectAltName; then + print "$(echo "$EASYRSA_EXTRA_EXTS" | grep subjectAltName | + sed 's/^\s*subjectAltName\s*=\s*//')" + else + san="$( + x509v3san="X509v3 Subject Alternative Name:" + "$EASYRSA_OPENSSL" "$format" -in "$path" -noout -text | + sed -n "/${x509v3san}/{n;s/ //g;s/IPAddress:/IP:/g;s/RegisteredID/RID/;p;}" + )" + + [ -n "$san" ] && print "$san" + fi +} # => display_san() + +# display cert DN info on a req/X509, passed by full pathname +display_dn() { + format="$1" path="$2" + name_opts="utf8,sep_multiline,space_eq,lname,align" + print "$( + "$EASYRSA_OPENSSL" "$format" -in "$path" -noout -subject \ + -nameopt "$name_opts" + )" + san="$(display_san "$1" "$2")" + if [ -n "$san" ]; then + print "" + print "X509v3 Subject Alternative Name:" + print " $san" + fi +} # => display_dn() + +# generate default SAN from req/X509, passed by full pathname +default_server_san() { + path="$1" + cn="$( + easyrsa_openssl req -in "$path" -noout -subject -nameopt sep_multiline | + awk -F'=' '/^ *CN=/{print $2}' + )" + + if echo "$cn" | grep -E -q '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'; then + print "subjectAltName = IP:$cn" + else + print "subjectAltName = DNS:$cn" + fi +} # => default_server_san() + +# Verify certificate against CA +verify_cert() { + # pull filename base: + [ "$1" ] || die "\ +Error: didn't find a file base name as the first argument. +Run easyrsa without commands for usage and command help." + + verify_ca_init + + # Assign file_name_base and dust off! + file_name_base="$1" + shift + + # function opts support + unset -v exit_with_error + while [ "$1" ]; do + case "$1" in + # batch flag, return status [0/1] to calling program + # Otherwise, exit 0 on successful completion + batch) exit_with_error=1 ;; + *) warn "Ignoring unknown command option: '$1'" + esac + shift + done + + in_dir="$EASYRSA_PKI" + ca_crt="$in_dir/ca.crt" + crt_in="$in_dir/issued/$file_name_base.crt" + + # Cert file must exist + [ -f "$crt_in" ] || die "\ +No certificate found for the input: '$crt_in'" + + # Verify file is a valid cert + verify_file x509 "$crt_in" || die "\ +Input is not a valid certificate: $crt_in" + + # Test and show SSL out + if easyrsa_openssl verify -CAfile "$ca_crt" "$crt_in"; then + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + notice "\ + Certificate name: $file_name_base + Verfication status: GOOD" + # easyrsa_error_exit=1 # Simple 'proof of concept' test + else + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + notice "\ + Certificate name: $file_name_base + Verfication status: FAILED" + # Exit with error (cmd-opt: batch), otherwise terminal msg only + [ "$exit_with_error" ] && easyrsa_error_exit=1 + fi +} # => verify_cert() + +# verify a file seems to be a valid req/X509 +verify_file() { + format="$1" + path="$2" + easyrsa_openssl "$format" -in "$path" -noout 2>/dev/null || return 1 + return 0 +} # => verify_file() + +# show-* command backend +# Prints req/cert details in a readable format +show() { + type="$1" + name="$2" + in_file="" + format="" + [ -n "$name" ] || die "\ +Missing expected filename_base argument. +Run easyrsa without commands for usage help." + shift 2 + + # opts support + type_opts="-${type}opt" + out_opts="no_pubkey,no_sigdump" + name_opts="utf8,sep_multiline,space_eq,lname,align" + while [ -n "$1" ]; do + case "$1" in + full) out_opts= ;; + *) warn "Ignoring unknown command option: '$1'" + esac + shift + done + + # Determine cert/req type (v2) + case "$type" in + cert) + verify_ca_init + in_file="$EASYRSA_PKI/issued/${name}.crt" + format="x509" + ;; + req) + verify_pki_init + in_file="$EASYRSA_PKI/reqs/${name}.req" + format="req" + ;; + crl) + verify_ca_init + in_file="$EASYRSA_PKI/${name}.pem" + format="crl" + unset type_opts out_opts name_opts + ;; + *) die "Unrecognised type: $type" + esac + + # Verify file exists and is of the correct type + [ -f "$in_file" ] || die "\ +No such $type file with a basename of '$name' is present. +Expected to find this file at: +$in_file" + + verify_file "$format" "$in_file" || die "\ +This file is not a valid $type file: +$in_file" + + notice "\ + + Showing $type details for '$name'. + This file is stored at: + * $in_file" + + easyrsa_openssl "$format" -in "$in_file" -noout -text \ + ${type_opts+ "$type_opts" "$out_opts"} \ + ${name_opts+ -nameopt "$name_opts"} \ + || die "\ +OpenSSL failure to process the input" +} # => show() + +# show-ca command backend +# Prints CA cert details in a readable format +show_ca() { + # opts support + out_opts="no_pubkey,no_sigdump" + name_opts="utf8,sep_multiline,space_eq,lname,align" + while [ -n "$1" ]; do + case "$1" in + full) out_opts= ;; + *) warn "Ignoring unknown command option: '$1'" + esac + shift + done + + verify_ca_init + in_file="$EASYRSA_PKI/ca.crt" + format="x509" + + # Verify file exists and is of the correct type + [ -f "$in_file" ] || die "\ +No such $type file with a basename of '$name' is present. +Expected to find this file at: +$in_file" + + verify_file "$format" "$in_file" || die "\ +This file is not a valid $type file: +$in_file" + + notice "\ + + Showing $type details for 'ca'. + This file is stored at: + * $in_file" + + easyrsa_openssl "$format" -in "$in_file" -noout -text \ + -nameopt "$name_opts" -certopt "$out_opts" || die "\ +OpenSSL failure to process the input" +} # => show_ca() + +# Fixed format date +# Build a Windows date.exe compatible input field +build_ff_date_string() { + unset -v ff_date + ff_date="$1" + [ "$ff_date" ] || die "ff_date: '$ff_date'" + yy="${ff_date%???????????}" + ff_date="${ff_date#"$yy"}" + mm="${ff_date%?????????}" + ff_date="${ff_date#"$mm"}" + dd="${ff_date%???????}" + ff_date="${ff_date#"$dd"}" + HH="${ff_date%?????}" + ff_date="${ff_date#"$HH"}" + MM="${ff_date%???}" + ff_date="${ff_date#"$MM"}" + SS="${ff_date%?}" + ff_date="${ff_date#"$SS"}" + TZ="$ff_date" + ff_date="${yy}-${mm}-${dd} ${HH}:${MM}:${SS}${TZ}" +} # => build_date_string() + +# SC2295: (info): Expansions inside ${..} need to be quoted separately, +# otherwise they match as patterns. (what-ever that means .. ;-) +# Unfortunately, Windows sh.exe has an absolutely ridiculous bug. +# Try this in sh.exe: t=' '; s="a${t}b${t}c"; echo "${s%%"${t}"*}" + +# Read db +# shellcheck disable=SC2295 +read_db() { + report="$1"; shift + + tab_char=' ' + db_in="$EASYRSA_PKI/index.txt" + while read -r db_status db_notAfter db_record; do + + # Interpret the db/certificate record + unset -v db_serial db_cn db_revoke_date db_reason + case "$db_status" in + V) # Valid + db_serial="${db_record%%${tab_char}*}" + db_record="${db_record#*${tab_char}}" + db_cn="${db_record#*/CN=}"; db_cn="${db_cn%%/*}" + crt_file="$EASYRSA_PKI/issued/$db_cn.crt" + ;; + R) # Revoked + db_revoke_date="${db_record%%${tab_char}*}" + db_reason="${db_revoke_date#*,}" + if [ "$db_reason" = "$db_revoke_date" ]; then + db_reason="None given" + else + db_revoke_date="${db_revoke_date%,*}" + fi + db_record="${db_record#*${tab_char}}" + + db_serial="${db_record%%${tab_char}*}" + db_record="${db_record#*${tab_char}}" + db_cn="${db_record#*/CN=}"; db_cn="${db_cn%%/*}" + ;; + *) die "Unexpected status: $db_status" + esac + + # Output selected status report for this record + case "$report" in + expire) # Certs which expire before EASYRSA_CERT_RENEW days + if [ "$db_status" = V ]; then expire_status; fi + ;; + revoke) # Certs which have been revoked + if [ "$db_status" = R ]; then revoke_status; fi + ;; + renew) # Certs which have been renewed but not revoked + if [ "$db_status" = V ]; then renew_status; fi + ;; + *) die "Unrecognised report: $report" + esac + done < "$db_in" +} # => read_db() + +# Expire status +expire_status() { + crt_file="$EASYRSA_PKI/issued/$db_cn.crt" + if [ -e "$crt_file" ]; then + # Use cert date + cert_dates "$crt_file" + else + # Translate db date to usable date + build_ff_date_string "$db_notAfter" + db_notAfter="$ff_date" + # Use db translated date + cert_dates "$db_notAfter" + fi + + if [ "$expire_date_s" -lt "$allow_renew_date_s" ]; then + # Cert expires in less than grace period + printf '%s%s\n' "$db_status | Serial: $db_serial | " \ + "Expires: $expire_date | CN: $db_cn" + fi +} # => expire_status() + +# Revoke status +revoke_status() { + # Translate db date to usable date + build_ff_date_string "$db_revoke_date" + db_revoke_date="$ff_date" + # Use db translated date + # ff db_revoke_date returns db_revoke_date as full expire_date + cert_dates "$db_revoke_date" + crt_revoke_date="$expire_date" + + printf '%s%s\n' "$db_status | Serial: $db_serial | " \ + "Revoked: $crt_revoke_date | Reason: $db_reason | CN: $db_cn" +} # => revoke_status() + +# Renewed status +# renewed certs only remain in the renewed folder until they are revoked +# Only ONE renewed cert with unique CN can exist in the renewed folder +renew_status() { + build_ff_date_string "$db_notAfter" + + # Does a Renewed cert exist ? + crt_file="$EASYRSA_PKI/renewed/issued/${db_cn}.crt" + if [ -e "$crt_file" ]; then + # Use cert date + cert_dates "$crt_file" + + # get the serial number of the certificate -> serial=XXXX + renewed_crt_serial="$(easyrsa_openssl x509 -in "$crt_file" -noout -serial)" + # remove the serial= part -> we only need the XXXX part + renewed_crt_serial="${renewed_crt_serial##*=}" + + # db serial must match certificate serial + if [ "$db_serial" = "$renewed_crt_serial" ]; then + printf '%s%s\n' "$db_status | Serial: $db_serial | " \ + "Expires: $crt_not_after | CN: $db_cn" + else + # Cert is valid, this is the replacement cert from renewal + : # ok - ignore + fi + else + # Cert is valid but no renewed cert exists or it has been revoked + : # ok - ignore + fi +} # => renew_status() + +# cert status reports +status() { + report="$1" + in_crt="$2" + shift 2 + + verify_ca_init + + # This does not build certs, so do not need support for fixed dates + unset -v EASYRSA_FIX_OFFSET + + case "$report" in + expire) + case "$in_crt" in + all) + [ "$EASYRSA_SILENT" ] || print "\ +* Showing certificates which expire in less than $EASYRSA_CERT_RENEW days: +" + read_db expire + ;; + *) print "Coming soon.." + esac + ;; + revoke) + case "$in_crt" in + all) + [ "$EASYRSA_SILENT" ] || print "\ +* Showing certificates which are revoked: +" + read_db revoke + ;; + *) print "Coming soon.." + esac + ;; + renew) + case "$in_crt" in + all) + [ "$EASYRSA_SILENT" ] || print "\ +* Showing certificates which have been renewed but NOT revoked: +" + read_db renew + ;; + *) print "Coming soon.." + esac + ;; + *) warn "Unrecognised report: $report" + esac +} # => status() + +# set_var is not known by shellcheck, therefore: +# Fake declare known variables for shellcheck +# Use these options without this function: +# -o all -e 2250,2244,2248 easyrsa +satisfy_shellcheck() { + die "Security feature enabled!" + # Add more as/if required + + # Enable the heredoc for a peek +#cat << SC2154 + EASYRSA= + EASYRSA_OPENSSL= + EASYRSA_PKI= + EASYRSA_DN= + EASYRSA_REQ_COUNTRY= + EASYRSA_REQ_PROVINCE= + EASYRSA_REQ_CITY= + EASYRSA_REQ_ORG= + EASYRSA_REQ_EMAIL= + EASYRSA_REQ_OU= + EASYRSA_ALGO= + EASYRSA_KEY_SIZE= + EASYRSA_CURVE= + EASYRSA_EC_DIR= + EASYRSA_CA_EXPIRE= + EASYRSA_CERT_EXPIRE= + EASYRSA_CERT_RENEW= + EASYRSA_CRL_DAYS= + EASYRSA_NS_SUPPORT= + EASYRSA_NS_COMMENT= + EASYRSA_TEMP_DIR= + EASYRSA_REQ_CN= + EASYRSA_DIGEST= + + EASYRSA_SSL_CONF= + EASYRSA_SAFE_CONF= + OPENSSL_CONF= + + #EASYRSA_KDC_REALM= + + EASYRSA_RAND_SN= + KSH_VERSION= +#SC2154 + +} # => satisfy_shellcheck() + +# Identify host OS +detect_host() { + unset -v easyrsa_host_os easyrsa_host_test easyrsa_win_git_bash + + # Detect Windows + [ "${OS}" ] && easyrsa_host_test="${OS}" + + # shellcheck disable=SC2016 # expansion inside '' blah + easyrsa_ksh='@(#)MIRBSD KSH R39-w32-beta14 $Date: 2013/06/28 21:28:57 $' + [ "${KSH_VERSION}" = "${easyrsa_ksh}" ] && easyrsa_host_test="${easyrsa_ksh}" + unset -v easyrsa_ksh + + # If not Windows then nix + if [ "${easyrsa_host_test}" ]; then + easyrsa_host_os=win + easyrsa_uname="${easyrsa_host_test}" + easyrsa_shell="$SHELL" + # Detect Windows git/bash + if [ "${EXEPATH}" ]; then + easyrsa_shell="$SHELL (Git)" + easyrsa_win_git_bash="${EXEPATH}" + # If found then set openssl NOW! + [ -e /usr/bin/openssl ] && set_var EASYRSA_OPENSSL /usr/bin/openssl + fi + else + easyrsa_host_os=nix + easyrsa_uname="$(uname 2>/dev/null)" + easyrsa_shell="$SHELL" + fi + host_out="$easyrsa_host_os | $easyrsa_uname | $easyrsa_shell" + host_out="${host_out}${easyrsa_win_git_bash+ | "$easyrsa_win_git_bash"}" + unset -v easyrsa_host_test +} # => detect_host() + +# Verify the selected algorithm parameters +verify_algo_params() { + # EASYRSA_ALGO_PARAMS must be set depending on selected algo + case "$EASYRSA_ALGO" in + rsa) + # Set RSA key size + EASYRSA_ALGO_PARAMS="$EASYRSA_KEY_SIZE" + ;; + ec) + # Verify Elliptic curve + EASYRSA_ALGO_PARAMS="$(easyrsa_mktemp)" + + # Create the required ecparams file + easyrsa_openssl ecparam -name "$EASYRSA_CURVE" \ + -out "$EASYRSA_ALGO_PARAMS" 1>/dev/null || die "\ +Failed to generate ecparam file (permissions?) when writing to: +$EASYRSA_ALGO_PARAMS" + ;; + ed) + # Verify Edwards curve + easyrsa_openssl genpkey -algorithm "$EASYRSA_CURVE" > /dev/null \ + || die "Edwards Curve $EASYRSA_CURVE not found." + ;; + *) die "Alg '$EASYRSA_ALGO' is invalid: must be 'rsa', 'ec' or 'ed'" + esac +} # => verify_algo_params() + +# vars setup +# Here sourcing of 'vars' if present occurs. If not present, defaults are used +# to support running without a sourced config format +vars_setup() { + # Try to locate a 'vars' file in order of location preference. + # If one is found, source it + # NOTE: EASYRSA_PKI is never set here, unless cmd-line --pki-dir=

is set. + # NOTE: EASYRSA is never set here, unless done so outside of easyrsa. + vars= + + # set up program path + prog_file="$0" + # Removed for basic sanity - To re-enable provide a REASON + #prog_file2="$(which -- "$prog_file" 2>/dev/null)" && prog_file="$prog_file2" + #prog_file2="$(readlink -f "$prog_file" 2>/dev/null)" && prog_file="$prog_file2" + prog_dir="${prog_file%/*}" + if [ "$prog_dir" = . ]; then prog_in_pwd=1; else unset -v prog_in_pwd; fi + + # Program dir vars - This location is least wanted. + prog_vars="${prog_dir}/vars" + + # set up PKI path vars - Top preference + pki_vars="${EASYRSA_PKI:-$PWD/pki}/vars" + expected_pki_vars="$pki_vars" + + # Some other place vars, out of scope. + if [ "$EASYRSA" ]; then + easy_vars="${EASYRSA}/vars" + else + unset -v easy_vars + fi + + # vars of last resort - Eventually this file must be removed from EasyRSA + pwd_vars="$PWD/vars" + + # Find vars + # Explicit command-line path: + if [ "$EASYRSA_VARS_FILE" ]; then + if [ -e "$EASYRSA_VARS_FILE" ]; then + vars="$EASYRSA_VARS_FILE" + else + # If the --vars option does not point to a file, show helpful error. + die "The file '$EASYRSA_VARS_FILE' was not found." + fi + unset -v prog_vars pwd_vars easy_vars pki_vars expected_pki_vars + + # Otherwise, find vars 'the new way' followed by 'the old way' .. + else + # if PKI is required + if [ "$no_pki_required" ]; then + : # ok - No vars required either + else + # Clear flags - This is the preferred order to find: + unset -v e_pki_vars e_easy_vars e_pwd_vars e_prog_vars \ + found_vars vars_in_pki + + # PKI location, if present: + [ -e "$pki_vars" ] && e_pki_vars=1 + + # EASYRSA, if defined: + [ -e "$easy_vars" ] && e_easy_vars=1 + + # Eventually the file below must be removed from EasyRSA + # vars of last resort + [ -e "$pwd_vars" ] && e_pwd_vars=1 + + # program location: + [ -e "$prog_vars" ] && e_prog_vars=1 + + # Filter duplicates + if [ "$e_prog_vars" ] && [ "$e_pwd_vars" ] && [ "$prog_in_pwd" ]; then + unset -v prog_vars e_prog_vars + fi + + # Allow only one vars to be found, No exceptions! + found_vars="$((e_pki_vars + e_easy_vars + e_pwd_vars + e_prog_vars))" + + # If found_vars greater than 1 then output user info and exit + case "$found_vars" in + 0) unset -v found_vars ;; + 1) : ;; # ok + *) + [ "$e_pki_vars" ] && print "Found: $pki_vars" + [ "$e_easy_vars" ] && print "Found: $easy_vars" + [ "$e_pwd_vars" ] && print "Found: $pwd_vars" + [ "$e_prog_vars" ] && print "Found: $prog_vars" + die "\ +Conflicting 'vars' files found. + +Priority should be given to your PKI vars file: +* $expected_pki_vars +" + esac + + # If a SINGLE vars file is found then assign $vars + [ "$e_prog_vars" ] && vars="$prog_vars" + [ "$e_pwd_vars" ] && vars="$pwd_vars" + [ "$e_easy_vars" ] && vars="$easy_vars" + [ "$e_pki_vars" ] && vars="$pki_vars" && vars_in_pki=1 + + # Clean up + unset -v prog_vars pwd_vars easy_vars pki_vars + fi + # END: Find vars + fi + + # If $EASYRSA_NO_VARS is defined (not blank) then do not use vars. + # If $no_pki_required then located vars files are not required. + if [ "$EASYRSA_NO_VARS" ] || [ "$no_pki_required" ]; then + : # ok + else + # If a vars file was located then source it + if [ -z "$vars" ]; then + # $vars remains undefined .. no vars found + # install_data_to_pki() will create a default 'PKI/vars' + : # ok + else + # 'vars' now MUST exist + [ -e "$vars" ] || die "Missing vars file, expected: $vars" + + # Sanitize vars + if grep -Eq 'EASYRSA_PASSIN|EASYRSA_PASSOUT' "$vars"; then + die "\ +Variable EASYRSA_PASSIN or EASYRSA_PASSOUT has been found in the configuration +file. Storing sensitive information in the configuration file is not +recommended - please remove it from there before continuing." + fi + + # Sanitize vars further but ONLY if it is in PKI folder + if [ "$vars_in_pki" ]; then + # Warning: Unsupported characters + if grep '^[[:blank:]]*set_var[[:blank:]]\+.*' "$vars" | \ + grep -q -e '&' -e "'" -e '`' -e '\$' -e '#' ; then + warn "\ +Unsupported characters are present in the vars file. +These characters are not supported: (') (&) (\`) (\$) (#) +Sourcing the vars file and building certificates will probably fail .." + fi + fi + + # Enable sourcing 'vars' + # shellcheck disable=SC2034 # EASYRSA_CALLER appears unused. + EASYRSA_CALLER=1 + + # Test souring 'vars' in a subshell + # shellcheck disable=1090 # can't follow non-constant source. vars + ( . "$vars" 2>/dev/null ) || die "\ +Failed to source the vars file, remove any unsupported characters." + + # Source 'vars' now + # shellcheck disable=1090 # can't follow non-constant source. vars + . "$vars" 2>/dev/null + notice "Using Easy-RSA configuration from: $vars" + if [ "$user_vars_true" ]; then + : # ok - No message required + else + [ "$vars_in_pki" ] || \ + warn "\ + Move your vars file to your PKI folder, where it is safe!" + fi + fi + fi + + # Set defaults, preferring existing env-vars if present + set_var EASYRSA "$PWD" + set_var EASYRSA_OPENSSL openssl + set_var EASYRSA_PKI "$EASYRSA/pki" + set_var EASYRSA_DN cn_only + set_var EASYRSA_REQ_COUNTRY "US" + set_var EASYRSA_REQ_PROVINCE "California" + set_var EASYRSA_REQ_CITY "San Francisco" + set_var EASYRSA_REQ_ORG "Copyleft Certificate Co" + set_var EASYRSA_REQ_EMAIL me@example.net + set_var EASYRSA_REQ_OU "My Organizational Unit" + set_var EASYRSA_ALGO rsa + set_var EASYRSA_KEY_SIZE 2048 + set_var EASYRSA_CURVE secp384r1 + set_var EASYRSA_EC_DIR "$EASYRSA_PKI/ecparams" + set_var EASYRSA_CA_EXPIRE 3650 + set_var EASYRSA_CERT_EXPIRE 825 # new default of 36 months + set_var EASYRSA_CERT_RENEW 30 + set_var EASYRSA_CRL_DAYS 180 + set_var EASYRSA_NS_SUPPORT no + set_var EASYRSA_NS_COMMENT "Easy-RSA (3.1.0) Generated Certificate" + set_var EASYRSA_TEMP_DIR "$EASYRSA_PKI" + set_var EASYRSA_REQ_CN ChangeMe + set_var EASYRSA_DIGEST sha256 + + set_var EASYRSA_SSL_CONF "$EASYRSA_PKI/openssl-easyrsa.cnf" + set_var EASYRSA_SAFE_CONF "$EASYRSA_PKI/safessl-easyrsa.cnf" + set_var OPENSSL_CONF "$EASYRSA_SAFE_CONF" + + set_var EASYRSA_KDC_REALM "CHANGEME.EXAMPLE.COM" + + # For commands which 'require a PKI' and the PKI exists + if [ ! "$no_pki_required" ] && [ -d "$EASYRSA_PKI" ]; then + + # Make a safe SSL config for LibreSSL + # Must specify 'no_pki_required' and 'require_safe_ssl_conf' here + # because verify_ssl_lib() has not yet run + # sub-shell out, to change running variables, only the file is required + #( + # no_pki_required=1 + # require_safe_ssl_conf=1 + # easyrsa_openssl makesafeconf + #) || \ + # die "Failed to create safe ssl conf (vars_setup)" + # Alternate version: + no_pki_required=1 require_safe_ssl_conf=1 easyrsa_openssl makesafeconf || \ + die "Failed to create safe ssl conf (vars_setup)" + + # mkdir Temp dir session + secure_session || die "Temporary directory secure-session failed." + + if [ -d "$EASYRSA_TEMP_DIR" ]; then + + #TODO: This should be removed. Not really suitable for packaging. + #set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types" + + # Hard break from 'old' Easy-RSA, see obsolete comment above. + # Install data-files into ALL PKIs + # This will find x509-types and export EASYRSA_EXT_DIR or die. + # Other errors only require warning. + install_data_to_pki vars-setup || \ + warn "Failed to install new required data-dir to PKI. (vars_setup)" + + # export OPENSSL_CONF for OpenSSL, OpenSSL config file MUST exist + # EASYRSA_SAFE_CONF is output by 'install_data_to_pki()' + # via 'easyrsa_openssl() makesafeconf' above. + # Setting EasyRSA specific OPENSSL_CONF to sanatized safe conf + if [ -e "$EASYRSA_SAFE_CONF" ]; then + export OPENSSL_CONF="$EASYRSA_SAFE_CONF" + else + die "Failed to find Safe-SSL config file." + fi + + # Verify selected algorithm and parameters + verify_algo_params + + else + # If the directory does not exist then we have not run init-pki + # The temp-dir is Always created by 'install_data_to_pki' + die "Temporary directory does not exist: $EASYRSA_TEMP_DIR" + fi + fi +} # vars_setup() + +# variable assignment by indirection when undefined; merely exports +# the variable when it is already defined (even if currently null) +# Sets $1 as the value contained in $2 and exports (may be blank) +set_var() { + var=$1 + shift + value="$*" + eval "export $var=\"\${$var-$value}\"" +} #=> set_var() + + + +############################################################################ +# Upgrade v2 PKI to v3 PKI + +# You can report problems on the normal openvpn support channels: +# -------------------------------------------------------------------------- +# 1. The Openvpn Forum: https://forums.openvpn.net/viewforum.php?f=31 +# 2. The #easyrsa IRC channel at libera.chat +# 3. Info: https://community.openvpn.net/openvpn/wiki/easyrsa-upgrade +# -------------------------------------------------------------------------- +# + +up23_fail_upgrade () +{ + # Replace die() + unset EASYRSA_BATCH + notice " +============================================================================ +The update has failed but NOTHING has been lost. + +ERROR: $1 +---------------------------------------------------------------------------- + +Further info: +* https://community.openvpn.net/openvpn/wiki/easyrsa-upgrade#ersa-up23-fails + +Easyrsa3 upgrade FAILED +============================================================================ +" + exit 9 +} #=> up23_fail_upgrade () + +up23_verbose () +{ + [ "$VERBOSE" ] || return 0 + printf "%s\n" "$1" +} #=> up23_verbose () + +up23_verify_new_pki () +{ + # Fail now, before any changes are made + + up23_verbose "> Verify DEFAULT NEW PKI does not exist .." + EASYRSA_NEW_PKI="$EASYRSA/pki" + [ -d "$EASYRSA_NEW_PKI" ] \ + && up23_fail_upgrade "DEFAULT NEW PKI exists: $EASYRSA_NEW_PKI" + + up23_verbose "> Verify VERY-SAFE-PKI does not exist .." + EASYRSA_SAFE_PKI="$EASYRSA/VERY-SAFE-PKI" + [ -d "$EASYRSA_SAFE_PKI" ] \ + && up23_fail_upgrade "VERY-SAFE-PKI exists: $EASYRSA_SAFE_PKI" + + up23_verbose "> Verify openssl-easyrsa.cnf does exist .." + EASYRSA_SSL_CNFFILE="$EASYRSA/openssl-easyrsa.cnf" + [ -f "$EASYRSA_SSL_CNFFILE" ] \ + || up23_fail_upgrade "cannot find $EASYRSA_SSL_CNFFILE" + + up23_verbose "> Verify vars.example does exist .." + EASYRSA_VARSV3_EXMP="$EASYRSA/vars.example" + [ -f "$EASYRSA_VARSV3_EXMP" ] \ + || up23_fail_upgrade "cannot find $EASYRSA_VARSV3_EXMP" + + up23_verbose "> OK" + up23_verbose " Initial dirs & files are in a workable state." +} #=> up23_verify_new_pki () + +# shellcheck disable=SC2154 +up23_verify_current_pki () +{ + up23_verbose "> Verify CURRENT PKI vars .." + + # This can probably be improved + EASYRSA_NO_REM="$(grep '^set ' "$EASYRSA_VER2_VARSFILE")" + + # This list may not be complete + # Not required: DH_KEY_SIZE PKCS11_MODULE_PATH PKCS11_PIN + for i in KEY_DIR KEY_SIZE KEY_COUNTRY KEY_PROVINCE \ + KEY_CITY KEY_ORG KEY_EMAIL KEY_CN KEY_NAME KEY_OU + do + # Effectively, source the v2 vars file + UNIQUE="set $i" + KEY_grep="$(printf "%s\n" "$EASYRSA_NO_REM" | grep "$UNIQUE")" + KEY_value="${KEY_grep##*=}" + set_var $i "$KEY_value" + done + + [ -d "$KEY_DIR" ] || up23_fail_upgrade "Cannot find CURRENT PKI KEY_DIR: $KEY_DIR" + + up23_verbose "> OK" + up23_verbose " Current CURRENT PKI vars uses PKI in: $KEY_DIR" +} #=> up23_verify_current_pki () + +# shellcheck disable=SC2154 +up23_verify_current_ca () +{ + up23_verbose "> Find CA .." + # $KEY_DIR is assigned in up23_verify_current_pki () + [ -f "$KEY_DIR/ca.crt" ] \ + || up23_fail_upgrade "Cannot find current ca.crt: $KEY_DIR/ca.crt" + up23_verbose "> OK" + + # If CA is already verified then return + in_file="$KEY_DIR/ca.crt" + [ "$CURRENT_CA_IS_VERIFIED" = "$in_file" ] && return 0 + format="x509" + + # Current CA is unverified + # Extract the current CA details + name_opts="utf8,sep_multiline,space_eq,lname,align" + CA_SUBJECT="$( + easyrsa_openssl $format -in "$in_file" -subject -noout \ + -nameopt "$name_opts" + )" + + # Extract individual elements + CA_countryName="$(printf "%s\n" "$CA_SUBJECT" \ + | grep countryName | sed "s\`^.*=\ \`\`g")" + CA_stateOrProvinceName="$(printf "%s\n" "$CA_SUBJECT" \ + | grep stateOrProvinceName | sed "s\`^.*=\ \`\`g")" + CA_localityName="$(printf "%s\n" "$CA_SUBJECT" \ + | grep localityName | sed "s\`^.*=\ \`\`g")" + CA_organizationName="$(printf "%s\n" "$CA_SUBJECT" \ + | grep organizationName | sed "s\`^.*=\ \`\`g")" + CA_organizationalUnitName="$(printf "%s\n" "$CA_SUBJECT" \ + | grep organizationalUnitName | sed "s\`^.*=\ \`\`g")" + CA_emailAddress="$(printf "%s\n" "$CA_SUBJECT" \ + | grep emailAddress | sed "s\`^.*=\ \`\`g")" + + # Match the current CA elements to the vars file settings + CA_vars_match=1 + [ "$CA_countryName" = "$KEY_COUNTRY" ] || CA_vars_match=0 + [ "$CA_stateOrProvinceName" = "$KEY_PROVINCE" ] || CA_vars_match=0 + [ "$CA_localityName" = "$KEY_CITY" ] || CA_vars_match=0 + [ "$CA_organizationName" = "$KEY_ORG" ] || CA_vars_match=0 + [ "$CA_organizationalUnitName" = "$KEY_OU" ] || CA_vars_match=0 + [ "$CA_emailAddress" = "$KEY_EMAIL" ] || CA_vars_match=0 + + if [ "$CA_vars_match" -eq 1 ] + then + CURRENT_CA_IS_VERIFIED="partially" + else + up23_fail_upgrade "CA certificate does not match vars file settings" + fi + + opts="-certopt no_pubkey,no_sigdump" + if [ ! "$EASYRSA_BATCH" ] + then + up23_show_current_ca + elif [ "$VERBOSE" ] + then + up23_show_current_ca + fi + confirm "* Confirm CA shown above is correct: " "yes" \ + "Found current CA at: $KEY_DIR/ca.crt" + CURRENT_CA_IS_VERIFIED="$in_file" +} #=> up23_verify_current_ca () + +up23_show_current_ca () +{ + name_opts="utf8,sep_multiline,space_eq,lname,align" + printf "%s\n" "-------------------------------------------------------------------------" + # $opts is always set here + # shellcheck disable=SC2086 # Ignore unquoted variables + easyrsa_openssl $format -in "$in_file" -noout -text \ + -nameopt "$name_opts" $opts || die "\ + OpenSSL failure to process the input CA certificate: $in_file" + printf "%s\n" "-------------------------------------------------------------------------" +} #=> up23_show_current_ca () + +up23_backup_current_pki () +{ + up23_verbose "> Backup current PKI .." + + mkdir -p "$EASYRSA_SAFE_PKI" \ + || up23_fail_upgrade "Failed to create safe PKI dir: $EASYRSA_SAFE_PKI" + + cp -r "$KEY_DIR" "$EASYRSA_SAFE_PKI" \ + || up23_fail_upgrade "Failed to copy $KEY_DIR to $EASYRSA_SAFE_PKI" + + # EASYRSA_VER2_VARSFILE is either version 2 *nix ./vars or Win vars.bat + cp "$EASYRSA_VER2_VARSFILE" "$EASYRSA_SAFE_PKI" \ + || up23_fail_upgrade "Failed to copy $EASYRSA_VER2_VARSFILE to EASYRSA_SAFE_PKI" + + up23_verbose "> OK" + up23_verbose " Current PKI backup created in: $EASYRSA_SAFE_PKI" +} #=> up23_backup_current_pki () + +up23_create_new_pki () +{ + # Dirs: renewed and revoked are created when used. + up23_verbose "> Create NEW PKI .." + up23_verbose ">> Create NEW PKI dirs .." + for i in private reqs issued certs_by_serial + do + mkdir -p "$EASYRSA_PKI/$i" \ + || up23_fail_upgrade "Failed to Create NEW PKI dir: $EASYRSA_PKI/$i" + done + up23_verbose ">> OK" + + up23_verbose ">> Copy database to NEW PKI .." + # Failure for these is not optional + # Files ignored: index.txt.old serial.old + for i in index.txt serial ca.crt index.txt.attr + do + cp "$KEY_DIR/$i" "$EASYRSA_PKI" \ + || up23_fail_upgrade "Failed to copy $KEY_DIR/$i to $EASYRSA_PKI" + done + up23_verbose ">> OK" + + up23_verbose ">> Copy current PKI to NEW PKI .." + for i in "csr.reqs" "pem.certs_by_serial" "crt.issued" "key.private" \ + "p12.private" "p8.private" "p7b.issued" + do + FILE_EXT="${i%%.*}" + DEST_DIR="${i##*.}" + if ls "$KEY_DIR/"*".$FILE_EXT" > /dev/null 2>&1; then + cp "$KEY_DIR/"*".$FILE_EXT" "$EASYRSA_PKI/$DEST_DIR" \ + || up23_fail_upgrade "Failed to copy .$FILE_EXT" + else + up23_verbose " Note: No .$FILE_EXT files found" + fi + done + up23_verbose ">> OK" + up23_verbose "> OK" + + # Todo: CRL - Or generate a new CRL on completion + up23_verbose " New PKI created in: $EASYRSA_PKI" +} #=> up23_create_new_pki () + +up23_upgrade_ca () +{ + [ -d "$EASYRSA_PKI" ] || return 0 + up23_verbose "> Confirm that index.txt.attr exists and 'unique_subject = no'" + if [ -f "$EASYRSA_PKI/index.txt.attr" ] + then + if grep -q 'unique_subject = no' "$EASYRSA_PKI/index.txt.attr" + then + # If index.txt.attr exists and "unique_suject = no" then do nothing + return 0 + fi + else + # If index.txt.attr does not exists then do nothing + return 0 + fi + + # Otherwise this is required for all easyrsa v3 + #confirm "Set 'unique_subject = no' in index.txt.attr for your current CA: " \ + #"yes" "This version of easyrsa requires that 'unique_subject = no' is set correctly" + + printf "%s\n" "unique_subject = no" > "$EASYRSA_PKI/index.txt.attr" + up23_verbose "> OK" + up23_verbose " Upgraded index.txt.attr to v306+" +} #=> up23_upgrade_index_txt_attr () + +up23_create_openssl_cnf () +{ + up23_verbose "> OpenSSL config .." + EASYRSA_PKI_SSL_CNFFILE="$EASYRSA_PKI/openssl-easyrsa.cnf" + EASYRSA_PKI_SAFE_CNFFILE="$EASYRSA_PKI/safessl-easyrsa.cnf" + cp "$EASYRSA_SSL_CNFFILE" "$EASYRSA_PKI_SSL_CNFFILE" \ + || up23_fail_upgrade "create $EASYRSA_PKI_SSL_CNFFILE" + up23_verbose "> OK" + up23_verbose " New OpenSSL config file created in: $EASYRSA_PKI_SSL_CNFFILE" + + # Create $EASYRSA_PKI/safessl-easyrsa.cnf + easyrsa_openssl makesafeconf + if [ -f "$EASYRSA_PKI_SAFE_CNFFILE" ] + then + up23_verbose " New SafeSSL config file created in: $EASYRSA_PKI_SAFE_CNFFILE" + else + up23_verbose " FAILED to create New SafeSSL config file in: $EASYRSA_PKI_SAFE_CNFFILE" + fi +} #=> up23_create_openssl_cnf () + +up23_move_easyrsa2_programs () +{ + # These files may not exist here + up23_verbose "> Move easyrsa2 programs to SAFE PKI .." + for i in build-ca build-dh build-inter build-key build-key-pass \ + build-key-pkcs12 build-key-server build-req build-req-pass \ + clean-all inherit-inter list-crl pkitool revoke-full sign-req \ + whichopensslcnf build-ca-pass build-key-server-pass init-config \ + make-crl revoke-crt openssl-0.9.6.cnf openssl-0.9.8.cnf \ + openssl-1.0.0.cnf openssl.cnf README.txt index.txt.start \ + vars.bat.sample serial.start + do + # Although unlikely, both files could exist + # EG: ./build-ca and ./build-ca.bat + NIX_FILE="$EASYRSA/$i" + WIN_FILE="$EASYRSA/$i.bat" + if [ -f "$NIX_FILE" ] + then + cp "$NIX_FILE" "$EASYRSA_SAFE_PKI" \ + || up23_fail_upgrade "copy $NIX_FILE $EASYRSA_SAFE_PKI" + fi + + if [ -f "$WIN_FILE" ] + then + cp "$WIN_FILE" "$EASYRSA_SAFE_PKI" \ + || up23_fail_upgrade "copy $WIN_FILE $EASYRSA_SAFE_PKI" + fi + + if [ ! -f "$NIX_FILE" ] && [ ! -f "$WIN_FILE" ] + then + up23_verbose "File does not exist, ignoring: $i(.bat)" + fi + + # These files are not removed on TEST run + [ "$NOSAVE" -eq 1 ] && rm -f "$NIX_FILE" "$WIN_FILE" + done + + up23_verbose "> OK" + up23_verbose " Easyrsa2 programs successfully moved to: $EASYRSA_SAFE_PKI" +} #=> up23_move_easyrsa2_programs () + +# shellcheck disable=SC2154 +up23_build_v3_vars () +{ + up23_verbose "> Build v3 vars file .." + + EASYRSA_EXT="easyrsa-upgrade-23" + EASYRSA_VARSV2_TMP="$EASYRSA/vars-v2.tmp.$EASYRSA_EXT" + rm -f "$EASYRSA_VARSV2_TMP" + EASYRSA_VARSV3_TMP="$EASYRSA/vars-v3.tmp.$EASYRSA_EXT" + rm -f "$EASYRSA_VARSV3_TMP" + EASYRSA_VARSV3_NEW="$EASYRSA/vars-v3.new.$EASYRSA_EXT" + rm -f "$EASYRSA_VARSV3_NEW" + EASYRSA_VARSV3_WRN="$EASYRSA/vars-v3.wrn.$EASYRSA_EXT" + rm -f "$EASYRSA_VARSV3_WRN" + + printf "%s\n" "\ +########################++++++++++######################### +### ### +### WARNING: THIS FILE WAS AUTOMATICALLY GENERATED ### +### ALL SETTINGS ARE AT THE END OF THE FILE ### +### ### +########################++++++++++######################### + +" > "$EASYRSA_VARSV3_WRN" || up23_fail_upgrade "Failed to create $EASYRSA_VARSV3_WRN" + + # Create vars v3 temp file from sourced vars v2 key variables + { + printf "%s\n" "set_var EASYRSA_KEY_SIZE $KEY_SIZE" + printf "%s\n" "set_var EASYRSA_REQ_COUNTRY \"$KEY_COUNTRY\"" + printf "%s\n" "set_var EASYRSA_REQ_PROVINCE \"$KEY_PROVINCE\"" + printf "%s\n" "set_var EASYRSA_REQ_CITY \"$KEY_CITY\"" + printf "%s\n" "set_var EASYRSA_REQ_ORG \"$KEY_ORG\"" + printf "%s\n" "set_var EASYRSA_REQ_EMAIL \"$KEY_EMAIL\"" + printf "%s\n" "set_var EASYRSA_REQ_OU \"$KEY_OU\"" + printf "%s\n" 'set_var EASYRSA_NS_SUPPORT "yes"' + printf "%s\n" 'set_var EASYRSA_DN "org"' + printf "%s\n" 'set_var EASYRSA_RAND_SN "no"' + printf "%s\n" "" + } > "$EASYRSA_VARSV3_TMP" \ + || up23_fail_upgrade "Failed to create $EASYRSA_VARSV3_TMP" + + # cat temp files into new v3 vars + cat "$EASYRSA_VARSV3_WRN" "$EASYRSA_VARSV3_EXMP" "$EASYRSA_VARSV3_TMP" \ + > "$EASYRSA_VARSV3_NEW" \ + || up23_fail_upgrade "Failed to create $EASYRSA_VARSV3_NEW" + + # This file must be created and restored at the end of TEST + # for the REAL update to to succeed + EASYRSA_VARS_LIVEBKP="$EASYRSA_TARGET_VARSFILE.livebackup" + cp "$EASYRSA_VER2_VARSFILE" "$EASYRSA_VARS_LIVEBKP" \ + || up23_fail_upgrade "Failed to create $EASYRSA_VARS_LIVEBKP" + rm -f "$EASYRSA_VER2_VARSFILE" + + # "$EASYRSA_TARGET_VARSFILE" is always $EASYRSA/vars + cp "$EASYRSA_VARSV3_NEW" "$EASYRSA_TARGET_VARSFILE" \ + || up23_fail_upgrade "copy $EASYRSA_VARSV3_NEW to $EASYRSA_TARGET_VARSFILE" + + # Delete temp files + rm -f "$EASYRSA_VARSV2_TMP" "$EASYRSA_VARSV3_TMP" \ + "$EASYRSA_VARSV3_NEW" "$EASYRSA_VARSV3_WRN" + + up23_verbose "> OK" + up23_verbose " New v3 vars file created in: $EASYRSA_TARGET_VARSFILE" +} #=> up23_build_v3_vars () + +# shellcheck disable=SC2154 +up23_do_upgrade_23 () +{ + up23_verbose "============================================================================" + up23_verbose "Begin ** $1 ** upgrade process .." + up23_verbose "" + up23_verbose "Easyrsa upgrade version: $EASYRSA_UPGRADE_23" + up23_verbose "" + + up23_verify_new_pki + up23_verify_current_pki + up23_verify_current_ca + up23_backup_current_pki + up23_create_new_pki + up23_upgrade_ca + up23_move_easyrsa2_programs + up23_build_v3_vars + up23_create_openssl_cnf + + if [ "$NOSAVE" -eq 0 ] + then + # Must stay in this order + # New created dirs: EASYRSA_NEW_PKI and EASYRSA_SAFE_PKI + rm -rf "$EASYRSA_NEW_PKI" + rm -rf "$EASYRSA_SAFE_PKI" + # EASYRSA_TARGET_VARSFILE is always the new created v3 vars + # Need to know if this fails + rm "$EASYRSA_TARGET_VARSFILE" \ + || up23_fail_upgrade "remove new vars file: $EASYRSA_TARGET_VARSFILE" + # EASYRSA_VER2_VARSFILE is either v2 *nix ./vars or Win vars.bat + # Need this dance because v2 vars is same name as v3 vars above + cp "$EASYRSA_VARS_LIVEBKP" "$EASYRSA_VER2_VARSFILE" + fi + rm -f "$EASYRSA_VARS_LIVEBKP" +} #= up23_do_upgrade_23 () + +up23_manage_upgrade_23 () +{ + EASYRSA_UPGRADE_VERSION="v1.0a (2020/01/08)" + EASYRSA_UPGRADE_TYPE="$1" + EASYRSA_FOUND_VARS=0 + + # Verify all existing versions of vars/vars.bat + if [ -f "$vars" ] + then + if grep -q 'Complain if a user tries to do this:' "$vars" + then + EASYRSA_FOUND_VARS=1 + EASYRSA_VARS_IS_VER3=1 + fi + + # Easyrsa v3 does not use NOR allow use of `export`. + if grep -q 'export' "$vars" + then + EASYRSA_FOUND_VARS=1 + EASYRSA_VARS_IS_VER2=1 + EASYRSA_VER2_VARSFILE="$vars" + EASYRSA_TARGET_VARSFILE="$vars" + fi + fi + + if [ -f "$EASYRSA/vars.bat" ] + then + EASYRSA_FOUND_VARS=1 + EASYRSA_VARS_IS_WIN2=1 + EASYRSA_VER2_VARSFILE="$EASYRSA/vars.bat" + EASYRSA_TARGET_VARSFILE="$EASYRSA/vars" + fi + + if [ $EASYRSA_FOUND_VARS -ne 1 ]; + then + die "vars file not found" + fi + + # Only allow specific vars/vars.bat to exist + if [ "$EASYRSA_VARS_IS_VER3" ] && [ "$EASYRSA_VARS_IS_VER2" ] + then + die "Verify your current vars file, v3 cannot use 'export'." + fi + + if [ "$EASYRSA_VARS_IS_VER3" ] && [ "$EASYRSA_VARS_IS_WIN2" ] + then + die "Verify your current vars/vars.bat file, cannot have both." + fi + + if [ "$EASYRSA_VARS_IS_VER2" ] && [ "$EASYRSA_VARS_IS_WIN2" ] + then + die "Verify your current vars/vars.bat file, cannot have both." + fi + + # Die on invalid upgrade type or environment + if [ "$EASYRSA_UPGRADE_TYPE" = "ca" ] + then + if [ "$EASYRSA_VARS_IS_VER3" ] + then + # v3 ensure index.txt.attr "unique_subject = no" + up23_upgrade_ca + unset EASYRSA_BATCH + notice "Your CA is fully up to date." + return 0 + else + die "Only v3 PKI CA can be upgraded." + fi + fi + + if [ "$EASYRSA_UPGRADE_TYPE" = "pki" ] + then + if [ "$EASYRSA_VARS_IS_VER3" ] + then + unset EASYRSA_BATCH + notice "Your PKI is fully up to date." + return 0 + fi + else + die "upgrade type must be 'pki' or 'ca'." + fi + + # PKI is potentially suitable for upgrade + + warn " +========================================================================= + + * WARNING * + +Found settings from EasyRSA-v2 which are not compatible with EasyRSA-v3. +Before you can continue, EasyRSA must upgrade your settings and PKI. +* Found EASYRSA and vars file: + $EASYRSA + $EASYRSA_VER2_VARSFILE : + +Further info: +* https://community.openvpn.net/openvpn/wiki/easyrsa-upgrade + +Easyrsa upgrade version: $EASYRSA_UPGRADE_VERSION +========================================================================= +" + +# Test upgrade + + NOSAVE=0 + + confirm "* EasyRSA **TEST** upgrade (Changes will NOT be written): " "yes" " +This upgrade will TEST that the upgrade works BEFORE making any changes." + + up23_do_upgrade_23 "TEST" + + notice " +========================================================================= + + * NOTICE * + +EasyRSA upgrade **TEST** has successfully completed. +" +# Upgrade for REAL + + NOSAVE=1 + + confirm "* EasyRSA **REAL** upgrade (Changes WILL be written): " "yes" " +========================================================================= + + * WARNING * + +Run REAL upgrade: Answer yes (Once completed you will have a version 3 PKI) +Terminate upgrade: Answer no (No changes have been made to your current PKI) +" + + confirm "* Confirm **REAL** upgrade (Changes will be written): " "yes" " +========================================================================= + + * SECOND WARNING * + +This upgrade will permanently write changes to your PKI ! +(With full backup backout) +" + up23_do_upgrade_23 "REAL" + + notice " +========================================================================= + + * NOTICE * + +Your settings and PKI have been successfully upgraded to EasyRSA version3 + +A backup of your current PKI is here: + $EASYRSA_SAFE_PKI + + * IMPORTANT NOTICE * + +1. YOU MUST VERIFY THAT YOUR NEW ./vars FILE IS SETUP CORRECTLY +2. IF YOU ARE USING WINDOWS YOU MUST ENSURE THAT openssl IS CORRECTLY DEFINED + IN ./vars (example follows) + + # + # This sample is in Windows syntax -- edit it for your path if not using PATH: + # set_var EASYRSA_OPENSSL \"C:/Program Files/OpenSSL-Win32/bin/openssl.exe\" + # + # Alternate location (Note: Forward slash '/' is correct for Windpws): + # set_var EASYRSA_OPENSSL \"C:/Program Files/Openvpn/bin/openssl.exe\" + # + +3. Finally, you can verify that easyrsa works by using these two commands: + ./easyrsa show-ca (Verify that your CA is intact and correct) + ./easyrsa gen-crl ((re)-generate a CRL file) + +Further info: +* https://community.openvpn.net/openvpn/wiki/easyrsa-upgrade" + up23_verbose " + * UPGRADE COMPLETED SUCCESSFULLY * +" + +return 0 + +} # => up23_manage_upgrade_23 () + +print_version() +{ + ssl_version="$("${EASYRSA_OPENSSL:-openssl}" version)" + cat << VERSION_TEXT +EasyRSA Version Information +Version: 3.1.0 +Generated: Wed May 18 20:53:50 CDT 2022 +SSL Lib: $ssl_version +Git Commit: 1600b3fe9bd71e229b8648cd24206c55917b2f9b +Source Repo: https://github.com/OpenVPN/easy-rsa +VERSION_TEXT +} # => print_version () + + +######################################## +# Invocation entry point: + +NL=' +' + +# Be secure with a restrictive umask +[ -z "$EASYRSA_NO_UMASK" ] && umask "${EASYRSA_UMASK:-077}" + +# Initialisation requirements +unset -v easyrsa_error_exit user_san_true user_vars_true + +# Parse options +while :; do + # Separate option from value: + opt="${1%%=*}" + val="${1#*=}" + + # Empty values are not allowed unless expected + unset -v is_empty empty_ok + # eg: '--batch' + [ "$opt" = "$val" ] && is_empty=1 + # eg: '--pki-dir=' + [ "$val" ] || is_empty=1 + + case "$opt" in + --days) + export EASYRSA_CERT_EXPIRE="$val" + export EASYRSA_CA_EXPIRE="$val" + export EASYRSA_CRL_DAYS="$val" + ;; + --fix-offset) + export EASYRSA_FIX_OFFSET="$val" ;; + --renew-days) + export EASYRSA_CERT_RENEW="$val" ;; + --pki-dir) + export EASYRSA_PKI="$val" ;; + --tmp-dir) + export EASYRSA_TEMP_DIR="$val" ;; + --ssl-conf) + export EASYRSA_SSL_CONF="$val" ;; + --use-algo) + export EASYRSA_ALGO="$val" ;; + --keysize) + export EASYRSA_KEY_SIZE="$val" ;; + --curve) + export EASYRSA_CURVE="$val" ;; + --dn-mode) + export EASYRSA_DN="$val" ;; + --req-cn) + export EASYRSA_REQ_CN="$val" ;; + --digest) + export EASYRSA_DIGEST="$val" ;; + --req-c) + empty_ok=1 + export EASYRSA_REQ_COUNTRY="$val" ;; + --req-st) + empty_ok=1 + export EASYRSA_REQ_PROVINCE="$val" ;; + --req-city) + empty_ok=1 + export EASYRSA_REQ_CITY="$val" ;; + --req-org) + empty_ok=1 + export EASYRSA_REQ_ORG="$val" ;; + --req-email) + empty_ok=1 + export EASYRSA_REQ_EMAIL="$val" ;; + --req-ou) + empty_ok=1 + export EASYRSA_REQ_OU="$val" ;; + --ns-cert) + export EASYRSA_NS_SUPPORT="$val" ;; + --ns-comment) + empty_ok=1 + export EASYRSA_NS_COMMENT="$val" ;; + --batch) + empty_ok=1 + export EASYRSA_BATCH=1 ;; + --silent) + empty_ok=1 + export EASYRSA_SILENT=1 ;; + --silent-batch|--sbatch) + empty_ok=1 + export EASYRSA_SILENT=1 + export EASYRSA_BATCH=1 ;; + --passin) + export EASYRSA_PASSIN="$val";; + --passout) + export EASYRSA_PASSOUT="$val";; + --subca-len) + export EASYRSA_SUBCA_LEN="$val" ;; + --vars) + user_vars_true=1 + export EASYRSA_VARS_FILE="$val" ;; + --copy-ext) + empty_ok=1 + export EASYRSA_CP_EXT=1 ;; + --subject-alt-name|--san) + user_san_true=1 + export EASYRSA_EXTRA_EXTS="\ +$EASYRSA_EXTRA_EXTS +subjectAltName = $val" ;; + --version) + shift "$#" + set -- "$@" "version" + break + ;; + *) + break + esac + + # fatal error when no value was provided + if [ "$is_empty" ]; then + [ "$empty_ok" ] || die "Missing value to option: $opt" + fi + + shift +done + +# Register cleanup on EXIT +trap "cleanup" EXIT +# When SIGHUP, SIGINT, SIGQUIT, SIGABRT and SIGTERM, +# explicitly exit to signal EXIT (non-bash shells) +trap "exit 1" 1 +trap "exit 2" 2 +trap "exit 3" 3 +trap "exit 6" 6 +trap "exit 14" 15 + +# Get host details - does not require vars_setup +detect_host + +# Set cmd now because vars_setup needs to know if this is init-pki +cmd="$1" +[ -n "$1" ] && shift # scrape off command + +# This avoids unnecessary warnings and notices +case "$cmd" in + init-pki|clean-all|""|help|-h|--help|--usage|version) + no_pki_required=1 ;; + *) unset -v no_pki_required +esac + +# Intelligent env-var detection and auto-loading: +vars_setup + +# determine how we were called, then hand off to the function responsible +case "$cmd" in + init-pki|clean-all) + if [ "$user_vars_true" ]; then + # Ref: https://github.com/OpenVPN/easy-rsa/issues/566 + die "Use of '--vars=FILE init-pki' is prohibited, use '--pki-dir=DIR'" + fi + init_pki "$@" + ;; + build-ca) + build_ca "$@" + ;; + gen-dh) + gen_dh + ;; + gen-req) + gen_req "$@" + ;; + sign|sign-req) + sign_req "$@" + ;; + build-client-full) + build_full client "$@" + ;; + build-server-full) + build_full server "$@" + ;; + build-serverClient-full) + build_full serverClient "$@" + ;; + gen-crl) + gen_crl + ;; + revoke) + revoke "$@" + ;; + revoke-renewed) + revoke_renewed "$@" + ;; + renew) + renew "$@" + ;; + renewable) + renewable "$@" + ;; + import-req) + import_req "$@" + ;; + export-p12) + export_pkcs p12 "$@" + ;; + export-p7) + export_pkcs p7 "$@" + ;; + export-p8) + export_pkcs p8 "$@" + ;; + export-p1) + export_pkcs p1 "$@" + ;; + set-rsa-pass) + set_pass rsa "$@" + ;; + set-ec-pass) + set_pass ec "$@" + ;; + update-db) + update_db + ;; + show-req) + show req "$@" + ;; + show-cert) + show cert "$@" + ;; + show-crl) + show crl crl + ;; + show-ca) + show_ca "$@" + ;; + verify) + verify_cert "$@" + ;; + show-expire) + if [ -z "$*" ]; then + status expire all + else + status expire "$@" + fi + ;; + show-revoke) + if [ -z "$*" ]; then + status revoke all + else + status revoke "$@" + fi + ;; + show-renew) + if [ -z "$*" ]; then + status renew all + else + status renew "$@" + fi + ;; + upgrade) + up23_manage_upgrade_23 "$@" + ;; + ""|help|-h|--help|--usage) + cmd_help "$1" + ;; + version) + print_version + ;; + *) + die "Unknown command '$cmd'. Run without commands for usage help." +esac + +# Clear traps and do 'cleanup ok' on successful completion +trap - 0 1 2 3 6 15 +cleanup ok + +# vim: ft=sh nu ai sw=8 ts=8 noet diff --git a/OpenVPN/CA Server/easy-rsa/pki/issued/edgerouterchambly.crt b/OpenVPN/CA Server/easy-rsa/pki/issued/edgerouterchambly.crt new file mode 100644 index 0000000..76e8338 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/issued/edgerouterchambly.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 35:09:16:22:41:a8:78:05:b5:72:26:31:6e:c3:94:02 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Jul 3 19:11:30 2023 GMT + Not After : Oct 5 19:11:30 2025 GMT + Subject: CN=edgerouterchambly + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:0e:fd:1c:60:83:5f:a7:64:79:a0:35:74:df:c0: + 63:68:c5:3c:b1:02:95:a9:73:58:a9:a3:74:cc:d8: + 5b:d8:7a:ab:aa:d3:1f:41:2d:68:86:bd:2f:e3:6c: + 73:b5:e8:01:73:b4:12:f4:71:dd:dd:cb:9b:4e:b0: + f1:d4:04:00:d1:60:cf:fe:ea:3c:a5:f2:ae:ee:aa: + 45:a3:21:71:e5:d2:b7:f0:22:30:c4:d4:27:58:79: + 96:6c:f0:5c:ba:96:19 + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + C1:2A:D4:21:E9:F3:08:CB:87:23:CC:2D:52:A3:DF:8F:BB:CF:BB:5A + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 2e:c6:3c:76:fd:64:a8:ab:c7:02:86:e8:80:d5:a6:8b:2f:ed: + be:70:cd:96:23:a5:86:1f:19:0c:72:7b:0b:ec:d2:58:ad:39: + 1d:ee:63:52:55:a3:f2:47:87:12:56:ad:cd:a1:ed:0d:ed:27: + 55:4c:9b:47:cf:e8:d7:a2:70:d7:8a:d2:60:7e:57:b4:02:0d: + 96:46:57:9d:f9:05:cf:f1:91:5c:1e:e2:a7:79:e1:5b:fe:46: + 7a:1b:ab:bb:c0:0a:a5:70:68:83:88:1a:62:8a:36:4c:98:9c: + 85:31:40:6b:ad:a7:11:d3:a3:cb:d9:8a:f3:e8:d4:2c:bd:8a: + 66:57:ca:bb:ad:d9:b1:cf:6a:83:88:e3:5e:a4:2e:5b:7e:50: + 26:16:5c:34:cd:6c:9b:35:d9:61:ef:63:87:7c:2a:2d:f0:dd: + ce:ab:9d:7e:14:46:98:d9:cb:9a:68:91:fb:a3:59:85:91:d5: + 4f:0c:ee:e3:47:df:7c:93:f8:05:ec:0a:d1:84:dc:21:0f:8e: + 6d:b5:14:e8:a3:bd:ea:21:1c:d1:5a:95:36:95:98:20:f0:0e: + 07:54:56:27:d9:6d:cc:c6:09:f1:98:1c:69:d7:1b:52:0c:54: + 38:32:fe:c6:50:07:74:ef:8c:05:03:bf:55:e0:c7:3b:e5:20: + f2:84:3e:9f +-----BEGIN CERTIFICATE----- +MIICrTCCAZWgAwIBAgIQNQkWIkGoeAW1ciYxbsOUAjANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjMwNzAzMTkxMTMwWhcNMjUxMDA1MTkx +MTMwWjAcMRowGAYDVQQDDBFlZGdlcm91dGVyY2hhbWJseTB2MBAGByqGSM49AgEG +BSuBBAAiA2IABA79HGCDX6dkeaA1dN/AY2jFPLEClalzWKmjdMzYW9h6q6rTH0Et +aIa9L+Nsc7XoAXO0EvRx3d3Lm06w8dQEANFgz/7qPKXyru6qRaMhceXSt/AiMMTU +J1h5lmzwXLqWGaOBoDCBnTAJBgNVHRMEAjAAMB0GA1UdDgQWBBTBKtQh6fMIy4cj +zC1So9+Pu8+7WjBPBgNVHSMESDBGgBSKeJDl8FDnjHXkuMCh6OmbshqdMqEYpBYw +FDESMBAGA1UEAwwJSkZfc2VydmVyghRd7fuTPbKqDIvbFd+9oZHOXPvLBjATBgNV +HSUEDDAKBggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEB +AC7GPHb9ZKirxwKG6IDVposv7b5wzZYjpYYfGQxyewvs0litOR3uY1JVo/JHhxJW +rc2h7Q3tJ1VMm0fP6NeicNeK0mB+V7QCDZZGV535Bc/xkVwe4qd54Vv+Rnobq7vA +CqVwaIOIGmKKNkyYnIUxQGutpxHTo8vZivPo1Cy9imZXyrut2bHPaoOI416kLlt+ +UCYWXDTNbJs12WHvY4d8Ki3w3c6rnX4URpjZy5pokfujWYWR1U8M7uNH33yT+AXs +CtGE3CEPjm21FOijveohHNFalTaVmCDwDgdUVifZbczGCfGYHGnXG1IMVDgy/sZQ +B3TvjAUDv1XgxzvlIPKEPp8= +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/issued/fred.crt b/OpenVPN/CA Server/easy-rsa/pki/issued/fred.crt new file mode 100644 index 0000000..96b815d --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/issued/fred.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + ab:ba:55:27:aa:06:49:7b:13:dd:f2:5b:ae:27:08:fe + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Jun 1 18:17:32 2023 GMT + Not After : Sep 3 18:17:32 2025 GMT + Subject: CN=fred + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:3e:78:ef:26:d9:87:bb:8b:08:47:fe:15:ad:96: + ae:f4:93:f1:d8:ce:e3:05:d2:96:46:fc:f6:47:c9: + ac:41:f5:01:1b:e3:25:61:f4:ee:6f:8d:13:dd:ab: + 1b:d8:02:85:a3:fb:52:3d:02:d8:ad:0b:ed:e3:02: + 88:c7:eb:06:52:ca:25:ac:8b:ac:eb:52:4c:43:52: + f9:c0:8c:f4:48:ea:72:a6:26:f7:5f:02:96:97:ad: + 10:ac:6d:c8:d3:b1:28 + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 3C:F6:00:C3:CF:A4:BB:8D:F1:1B:AB:A1:6F:24:44:2A:73:95:EB:46 + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 10:9c:49:d0:09:dc:52:df:2b:e1:ce:59:ef:f7:a0:96:13:05: + 7e:30:ba:4b:6d:17:62:ed:89:39:cb:0e:c5:cc:df:0c:5a:68: + e7:0f:bc:c2:67:e0:b2:72:b6:9f:e7:9f:1f:4c:e5:da:d9:5c: + d8:53:44:ef:47:ea:47:9d:d7:1d:12:ab:75:c3:1f:c4:d8:ae: + 65:7e:39:9d:98:f1:02:df:03:77:1e:7b:88:24:5f:7e:51:5c: + f2:9c:b8:1f:84:71:4b:f9:5a:6d:06:63:4d:e9:ab:27:f5:99: + fa:ac:25:7a:e2:a7:ba:94:a7:44:8b:2f:21:73:c1:db:1a:37: + 38:d6:46:4a:a5:65:f7:24:35:08:40:9a:8e:d6:22:56:20:c9: + 7b:52:b3:8f:ea:53:bf:00:bd:6a:23:bd:07:fe:af:2e:20:ee: + 71:69:f8:66:b0:f3:00:5e:8d:2f:2a:37:b9:14:a6:bf:c8:25: + 2e:1b:f4:86:58:94:33:2b:85:f9:08:3a:48:9e:49:42:66:5a: + 37:10:10:5b:50:2e:f6:06:d0:fe:86:17:0d:9d:f5:dd:cb:ab: + 92:39:de:d8:57:9d:0d:7e:14:b7:61:e5:bc:dc:62:00:22:8c: + 23:df:90:d4:38:01:18:23:96:c6:7e:e8:c8:5e:c8:fd:a4:b2: + 47:87:02:4f +-----BEGIN CERTIFICATE----- +MIICoTCCAYmgAwIBAgIRAKu6VSeqBkl7E93yW64nCP4wDQYJKoZIhvcNAQELBQAw +FDESMBAGA1UEAwwJSkZfc2VydmVyMB4XDTIzMDYwMTE4MTczMloXDTI1MDkwMzE4 +MTczMlowDzENMAsGA1UEAwwEZnJlZDB2MBAGByqGSM49AgEGBSuBBAAiA2IABD54 +7ybZh7uLCEf+Fa2WrvST8djO4wXSlkb89kfJrEH1ARvjJWH07m+NE92rG9gChaP7 +Uj0C2K0L7eMCiMfrBlLKJayLrOtSTENS+cCM9EjqcqYm918ClpetEKxtyNOxKKOB +oDCBnTAJBgNVHRMEAjAAMB0GA1UdDgQWBBQ89gDDz6S7jfEbq6FvJEQqc5XrRjBP +BgNVHSMESDBGgBSKeJDl8FDnjHXkuMCh6OmbshqdMqEYpBYwFDESMBAGA1UEAwwJ +SkZfc2VydmVyghRd7fuTPbKqDIvbFd+9oZHOXPvLBjATBgNVHSUEDDAKBggrBgEF +BQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBABCcSdAJ3FLfK+HO +We/3oJYTBX4wukttF2LtiTnLDsXM3wxaaOcPvMJn4LJytp/nnx9M5drZXNhTRO9H +6ked1x0Sq3XDH8TYrmV+OZ2Y8QLfA3cee4gkX35RXPKcuB+EcUv5Wm0GY03pqyf1 +mfqsJXrip7qUp0SLLyFzwdsaNzjWRkqlZfckNQhAmo7WIlYgyXtSs4/qU78AvWoj +vQf+ry4g7nFp+Gaw8wBejS8qN7kUpr/IJS4b9IZYlDMrhfkIOkieSUJmWjcQEFtQ +LvYG0P6GFw2d9d3Lq5I53thXnQ1+FLdh5bzcYgAijCPfkNQ4ARgjlsZ+6MheyP2k +skeHAk8= +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/issued/jf.crt b/OpenVPN/CA Server/easy-rsa/pki/issued/jf.crt new file mode 100644 index 0000000..7c6e620 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/issued/jf.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 22:7a:b3:cb:88:05:00:8c:df:af:02:be:af:63:f9:59 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Feb 20 22:37:46 2023 GMT + Not After : May 25 22:37:46 2025 GMT + Subject: CN=jf + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:8d:38:ea:4f:29:bd:83:a9:33:a3:1c:33:8a:60: + 8f:fa:19:81:00:73:44:81:98:1e:76:05:ee:f6:46: + d5:25:a8:c5:3b:bd:d6:fa:cf:c6:79:e0:b4:42:27: + 80:e2:96:2d:30:50:c2:f6:9c:2c:13:f8:b9:46:b3: + 0d:96:6c:9b:d2:45:15:a3:f0:4c:bc:6b:51:45:f8: + cb:59:04:b1:d0:47:b9:90:06:71:c7:eb:34:32:e2: + 72:14:84:94:58:e3:34 + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + C5:CE:72:8F:A3:8E:13:57:DD:0E:02:A1:24:F1:56:C3:AE:2F:65:8F + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 3b:e8:1a:3e:ac:17:17:49:7c:4d:73:55:39:e9:1b:e4:d6:7f: + 6d:6d:43:6c:e2:79:41:f4:26:a4:2d:18:59:24:a0:b1:e0:db: + 03:07:f9:fb:24:f6:be:ed:8c:31:3e:c7:bb:74:b6:87:ba:43: + fc:d6:fb:2f:9f:1c:eb:d1:27:ad:60:eb:ab:87:c7:46:fe:22: + 75:c1:bb:fb:23:ad:ba:1d:ab:41:45:29:d6:c4:89:99:94:40: + 06:c7:3a:08:fe:d3:b5:f4:e7:52:57:aa:d1:a8:ec:74:e6:c9: + ec:9e:80:e0:ba:92:92:95:55:2e:d7:b2:d8:09:ee:72:fd:12: + ac:0a:0d:dc:ba:ac:4e:34:8c:37:19:76:60:7c:bd:ba:99:b7: + e5:47:c3:4b:67:2f:a9:5c:89:95:70:2d:2c:97:45:04:64:15: + 47:04:d1:48:7d:d8:40:63:6c:05:8b:dc:ed:0f:a3:ae:3a:e8: + 6f:49:34:54:de:99:4b:aa:28:6d:c9:3d:db:43:60:14:40:d5: + 09:87:a8:b2:88:11:4c:8c:00:71:b1:38:25:91:5f:2f:93:7b: + 42:64:38:db:d2:59:48:e8:ed:2e:92:69:4e:d4:2a:3b:e3:03: + 94:2c:fc:ac:bc:ff:a9:b4:1e:ca:d3:d2:b5:fd:bf:33:bd:55: + 12:75:db:f1 +-----BEGIN CERTIFICATE----- +MIICnjCCAYagAwIBAgIQInqzy4gFAIzfrwK+r2P5WTANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjMwMjIwMjIzNzQ2WhcNMjUwNTI1MjIz +NzQ2WjANMQswCQYDVQQDDAJqZjB2MBAGByqGSM49AgEGBSuBBAAiA2IABI046k8p +vYOpM6McM4pgj/oZgQBzRIGYHnYF7vZG1SWoxTu91vrPxnngtEIngOKWLTBQwvac +LBP4uUazDZZsm9JFFaPwTLxrUUX4y1kEsdBHuZAGccfrNDLichSElFjjNKOBoDCB +nTAJBgNVHRMEAjAAMB0GA1UdDgQWBBTFznKPo44TV90OAqEk8VbDri9ljzBPBgNV +HSMESDBGgBSKeJDl8FDnjHXkuMCh6OmbshqdMqEYpBYwFDESMBAGA1UEAwwJSkZf +c2VydmVyghRd7fuTPbKqDIvbFd+9oZHOXPvLBjATBgNVHSUEDDAKBggrBgEFBQcD +AjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBADvoGj6sFxdJfE1zVTnp +G+TWf21tQ2zieUH0JqQtGFkkoLHg2wMH+fsk9r7tjDE+x7t0toe6Q/zW+y+fHOvR +J61g66uHx0b+InXBu/sjrbodq0FFKdbEiZmUQAbHOgj+07X051JXqtGo7HTmyeye +gOC6kpKVVS7XstgJ7nL9EqwKDdy6rE40jDcZdmB8vbqZt+VHw0tnL6lciZVwLSyX +RQRkFUcE0Uh92EBjbAWL3O0Po6466G9JNFTemUuqKG3JPdtDYBRA1QmHqLKIEUyM +AHGxOCWRXy+Te0JkONvSWUjo7S6SaU7UKjvjA5Qs/Ky8/6m0HsrT0rX9vzO9VRJ1 +2/E= +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/issued/pascal.crt b/OpenVPN/CA Server/easy-rsa/pki/issued/pascal.crt new file mode 100644 index 0000000..5730b5c --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/issued/pascal.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + a6:7f:64:22:94:22:4a:39:b9:48:25:9b:99:9d:ae:a7 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Mar 17 19:30:32 2023 GMT + Not After : Jun 19 19:30:32 2025 GMT + Subject: CN=pascal + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:6e:d7:fc:29:a8:23:70:28:49:70:82:f4:1a:4f: + fc:e8:5a:d3:10:84:ef:0a:59:d9:3e:31:2e:5f:91: + 8b:97:7e:32:c5:e4:9a:b1:df:8b:66:82:f7:a5:5a: + 6d:90:ba:4d:4b:75:4e:1b:09:37:3b:23:5b:df:b8: + 08:89:c7:a0:d6:3b:fa:3e:f8:b1:08:18:a6:ee:25: + 02:25:b2:c5:43:ee:f5:03:82:9e:39:a0:82:d0:23: + 49:eb:fe:be:3e:8f:7a + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 8E:E1:F2:13:12:D0:E0:C4:29:EA:29:E4:3D:94:2B:EC:0D:04:8F:BC + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 7d:0b:3f:f6:58:09:f2:8a:8d:0e:1e:50:c9:e8:31:f0:8f:0a: + f5:65:66:55:d3:dd:2c:5d:42:d4:0f:a5:02:ed:6a:77:e1:1d: + 39:c5:46:1c:a5:38:17:89:13:f1:cd:eb:ff:b8:a5:3d:e9:85: + 6f:d2:96:9b:f4:a1:09:6c:1b:84:40:70:19:2b:e1:ac:91:c2: + df:bf:09:a4:4f:c4:31:44:fe:2b:a5:60:38:97:a8:b3:01:aa: + 39:43:74:90:b5:c6:fc:85:63:26:9f:7f:54:ba:de:4a:b1:ae: + 6d:85:00:35:4d:15:9f:9d:10:f4:bf:bb:67:45:7e:c6:ab:ee: + 7e:ad:92:4a:b4:e8:76:65:be:94:40:5a:67:83:ab:6c:d9:f9: + 7d:40:bd:70:87:1f:14:4d:eb:56:50:a5:c3:7e:4a:b3:42:b5: + 95:fe:f8:7f:9b:c6:c0:81:04:62:fd:94:ef:da:dd:17:01:a0: + 93:14:80:31:5a:a2:fa:c7:8c:2d:7c:df:8b:40:d5:5c:ce:5f: + a8:9f:9f:48:4f:49:49:dc:cc:37:7e:f7:55:84:74:8a:cd:68: + 15:60:8b:e8:4a:75:3e:83:cb:33:be:45:e1:a1:76:52:1a:b9: + 09:34:38:af:6e:af:98:e3:6d:ed:c2:24:97:de:08:83:6b:d5: + 45:9e:91:3a +-----BEGIN CERTIFICATE----- +MIICozCCAYugAwIBAgIRAKZ/ZCKUIko5uUglm5mdrqcwDQYJKoZIhvcNAQELBQAw +FDESMBAGA1UEAwwJSkZfc2VydmVyMB4XDTIzMDMxNzE5MzAzMloXDTI1MDYxOTE5 +MzAzMlowETEPMA0GA1UEAwwGcGFzY2FsMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE +btf8KagjcChJcIL0Gk/86FrTEITvClnZPjEuX5GLl34yxeSasd+LZoL3pVptkLpN +S3VOGwk3OyNb37gIiceg1jv6PvixCBim7iUCJbLFQ+71A4KeOaCC0CNJ6/6+Po96 +o4GgMIGdMAkGA1UdEwQCMAAwHQYDVR0OBBYEFI7h8hMS0ODEKeop5D2UK+wNBI+8 +ME8GA1UdIwRIMEaAFIp4kOXwUOeMdeS4wKHo6ZuyGp0yoRikFjAUMRIwEAYDVQQD +DAlKRl9zZXJ2ZXKCFF3t+5M9sqoMi9sV372hkc5c+8sGMBMGA1UdJQQMMAoGCCsG +AQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAfQs/9lgJ8oqN +Dh5Qyegx8I8K9WVmVdPdLF1C1A+lAu1qd+EdOcVGHKU4F4kT8c3r/7ilPemFb9KW +m/ShCWwbhEBwGSvhrJHC378JpE/EMUT+K6VgOJeoswGqOUN0kLXG/IVjJp9/VLre +SrGubYUANU0Vn50Q9L+7Z0V+xqvufq2SSrTodmW+lEBaZ4OrbNn5fUC9cIcfFE3r +VlClw35Ks0K1lf74f5vGwIEEYv2U79rdFwGgkxSAMVqi+seMLXzfi0DVXM5fqJ+f +SE9JSdzMN373VYR0is1oFWCL6Ep1PoPLM75F4aF2Uhq5CTQ4r26vmONt7cIkl94I +g2vVRZ6ROg== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/issued/remoteclient.crt b/OpenVPN/CA Server/easy-rsa/pki/issued/remoteclient.crt new file mode 100644 index 0000000..ed70cba --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/issued/remoteclient.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + d1:ae:61:45:8e:84:e3:8e:5b:92:3f:aa:bb:81:9d:59 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: Feb 23 20:30:31 2023 GMT + Not After : May 28 20:30:31 2025 GMT + Subject: CN=remoteclient + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:65:e9:86:35:01:c3:d7:0e:16:3d:89:90:3c:cb: + a0:5f:d2:04:f7:b6:32:84:1e:a0:dc:6a:1d:16:a0: + 6f:47:a3:b5:7d:4c:39:bd:d0:70:18:34:e8:16:67: + d4:5b:4c:ca:ce:ea:f0:75:5f:55:72:09:4b:f5:dd: + 80:f1:d5:db:e6:26:09:e4:34:3b:ca:89:f3:3a:40: + 91:31:14:c6:ff:06:8d:8e:f9:ba:8f:47:df:40:41: + f4:6b:84:f8:e5:e8:70 + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 23:F8:BF:EB:8E:A3:77:B3:2B:6A:FA:16:7A:39:B2:C2:47:31:9F:76 + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 27:af:ff:e0:98:8e:d1:6c:39:d7:40:97:df:ea:5a:fc:57:31: + a2:92:0c:d3:4c:4b:74:22:9e:47:01:9b:0f:e0:a4:6c:dc:ef: + 14:b7:93:0f:99:93:ec:c9:96:dc:51:58:d3:ac:eb:f1:10:48: + ba:96:54:25:32:2a:89:66:cb:ca:13:b4:75:cc:4e:2a:5d:7c: + bb:b9:15:28:c0:32:59:f0:66:e5:fe:d8:14:14:2c:fb:df:6e: + 1e:b6:53:c9:f0:77:68:54:b9:21:4b:0c:a4:d6:bc:4d:c2:a3: + de:d0:9f:ef:67:68:3e:c6:d4:da:d5:6c:92:80:cf:2e:8d:04: + 59:c8:39:9f:22:4a:04:28:3e:e8:cf:02:73:73:a6:59:d4:e5: + 9c:77:55:41:00:5c:c2:23:61:df:44:5c:ad:a8:bc:15:57:2d: + ae:89:99:a7:33:8f:d3:75:02:21:91:f6:38:34:23:68:70:8f: + 99:0f:53:27:6d:52:9a:9b:f3:62:cf:20:bc:f5:91:41:78:fc: + 92:09:2f:3e:bb:2d:9b:69:39:7f:c4:b1:a8:62:64:27:3f:27: + 2d:16:c4:3e:0d:51:c9:f7:4f:40:f0:fd:55:a9:44:36:31:59: + b7:08:6a:3c:28:31:8a:43:c0:b9:05:44:75:48:6d:94:24:c6: + b2:fc:f7:33 +-----BEGIN CERTIFICATE----- +MIICqTCCAZGgAwIBAgIRANGuYUWOhOOOW5I/qruBnVkwDQYJKoZIhvcNAQELBQAw +FDESMBAGA1UEAwwJSkZfc2VydmVyMB4XDTIzMDIyMzIwMzAzMVoXDTI1MDUyODIw +MzAzMVowFzEVMBMGA1UEAwwMcmVtb3RlY2xpZW50MHYwEAYHKoZIzj0CAQYFK4EE +ACIDYgAEZemGNQHD1w4WPYmQPMugX9IE97YyhB6g3GodFqBvR6O1fUw5vdBwGDTo +FmfUW0zKzurwdV9VcglL9d2A8dXb5iYJ5DQ7yonzOkCRMRTG/waNjvm6j0ffQEH0 +a4T45ehwo4GgMIGdMAkGA1UdEwQCMAAwHQYDVR0OBBYEFCP4v+uOo3ezK2r6Fno5 +ssJHMZ92ME8GA1UdIwRIMEaAFIp4kOXwUOeMdeS4wKHo6ZuyGp0yoRikFjAUMRIw +EAYDVQQDDAlKRl9zZXJ2ZXKCFF3t+5M9sqoMi9sV372hkc5c+8sGMBMGA1UdJQQM +MAoGCCsGAQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAJ6// +4JiO0Ww510CX3+pa/FcxopIM00xLdCKeRwGbD+CkbNzvFLeTD5mT7MmW3FFY06zr +8RBIupZUJTIqiWbLyhO0dcxOKl18u7kVKMAyWfBm5f7YFBQs+99uHrZTyfB3aFS5 +IUsMpNa8TcKj3tCf72doPsbU2tVskoDPLo0EWcg5nyJKBCg+6M8Cc3OmWdTlnHdV +QQBcwiNh30Rcrai8FVctromZpzOP03UCIZH2ODQjaHCPmQ9TJ21SmpvzYs8gvPWR +QXj8kgkvPrstm2k5f8SxqGJkJz8nLRbEPg1RyfdPQPD9ValENjFZtwhqPCgxikPA +uQVEdUhtlCTGsvz3Mw== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/issued/stationKA2401.crt b/OpenVPN/CA Server/easy-rsa/pki/issued/stationKA2401.crt new file mode 100644 index 0000000..2260c91 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/issued/stationKA2401.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 78:5e:57:99:93:be:f2:47:da:cc:6c:8e:0d:71:3d:f8 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: May 5 13:33:22 2024 GMT + Not After : Aug 8 13:33:22 2026 GMT + Subject: CN=stationKA2401 + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:8f:4f:26:6b:af:cb:49:0b:74:3e:65:aa:0e:9a: + 9a:57:99:b1:f6:bf:dc:74:ae:d6:72:ed:d3:a8:04: + 2f:a8:a0:43:63:f6:c8:e2:cd:dc:d8:fd:bf:69:93: + 09:d7:bd:11:ab:d9:c5:ae:20:bc:00:ac:d7:ad:ea: + fb:c0:1e:44:6f:ba:20:63:9d:32:f7:38:8f:c0:d7: + bf:b4:23:15:16:4d:84:59:13:d5:4b:de:9e:7b:46: + d3:ce:ba:5d:d9:53:c4 + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 68:18:F5:54:75:30:27:4D:B5:96:D3:34:8E:1C:3B:58:1E:BC:1B:78 + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 67:97:34:79:07:29:c3:cd:a6:7c:86:82:aa:94:0b:ca:69:ef: + 79:5e:a6:35:97:c3:31:07:9f:cd:aa:89:95:e3:b1:26:4b:e9: + 88:50:1f:3e:10:eb:d2:82:c5:6e:56:18:1e:ff:72:60:c1:de: + 11:af:b8:e6:b6:bb:de:7d:52:f5:ba:1b:9b:4e:49:b2:05:25: + 0a:e9:8a:f8:85:f7:0e:c8:db:fd:c4:b9:e9:a9:6f:85:0a:cb: + 63:a3:d0:a7:77:e0:7f:ff:34:29:90:80:66:a7:8d:80:6a:bf: + 23:74:80:77:ad:53:2d:5e:f6:02:d1:05:3f:9f:fa:17:11:8f: + 7f:b4:a5:44:74:2b:57:1e:4b:7e:29:c8:95:48:a6:3a:fc:ae: + 82:c2:7b:b2:26:4f:92:d5:af:73:71:30:8e:b6:b9:6a:f2:b0: + 00:df:44:a2:3f:cd:4a:45:7e:ed:43:4b:d4:0e:07:25:94:37: + e0:5d:8d:0b:1b:fb:76:07:d0:41:da:c9:f3:19:fa:28:8b:46: + df:5a:19:82:ee:1e:e0:1a:be:39:c1:a9:65:b1:02:92:32:96: + 2c:7e:3f:4e:ce:9e:b0:66:57:b4:74:2c:98:de:13:da:b2:27: + e5:7a:5b:30:df:3e:46:1b:6c:92:53:6f:c6:0e:88:6f:0d:ae: + 89:ca:ea:ea +-----BEGIN CERTIFICATE----- +MIICqTCCAZGgAwIBAgIQeF5XmZO+8kfazGyODXE9+DANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjQwNTA1MTMzMzIyWhcNMjYwODA4MTMz +MzIyWjAYMRYwFAYDVQQDDA1zdGF0aW9uS0EyNDAxMHYwEAYHKoZIzj0CAQYFK4EE +ACIDYgAEj08ma6/LSQt0PmWqDpqaV5mx9r/cdK7Wcu3TqAQvqKBDY/bI4s3c2P2/ +aZMJ170Rq9nFriC8AKzXrer7wB5Eb7ogY50y9ziPwNe/tCMVFk2EWRPVS96ee0bT +zrpd2VPEo4GgMIGdMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGgY9VR1MCdNtZbTNI4c +O1gevBt4ME8GA1UdIwRIMEaAFIp4kOXwUOeMdeS4wKHo6ZuyGp0yoRikFjAUMRIw +EAYDVQQDDAlKRl9zZXJ2ZXKCFF3t+5M9sqoMi9sV372hkc5c+8sGMBMGA1UdJQQM +MAoGCCsGAQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAZ5c0 +eQcpw82mfIaCqpQLymnveV6mNZfDMQefzaqJleOxJkvpiFAfPhDr0oLFblYYHv9y +YMHeEa+45ra73n1S9bobm05JsgUlCumK+IX3Dsjb/cS56alvhQrLY6PQp3fgf/80 +KZCAZqeNgGq/I3SAd61TLV72AtEFP5/6FxGPf7SlRHQrVx5LfinIlUimOvyugsJ7 +siZPktWvc3Ewjra5avKwAN9Eoj/NSkV+7UNL1A4HJZQ34F2NCxv7dgfQQdrJ8xn6 +KItG31oZgu4e4Bq+OcGpZbECkjKWLH4/Ts6esGZXtHQsmN4T2rIn5XpbMN8+Rhts +klNvxg6Ibw2uicrq6g== +-----END CERTIFICATE----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/openssl-easyrsa.cnf b/OpenVPN/CA Server/easy-rsa/pki/openssl-easyrsa.cnf new file mode 100644 index 0000000..5c4fc79 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/openssl-easyrsa.cnf @@ -0,0 +1,138 @@ +# For use with Easy-RSA 3.0+ and OpenSSL or LibreSSL + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = $ENV::EASYRSA_PKI # Where everything is kept +certs = $dir # Where the issued certs are kept +crl_dir = $dir # Where the issued crl are kept +database = $dir/index.txt # database index file. +new_certs_dir = $dir/certs_by_serial # default place for new certs. + +certificate = $dir/ca.crt # The CA certificate +serial = $dir/serial # The current serial number +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/ca.key # The private key +RANDFILE = $dir/.rand # private random number file + +x509_extensions = basic_exts # The extensions to add to the cert + +# This allows a V2 CRL. Ancient browsers don't like it, but anything Easy-RSA +# is designed for will. In return, we get the Issuer attached to CRLs. +crl_extensions = crl_ext + +default_days = $ENV::EASYRSA_CERT_EXPIRE # how long to certify for +default_crl_days= $ENV::EASYRSA_CRL_DAYS # how long before next CRL +default_md = $ENV::EASYRSA_DIGEST # use public key default MD +preserve = no # keep passed DN ordering + +# This allows to renew certificates which have not been revoked +unique_subject = no + +# A few different ways of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_anything + +# For the 'anything' policy, which defines allowed DN fields +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +name = optional +emailAddress = optional + +#################################################################### +# Easy-RSA request handling +# We key off $DN_MODE to determine how to format the DN +[ req ] +default_bits = $ENV::EASYRSA_KEY_SIZE +default_keyfile = privkey.pem +default_md = $ENV::EASYRSA_DIGEST +distinguished_name = $ENV::EASYRSA_DN +x509_extensions = easyrsa_ca # The extensions to add to the self signed cert + +# A placeholder to handle the $EXTRA_EXTS feature: +#%EXTRA_EXTS% # Do NOT remove or change this line as $EXTRA_EXTS support requires it + +#################################################################### +# Easy-RSA DN (Subject) handling + +# Easy-RSA DN for cn_only support: +[ cn_only ] +commonName = Common Name (eg: your user, host, or server name) +commonName_max = 64 +commonName_default = $ENV::EASYRSA_REQ_CN + +# Easy-RSA DN for org support: +[ org ] +countryName = Country Name (2 letter code) +countryName_default = $ENV::EASYRSA_REQ_COUNTRY +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = $ENV::EASYRSA_REQ_PROVINCE + +localityName = Locality Name (eg, city) +localityName_default = $ENV::EASYRSA_REQ_CITY + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = $ENV::EASYRSA_REQ_ORG + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = $ENV::EASYRSA_REQ_OU + +commonName = Common Name (eg: your user, host, or server name) +commonName_max = 64 +commonName_default = $ENV::EASYRSA_REQ_CN + +emailAddress = Email Address +emailAddress_default = $ENV::EASYRSA_REQ_EMAIL +emailAddress_max = 64 + +#################################################################### +# Easy-RSA cert extension handling + +# This section is effectively unused as the main script sets extensions +# dynamically. This core section is left to support the odd usecase where +# a user calls openssl directly. +[ basic_exts ] +basicConstraints = CA:FALSE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always + +# The Easy-RSA CA extensions +[ easyrsa_ca ] + +# PKIX recommendations: + +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always + +# This could be marked critical, but it's nice to support reading by any +# broken clients who attempt to do so. +basicConstraints = CA:true + +# Limit key usage to CA tasks. If you really want to use the generated pair as +# a self-signed cert, comment this out. +keyUsage = cRLSign, keyCertSign + +# nsCertType omitted by default. Let's try to let the deprecated stuff die. +# nsCertType = sslCA + +# CRL extensions. +[ crl_ext ] + +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always,issuer:always + diff --git a/OpenVPN/CA Server/easy-rsa/pki/private/ca.key b/OpenVPN/CA Server/easy-rsa/pki/private/ca.key new file mode 100644 index 0000000..f476879 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/private/ca.key @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIw1tnGvuox6gCAggA +MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBdDd6JgGX1841NPsv9frZUBIIE +0HitEQ592ib/cprXIIKYNhpwikw5qFuaJh2ZyVLM6AUiBGLguWvebis/fhvXClDz +KjZsljyEoC8IIwBvTsavDvNdhUe2DLmA7D8u6bhTUY73dLbOudEsf8ddZu99pYRL +MD1sOawfvacCzazDhqjiZBnRDv+2G19bCX9dtb2yK+44ybMFD57k4uYBBkrxyzWR +5rJJVlSi2WQ0OLEg9pFZ66cp8wZPn9+vChsXP4MnTP+8Gvx4o1gdFmRENvgUL+rR +edf8gUKsbmOqTTv4upiydaT0D6knjdS/QfacGe+d61RS9PtidEMFVfqnSDO2VIkO +7DvyYP8RYiJv7QO9RZ7/yi/DGK0Ha25azAQuntSHH2f+zGb99PRxypOZY9iiKqs4 +u0oAUaZETWZ7DPlc0sEIT8TwPEeAuNremllIt5w+9PdqBjA1CMTdA2b8Gn+FUuIh +wKeSgW++WnCWGYQfkE9rKDYdDCjNhnvDM2t379OKC+Kv0aEUnLdaf7Spvd43VrQm +hmz2cXMr4UkMmxk9vZ94mIo+ArVO4gzVam+IOlwr1QOLd1rijFkx4kLOSI9RiMAL +202lML0mT0tPyc1LxeVdjvvU+R4CaUG37VvkyLvV4FkS4A3UnQqV6JYsjby1vAB5 +npJSPDQ7w9fklskkqK9UM2W5r4r9+sC7bSOq/iXbJpe+dzh29voKj3TbYVDqX3DE +c1SGI3K6rmD6WVWNgP+QMv2gqw90tQKVEikzRyC0A/oWgKtR8gt3AiKCsmDbbVru +sWh4QZJ1ebGQ3IFQG1HzCPu4m0My8zhqM1H+UnLay2s/GSS0o2S6iiH+Fp9t7zWv ++Jl3l5+9A0wkUbuabLyxEkyNEljwbLg7UTSLrPfU4rEKOjItiaa4Hbl89RLWhAr0 +I1rWbEEv+ODDkX2jGjsFK2EvTsIcN2meUekmFe0VhRq8UH/jCQG2ACrft7/UtrC1 +s9astkSNhftBH6huXzslPLay/AIb9wZAmuGUwfBHZmwB+D7invh7Uc7L0GlwQkAl +az5L0V97u3Fr9qvuq0ImOnvzxo7TGx6+EBtoXU1aXxcGYX0jfpSyUJ//50zXhhp5 +uERwoy+VPmJjBbVsfyCTiSKWEM3eA0pTM2Z2gQ+65J7NEvqgvCNTVl4bomBnudQI +7y6qX4EEJQDQDy7BrX9FzdxCzvT3VUXAFtDZb5dQTiiwoUi4aAnB4oSrF/fdSUuS +UXWkQDOyvrbuitleHV0lf0qC4sdzo96KJvzd7884nNfHClQdYHkO4qridNCb1hax +5hntKqMwzYun4Ts3ZhlBOoKvQ4QCH4yNtc4K6CBm/ivjY51Cf8LBx1yHa1p3H9ix +pVrqHiAIBjTrQf8AZKs0JS3EZo4cbulXFkyGDZaSGlC2BL5Pvs3ICXxhTmzUNYa4 +y4FZ3COTrRXk7lkS7Edh/eh17Xu4xvHH7Zf1vHqaBzRFL9BMcdNqXlPev3OESSCe +1XE2xba0GH9NKWlXwgu0zLPvrjygnQ3Z3E6irQvrZ0VIAeW9wW4dpbwKST+sxXMX +Kgel1WvSa7iPozLH75ia9YMw5jXi8NBip9nSRqHQqMVBoaHNlXhaUxXLmF2sk2kp +Tk4jKqLKc39QtjsetqfzUTVmIcLqXteC+BjjOIBCOtJD +-----END ENCRYPTED PRIVATE KEY----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/reqs/DO_server.req b/OpenVPN/CA Server/easy-rsa/pki/reqs/DO_server.req new file mode 100644 index 0000000..1d0b0f9 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/reqs/DO_server.req @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBDDCBkwIBADAUMRIwEAYDVQQDDAlET19zZXJ2ZXIwdjAQBgcqhkjOPQIBBgUr +gQQAIgNiAAQuCojiA60UOu4AUZY+9ewky9ZbjdZdD9+SCJcZ27CNwp3WxqJZLpTU +2dAQ+M3ZPJCA6GGImr6s+M7SRH8hmP/XU0gm1hhvjw1h0zb2IDAYZ2Zh9yXa7nb1 +qxbL/UBSlTygADAKBggqhkjOPQQDBANoADBlAjBre9V6PcQqQZs3zymemhYWPiJp +CCXGC4I8MOnjVlSdeCgl2SKvxRx+87Ywvr1o8hQCMQCPuQ+ntCc1yCGOJ9JlDCE0 +rxa71Os35Ma78TK+vuW/bv1zrTSoHxgJpCrnJS0V21o= +-----END CERTIFICATE REQUEST----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/reqs/Otarcik202501.req b/OpenVPN/CA Server/easy-rsa/pki/reqs/Otarcik202501.req new file mode 100644 index 0000000..ba6deff --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/reqs/Otarcik202501.req @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBEDCBlwIBADAYMRYwFAYDVQQDDA1PdGFyY2lrMjAyNTAxMHYwEAYHKoZIzj0C +AQYFK4EEACIDYgAEQJBHidjsciCVwPuNtxD8Uh2brcFlkeRF1Q8CsDGOVbf6MZqm +Wh/ghc3iIZ08lX+tgPLRY+dBfeSHl36k0efSyT07Zp9S/hFy09feufdB1XsyKwGU +THHL/2V2Zz6uGk5PoAAwCgYIKoZIzj0EAwQDaAAwZQIwRKy3o/Z419Oh8JHDBhEM +x4EAhdueoKp+PK5nKQ1FdI+TbwYSGEgoCpc5bjQB0TkVAjEAnV9R90TWM+kSr+R3 +XUkUyfdkukpHyRMmH7HINp/hDf2idPQHdpm+y4CgtNpmTShp +-----END CERTIFICATE REQUEST----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/reqs/edgerouterchambly.req b/OpenVPN/CA Server/easy-rsa/pki/reqs/edgerouterchambly.req new file mode 100644 index 0000000..2622351 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/reqs/edgerouterchambly.req @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBFDCBmwIBADAcMRowGAYDVQQDDBFlZGdlcm91dGVyY2hhbWJseTB2MBAGByqG +SM49AgEGBSuBBAAiA2IABA79HGCDX6dkeaA1dN/AY2jFPLEClalzWKmjdMzYW9h6 +q6rTH0EtaIa9L+Nsc7XoAXO0EvRx3d3Lm06w8dQEANFgz/7qPKXyru6qRaMhceXS +t/AiMMTUJ1h5lmzwXLqWGaAAMAoGCCqGSM49BAMEA2gAMGUCMCvrCc8hUdJ+NdGi +64TnDwHJ9Kl1HDBmW3fxYJzjXzBAY8ZhgLuw2Bn4GqIUYtdhqgIxAM5GStvPR0iy +Qp7iXmjAhg15YQL2hm/qckmm3S7SwMGMKqZkQvBk/XafYZe8VajM0Q== +-----END CERTIFICATE REQUEST----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/reqs/fred.req b/OpenVPN/CA Server/easy-rsa/pki/reqs/fred.req new file mode 100644 index 0000000..0518ab2 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/reqs/fred.req @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBCDCBjgIBADAPMQ0wCwYDVQQDDARmcmVkMHYwEAYHKoZIzj0CAQYFK4EEACID +YgAEPnjvJtmHu4sIR/4VrZau9JPx2M7jBdKWRvz2R8msQfUBG+MlYfTub40T3asb +2AKFo/tSPQLYrQvt4wKIx+sGUsolrIus61JMQ1L5wIz0SOpypib3XwKWl60QrG3I +07EooAAwCgYIKoZIzj0EAwQDaQAwZgIxAJmONNtX7d0nhO1ExxBRWzyjsripBfo2 +pzMXN/wL70YmZ/JiVDB9FcZGKCGkqxGPUAIxAJQ766zGfSReyVeBWWkzZJQvhU7o +RNP2pIhWmCneLhb0hkiIxkgNm/ZQmHD1WCuT3w== +-----END CERTIFICATE REQUEST----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/reqs/jf.req b/OpenVPN/CA Server/easy-rsa/pki/reqs/jf.req new file mode 100644 index 0000000..0583972 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/reqs/jf.req @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBBjCBjAIBADANMQswCQYDVQQDDAJqZjB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BI046k8pvYOpM6McM4pgj/oZgQBzRIGYHnYF7vZG1SWoxTu91vrPxnngtEIngOKW +LTBQwvacLBP4uUazDZZsm9JFFaPwTLxrUUX4y1kEsdBHuZAGccfrNDLichSElFjj +NKAAMAoGCCqGSM49BAMEA2kAMGYCMQCavWzeG/WWhQ6wkIJC72oie/5xCwYGrlSP +b4ijDgJlmyQfy920wbDcTLWFJ26lpeYCMQC2FDVLQ+AjZnsWvVkPWl2j10VfRQxF +lPJnbb+ajusWy7qLdOFeLWVKeQCYL2s1aMc= +-----END CERTIFICATE REQUEST----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/reqs/pascal.req b/OpenVPN/CA Server/easy-rsa/pki/reqs/pascal.req new file mode 100644 index 0000000..6369a0e --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/reqs/pascal.req @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBCTCBkAIBADARMQ8wDQYDVQQDDAZwYXNjYWwwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAARu1/wpqCNwKElwgvQaT/zoWtMQhO8KWdk+MS5fkYuXfjLF5Jqx34tmgvel +Wm2Quk1LdU4bCTc7I1vfuAiJx6DWO/o++LEIGKbuJQIlssVD7vUDgp45oILQI0nr +/r4+j3qgADAKBggqhkjOPQQDBANoADBlAjEA4IhMIxWjsYamRn2jr0X0Z2ilUyC6 +IaPo9mE7gLQNxvvNlksKBlrIcOMoqp4RX58mAjAqGNEb63KjrKwaCVzbjiF4h4dg +c3PYjObVjwTwWQKSNHReGrqhgjCcrcAbK5pdofs= +-----END CERTIFICATE REQUEST----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/reqs/remoteclient.req b/OpenVPN/CA Server/easy-rsa/pki/reqs/remoteclient.req new file mode 100644 index 0000000..1815e88 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/reqs/remoteclient.req @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBEDCBlgIBADAXMRUwEwYDVQQDDAxyZW1vdGVjbGllbnQwdjAQBgcqhkjOPQIB +BgUrgQQAIgNiAARl6YY1AcPXDhY9iZA8y6Bf0gT3tjKEHqDcah0WoG9Ho7V9TDm9 +0HAYNOgWZ9RbTMrO6vB1X1VyCUv13YDx1dvmJgnkNDvKifM6QJExFMb/Bo2O+bqP +R99AQfRrhPjl6HCgADAKBggqhkjOPQQDBANpADBmAjEAorG1junRTCsKjo5zCAi/ +VCT/LtoDyb3xpxDaTFX33WCB77AFc5m4PZ8w43sldxHQAjEAutGviIFXdGI/HM0g +Q7lGg4ch2v0y6SbZA7Fphp5FX1w/8uR7lvMBOSCE3KbnS5on +-----END CERTIFICATE REQUEST----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/reqs/stationKA2401.req b/OpenVPN/CA Server/easy-rsa/pki/reqs/stationKA2401.req new file mode 100644 index 0000000..fef23ab --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/reqs/stationKA2401.req @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBDzCBlwIBADAYMRYwFAYDVQQDDA1zdGF0aW9uS0EyNDAxMHYwEAYHKoZIzj0C +AQYFK4EEACIDYgAEj08ma6/LSQt0PmWqDpqaV5mx9r/cdK7Wcu3TqAQvqKBDY/bI +4s3c2P2/aZMJ170Rq9nFriC8AKzXrer7wB5Eb7ogY50y9ziPwNe/tCMVFk2EWRPV +S96ee0bTzrpd2VPEoAAwCgYIKoZIzj0EAwQDZwAwZAIwMhPuY2cvcd/nxcmEJjqV +5H+FLyOW+xTOFIF2EIptJqMw2fUt8xFg1A6S/m7FNG/nAjAVTYLqYdy7xw/o7Lz8 +v5nTfxE1n2YsApc9ZmnrZOMiDPdWLMV5U8t+b3Vn574Tetc= +-----END CERTIFICATE REQUEST----- diff --git a/OpenVPN/CA Server/easy-rsa/pki/safessl-easyrsa.cnf b/OpenVPN/CA Server/easy-rsa/pki/safessl-easyrsa.cnf new file mode 100644 index 0000000..2995628 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/safessl-easyrsa.cnf @@ -0,0 +1,138 @@ +# For use with Easy-RSA 3.0+ and OpenSSL or LibreSSL + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = /home/jfmartel/easy-rsa/pki # Where everything is kept +certs = /home/jfmartel/easy-rsa/pki # Where the issued certs are kept +crl_dir = /home/jfmartel/easy-rsa/pki # Where the issued crl are kept +database = /home/jfmartel/easy-rsa/pki/index.txt # database index file. +new_certs_dir = /home/jfmartel/easy-rsa/pki/certs_by_serial # default place for new certs. + +certificate = /home/jfmartel/easy-rsa/pki/ca.crt # The CA certificate +serial = /home/jfmartel/easy-rsa/pki/serial # The current serial number +crl = /home/jfmartel/easy-rsa/pki/crl.pem # The current CRL +private_key = /home/jfmartel/easy-rsa/pki/private/ca.key # The private key +RANDFILE = /home/jfmartel/easy-rsa/pki/.rand # private random number file + +x509_extensions = basic_exts # The extensions to add to the cert + +# This allows a V2 CRL. Ancient browsers don't like it, but anything Easy-RSA +# is designed for will. In return, we get the Issuer attached to CRLs. +crl_extensions = crl_ext + +default_days = 825 # how long to certify for +default_crl_days= 180 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# This allows to renew certificates which have not been revoked +unique_subject = no + +# A few different ways of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_anything + +# For the 'anything' policy, which defines allowed DN fields +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +name = optional +emailAddress = optional + +#################################################################### +# Easy-RSA request handling +# We key off $DN_MODE to determine how to format the DN +[ req ] +default_bits = 2048 +default_keyfile = privkey.pem +default_md = sha256 +distinguished_name = cn_only +x509_extensions = easyrsa_ca # The extensions to add to the self signed cert + +# A placeholder to handle the $EXTRA_EXTS feature: +#%EXTRA_EXTS% # Do NOT remove or change this line as $EXTRA_EXTS support requires it + +#################################################################### +# Easy-RSA DN (Subject) handling + +# Easy-RSA DN for cn_only support: +[ cn_only ] +commonName = Common Name (eg: your user, host, or server name) +commonName_max = 64 +commonName_default = ChangeMe + +# Easy-RSA DN for org support: +[ org ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = California + +localityName = Locality Name (eg, city) +localityName_default = San Francisco + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Copyleft Certificate Co + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = My Organizational Unit + +commonName = Common Name (eg: your user, host, or server name) +commonName_max = 64 +commonName_default = ChangeMe + +emailAddress = Email Address +emailAddress_default = me@example.net +emailAddress_max = 64 + +#################################################################### +# Easy-RSA cert extension handling + +# This section is effectively unused as the main script sets extensions +# dynamically. This core section is left to support the odd usecase where +# a user calls openssl directly. +[ basic_exts ] +basicConstraints = CA:FALSE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always + +# The Easy-RSA CA extensions +[ easyrsa_ca ] + +# PKIX recommendations: + +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always + +# This could be marked critical, but it's nice to support reading by any +# broken clients who attempt to do so. +basicConstraints = CA:true + +# Limit key usage to CA tasks. If you really want to use the generated pair as +# a self-signed cert, comment this out. +keyUsage = cRLSign, keyCertSign + +# nsCertType omitted by default. Let's try to let the deprecated stuff die. +# nsCertType = sslCA + +# CRL extensions. +[ crl_ext ] + +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always,issuer:always + diff --git a/OpenVPN/CA Server/easy-rsa/pki/serial b/OpenVPN/CA Server/easy-rsa/pki/serial new file mode 100644 index 0000000..ccab6ef --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/serial @@ -0,0 +1 @@ +44E31288C38E1632F41EBB13CA4D4C8E diff --git a/OpenVPN/CA Server/easy-rsa/pki/serial.old b/OpenVPN/CA Server/easy-rsa/pki/serial.old new file mode 100644 index 0000000..172d897 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/pki/serial.old @@ -0,0 +1 @@ +44e31288c38e1632f41ebb13ca4d4c8d diff --git a/OpenVPN/CA Server/easy-rsa/vars b/OpenVPN/CA Server/easy-rsa/vars new file mode 100644 index 0000000..c08d3fc --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/vars @@ -0,0 +1,9 @@ +set_var EASYRSA_REQ_COUNTRY "CA" +set_var EASYRSA_REQ_PROVINCE "Quebec" +set_var EASYRSA_REQ_CITY "Montreal" +set_var EASYRSA_REQ_ORG "GrosGin" +set_var EASYRSA_REQ_EMAIL "jean-francois@jfmartel.ca" +set_var EASYRSA_REQ_OU "Community" +set_var EASYRSA_ALGO "ec" +set_var EASYRSA_DIGEST "sha512" +set_var EASYRSA_CERT_EXPIRE 3600 diff --git a/OpenVPN/CA Server/easy-rsa/vars.example b/OpenVPN/CA Server/easy-rsa/vars.example new file mode 100644 index 0000000..f62f4b1 --- /dev/null +++ b/OpenVPN/CA Server/easy-rsa/vars.example @@ -0,0 +1,221 @@ +# Easy-RSA 3 parameter settings + +# NOTE: If you installed Easy-RSA from your distro's package manager, don't edit +# this file in place -- instead, you should copy the entire easy-rsa directory +# to another location so future upgrades don't wipe out your changes. + +# HOW TO USE THIS FILE +# +# vars.example contains built-in examples to Easy-RSA settings. You MUST name +# this file 'vars' if you want it to be used as a configuration file. If you do +# not, it WILL NOT be automatically read when you call easyrsa commands. +# +# It is not necessary to use this config file unless you wish to change +# operational defaults. These defaults should be fine for many uses without the +# need to copy and edit the 'vars' file. +# +# All of the editable settings are shown commented and start with the command +# 'set_var' -- this means any set_var command that is uncommented has been +# modified by the user. If you're happy with a default, there is no need to +# define the value to its default. + +# NOTES FOR WINDOWS USERS +# +# Paths for Windows *MUST* use forward slashes, or optionally double-escaped +# backslashes (single forward slashes are recommended.) This means your path to +# the openssl binary might look like this: +# "C:/Program Files/OpenSSL-Win32/bin/openssl.exe" + +# A little housekeeping: DON'T EDIT THIS SECTION +# +# Easy-RSA 3.x doesn't source into the environment directly. +# Complain if a user tries to do this: +if [ -z "$EASYRSA_CALLER" ]; then + echo "You appear to be sourcing an Easy-RSA 'vars' file." >&2 + echo "This is no longer necessary and is disallowed. See the section called" >&2 + echo "'How to use this file' near the top comments for more details." >&2 + return 1 +fi + +# DO YOUR EDITS BELOW THIS POINT + +# This variable is used as the base location of configuration files needed by +# easyrsa. More specific variables for specific files (e.g., EASYRSA_SSL_CONF) +# may override this default. +# +# The default value of this variable is the location of the easyrsa script +# itself, which is also where the configuration files are located in the +# easy-rsa tree. + +#set_var EASYRSA "${0%/*}" + +# If your OpenSSL command is not in the system PATH, you will need to define the +# path to it here. Normally this means a full path to the executable, otherwise +# you could have left it undefined here and the shown default would be used. +# +# Windows users, remember to use paths with forward-slashes (or escaped +# back-slashes.) Windows users should declare the full path to the openssl +# binary here if it is not in their system PATH. + +#set_var EASYRSA_OPENSSL "openssl" +# +# This sample is in Windows syntax -- edit it for your path if not using PATH: +#set_var EASYRSA_OPENSSL "C:/Program Files/OpenSSL-Win32/bin/openssl.exe" + +# Edit this variable to point to your soon-to-be-created key directory. By +# default, this will be "$PWD/pki" (i.e. the "pki" subdirectory of the +# directory you are currently in). +# +# WARNING: init-pki will do a rm -rf on this directory so make sure you define +# it correctly! (Interactive mode will prompt before acting.) + +#set_var EASYRSA_PKI "$PWD/pki" + +# Define directory for temporary subdirectories. + +#set_var EASYRSA_TEMP_DIR "$EASYRSA_PKI" + +# Define X509 DN mode. +# This is used to adjust what elements are included in the Subject field as the DN +# (this is the "Distinguished Name.") +# Note that in cn_only mode the Organizational fields further below aren't used. +# +# Choices are: +# cn_only - use just a CN value +# org - use the "traditional" Country/Province/City/Org/OU/email/CN format + +#set_var EASYRSA_DN "cn_only" + +# Organizational fields (used with 'org' mode and ignored in 'cn_only' mode.) +# These are the default values for fields which will be placed in the +# certificate. Don't leave any of these fields blank, although interactively +# you may omit any specific field by typing the "." symbol (not valid for +# email.) + +#set_var EASYRSA_REQ_COUNTRY "US" +#set_var EASYRSA_REQ_PROVINCE "California" +#set_var EASYRSA_REQ_CITY "San Francisco" +#set_var EASYRSA_REQ_ORG "Copyleft Certificate Co" +#set_var EASYRSA_REQ_EMAIL "me@example.net" +#set_var EASYRSA_REQ_OU "My Organizational Unit" + +# Choose a size in bits for your keypairs. The recommended value is 2048. Using +# 2048-bit keys is considered more than sufficient for many years into the +# future. Larger keysizes will slow down TLS negotiation and make key/DH param +# generation take much longer. Values up to 4096 should be accepted by most +# software. Only used when the crypto alg is rsa (see below.) + +#set_var EASYRSA_KEY_SIZE 2048 + +# The default crypto mode is rsa; ec can enable elliptic curve support. +# Note that not all software supports ECC, so use care when enabling it. +# Choices for crypto alg are: (each in lower-case) +# * rsa +# * ec +# * ed + +#set_var EASYRSA_ALGO rsa + +# Define the named curve, used in ec & ed modes: + +#set_var EASYRSA_CURVE secp384r1 + +# In how many days should the root CA key expire? + +#set_var EASYRSA_CA_EXPIRE 3650 + +# In how many days should certificates expire? + +#set_var EASYRSA_CERT_EXPIRE 825 + +# How many days until the next CRL publish date? Note that the CRL can still be +# parsed after this timeframe passes. It is only used for an expected next +# publication date. +#set_var EASYRSA_CRL_DAYS 180 + +# How many days before its expiration date a certificate is allowed to be +# renewed? +#set_var EASYRSA_CERT_RENEW 30 + +# Random serial numbers by default, set to no for the old incremental serial numbers +# +#set_var EASYRSA_RAND_SN "yes" + +# Support deprecated "Netscape" extensions? (choices "yes" or "no".) The default +# is "no" to discourage use of deprecated extensions. If you require this +# feature to use with --ns-cert-type, set this to "yes" here. This support +# should be replaced with the more modern --remote-cert-tls feature. If you do +# not use --ns-cert-type in your configs, it is safe (and recommended) to leave +# this defined to "no". When set to "yes", server-signed certs get the +# nsCertType=server attribute, and also get any NS_COMMENT defined below in the +# nsComment field. + +#set_var EASYRSA_NS_SUPPORT "no" + +# When NS_SUPPORT is set to "yes", this field is added as the nsComment field. +# Set this blank to omit it. With NS_SUPPORT set to "no" this field is ignored. + +#set_var EASYRSA_NS_COMMENT "Easy-RSA Generated Certificate" + +# A temp file used to stage cert extensions during signing. The default should +# be fine for most users; however, some users might want an alternative under a +# RAM-based FS, such as /dev/shm or /tmp on some systems. + +#set_var EASYRSA_TEMP_FILE "$EASYRSA_PKI/extensions.temp" + +# !! +# NOTE: ADVANCED OPTIONS BELOW THIS POINT +# PLAY WITH THEM AT YOUR OWN RISK +# !! + +# Broken shell command aliases: If you have a largely broken shell that is +# missing any of these POSIX-required commands used by Easy-RSA, you will need +# to define an alias to the proper path for the command. The symptom will be +# some form of a 'command not found' error from your shell. This means your +# shell is BROKEN, but you can hack around it here if you really need. These +# shown values are not defaults: it is up to you to know what you're doing if +# you touch these. +# +#alias awk="/alt/bin/awk" +#alias cat="/alt/bin/cat" + +# X509 extensions directory: +# If you want to customize the X509 extensions used, set the directory to look +# for extensions here. Each cert type you sign must have a matching filename, +# and an optional file named 'COMMON' is included first when present. Note that +# when undefined here, default behaviour is to look in $EASYRSA_PKI first, then +# fallback to $EASYRSA for the 'x509-types' dir. You may override this +# detection with an explicit dir here. +# +#set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types" + +# If you want to generate KDC certificates, you need to set the realm here. +#set_var EASYRSA_KDC_REALM "CHANGEME.EXAMPLE.COM" + +# OpenSSL config file: +# If you need to use a specific openssl config file, you can reference it here. +# Normally this file is auto-detected from a file named openssl-easyrsa.cnf from the +# EASYRSA_PKI or EASYRSA dir (in that order.) NOTE that this file is Easy-RSA +# specific and you cannot just use a standard config file, so this is an +# advanced feature. + +#set_var EASYRSA_SSL_CONF "$EASYRSA/openssl-easyrsa.cnf" + +# Default CN: +# This is best left alone. Interactively you will set this manually, and BATCH +# callers are expected to set this themselves. + +#set_var EASYRSA_REQ_CN "ChangeMe" + +# Cryptographic digest to use. +# Do not change this default unless you understand the security implications. +# Valid choices include: md5, sha1, sha256, sha224, sha384, sha512 + +#set_var EASYRSA_DIGEST "sha256" + +# Batch mode. Leave this disabled unless you intend to call Easy-RSA explicitly +# in batch mode without any user input, confirmation on dangerous operations, +# or most output. Setting this to any non-blank string enables batch mode. + +#set_var EASYRSA_BATCH "" + diff --git a/OpenVPN/ccd/Otarcik202501 b/OpenVPN/ccd/Otarcik202501 new file mode 100644 index 0000000..44aeecd --- /dev/null +++ b/OpenVPN/ccd/Otarcik202501 @@ -0,0 +1 @@ +iroute 192.168.12.0 255.255.255.0 diff --git a/OpenVPN/ccd/remoteclient b/OpenVPN/ccd/remoteclient new file mode 100644 index 0000000..36ef015 --- /dev/null +++ b/OpenVPN/ccd/remoteclient @@ -0,0 +1 @@ +iroute 192.168.10.0 255.255.255.0 diff --git a/OpenVPN/ccd/stationKA2401 b/OpenVPN/ccd/stationKA2401 new file mode 100644 index 0000000..35a471e --- /dev/null +++ b/OpenVPN/ccd/stationKA2401 @@ -0,0 +1 @@ +iroute 192.168.11.0 255.255.255.0 diff --git a/OpenVPN/jf2.ovpn b/OpenVPN/jf2.ovpn new file mode 100644 index 0000000..ca444fd --- /dev/null +++ b/OpenVPN/jf2.ovpn @@ -0,0 +1,269 @@ +############################################## +# Sample client-side OpenVPN 2.0 config file # +# for connecting to multi-client server. # +# # +# This configuration can be used by multiple # +# clients, however each client should have # +# its own cert and key files. # +# # +# On Windows, you might want to rename this # +# file so it has a .ovpn extension # +############################################## + +# Specify that we are a client and that we +# will be pulling certain config file directives +# from the server. +client + +# Use the same setting as you are using on +# the server. +# On most systems, the VPN will not function +# unless you partially or fully disable +# the firewall for the TUN/TAP interface. +;dev tap +dev tun + +# Windows needs the TAP-Win32 adapter name +# from the Network Connections panel +# if you have more than one. On XP SP2, +# you may need to disable the firewall +# for the TAP adapter. +;dev-node MyTap + +# Are we connecting to a TCP or +# UDP server? Use the same setting as +# on the server. +;proto tcp +proto udp + +# The hostname/IP and port of the server. +# You can have multiple remote entries +# to load balance between the servers. +remote vpn.yultek.dev 1194 +;remote 138.197.151.172 1194 +;remote my-server-2 1194 + +# Choose a random host from the remote +# list for load-balancing. Otherwise +# try hosts in the order specified. +;remote-random + +# Keep trying indefinitely to resolve the +# host name of the OpenVPN server. Very useful +# on machines which are not permanently connected +# to the internet such as laptops. +resolv-retry infinite + +# Most clients don't need to bind to +# a specific local port number. +nobind + +# Downgrade privileges after initialization (non-Windows only) +;user nobody +;group nobody + +# Try to preserve some state across restarts. +persist-key +persist-tun + +# If you are connecting through an +# HTTP proxy to reach the actual OpenVPN +# server, put the proxy server/IP and +# port number here. See the man page +# if your proxy server requires +# authentication. +;http-proxy-retry # retry on connection failures +;http-proxy [proxy server] [proxy port #] + +# Wireless networks often produce a lot +# of duplicate packets. Set this flag +# to silence duplicate packet warnings. +;mute-replay-warnings + +# SSL/TLS parms. +# See the server config file for more +# description. It's best to use +# a separate .crt/.key file pair +# for each client. A single ca +# file can be used for all clients. +;ca ca.crt +;cert client.crt +;key client.key + +# Verify server certificate by checking that the +# certificate has the correct key usage set. +# This is an important precaution to protect against +# a potential attack discussed here: +# http://openvpn.net/howto.html#mitm +# +# To use this feature, you will need to generate +# your server certificates with the keyUsage set to +# digitalSignature, keyEncipherment +# and the extendedKeyUsage to +# serverAuth +# EasyRSA can do this for you. +remote-cert-tls server + +# If a tls-auth key is used on the server +# then every client must also have the key. +;tls-auth ta.key 1 + +# Select a cryptographic cipher. +# If the cipher option is used on the server +# then you must also specify it here. +# Note that v2.4 client/server will automatically +# negotiate AES-256-GCM in TLS mode. +# See also the data-ciphers option in the manpage +cipher AES-256-GCM +auth SHA256 + +# Enable compression on the VPN link. +# Don't enable this unless it is also +# enabled in the server config file. +#comp-lzo + +# Set log file verbosity. +verb 3 + +# Silence repeating messages +;mute 20 + +key-direction 1 + + +; script-security 2 +; up /etc/openvpn/update-resolv-conf +; down /etc/openvpn/update-resolv-conf + + +; script-security 2 +; up /etc/openvpn/update-systemd-resolved +; down /etc/openvpn/update-systemd-resolved +; down-pre +; dhcp-option DOMAIN-ROUTE . + +-----BEGIN CERTIFICATE----- +MIIDRTCCAi2gAwIBAgIUXe37kz2yqgyL2xXfvaGRzlz7ywYwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJSkZfc2VydmVyMB4XDTIzMDIyMDIyMDkyMVoXDTMzMDIx +NzIyMDkyMVowFDESMBAGA1UEAwwJSkZfc2VydmVyMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAnLdVAj0W31TtWGxwdBeqsdIHyUdVAEG8bX+CcNZDP3M3 +R/gJOmenjqsqHYBe5gZcky1hkqWaD7l/LNmyzZDZ1lVEWpcAZqxbsUZKiHU30bxq +84L5qtaAOpwTsumidq2hBqoDBMdBmh18e0QEW624mui7ckXTRRG3PA0ccXtXcTYU +ntmhYtQ2oaPauSmfJZIUfZTfVZbB8FkCgu+zJtCx5hq46vIHm8KX0m1zLIeUtGsI +hkly+5v52f3sEMlddyoZZkfjRddETk2co09q3oNaP1LYxN5G+TvZDhpdE+PrDsNT +wO4uU2d9hVIP3T49heLieZ6KVxyp1FsDYzo0CNlIDwIDAQABo4GOMIGLMB0GA1Ud +DgQWBBSKeJDl8FDnjHXkuMCh6OmbshqdMjBPBgNVHSMESDBGgBSKeJDl8FDnjHXk +uMCh6OmbshqdMqEYpBYwFDESMBAGA1UEAwwJSkZfc2VydmVyghRd7fuTPbKqDIvb +Fd+9oZHOXPvLBjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B +AQsFAAOCAQEARIg2x4Tit/6ZydMlle6ku32t75OMCVQoe7fUkRjNe8pCkZjZXLy9 +QIRwoqW3FRT8+mQjctZk3NsyLStF8Rc/fFvpjGY/hiEQ/RV1K2/IZ9hcswp/LRzQ +ElDwXhe4zlcDT10GjHYYx221SR+ijgicZcaXgb9f3uZKIrPgyb8qB4KCQS8gPtCV +1VmPM5/svVCI93G+xT92XBHa47fgV5GEn7Snah2UgFol5h7/KX/Sa2q0pfBlzqmt +CutfEbYcwSxkoLsEUIW8KMoEAIsO+KIsraS6EXlRdT82Ui+UZWVPZABlzifCl+AV +LzBrLwt2OeoEI1h65EyzzE7gDsjrE3JR/Q== +-----END CERTIFICATE----- + + +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 49:6e:3c:e9:b5:30:c1:6a:89:b2:c8:b1:e9:96:32:9c + Signature Algorithm: sha512WithRSAEncryption + Issuer: CN=JF_server + Validity + Not Before: May 12 20:06:31 2025 GMT + Not After : Mar 21 20:06:31 2035 GMT + Subject: CN=jf2 + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (384 bit) + pub: + 04:53:3d:55:81:8e:b0:b2:39:47:1b:62:d6:1b:4f: + 78:5d:02:48:c2:00:0a:80:08:74:d7:3a:da:c5:b4: + e5:fc:f6:c6:ad:25:b2:20:03:37:9d:99:67:20:81: + 6b:87:69:e3:06:a6:7f:b7:3b:79:30:33:0c:78:c1: + 9a:a2:fc:59:22:89:3c:ff:f1:ec:41:52:e7:0a:51: + a9:39:6d:72:40:ec:d0:fb:16:1a:f6:31:cb:2a:a3: + 9b:e9:35:af:b2:6f:9e + ASN1 OID: secp384r1 + NIST CURVE: P-384 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + B4:87:90:DC:D8:E1:64:DE:A9:92:1A:99:12:9C:27:62:CF:35:7C:24 + X509v3 Authority Key Identifier: + keyid:8A:78:90:E5:F0:50:E7:8C:75:E4:B8:C0:A1:E8:E9:9B:B2:1A:9D:32 + DirName:/CN=JF_server + serial:5D:ED:FB:93:3D:B2:AA:0C:8B:DB:15:DF:BD:A1:91:CE:5C:FB:CB:06 + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha512WithRSAEncryption + Signature Value: + 87:0c:f2:91:fe:7f:b9:c4:9f:8e:b1:72:0d:77:35:fe:53:a7: + 6e:ec:70:14:ad:40:f3:b7:63:8c:e1:ab:97:11:0d:2e:9b:23: + 4d:57:36:b1:8c:f5:85:cd:a2:23:af:f5:be:1d:7e:67:f6:95: + f0:83:99:d4:f9:d6:e9:fb:c6:9f:1c:e4:8c:f7:6a:ab:50:de: + 68:50:24:69:7c:bc:41:55:c2:a2:b6:32:9c:41:19:6d:42:4c: + 42:89:fe:4e:08:3d:9c:50:db:ff:e8:e5:47:5d:a8:ba:c3:03: + 7a:ea:30:7d:00:e2:a2:de:36:23:1d:63:01:50:9d:f9:04:9c: + bb:51:f7:6a:0e:8a:3a:23:45:5c:d2:69:0a:1c:e1:6d:98:b0: + e9:31:a5:4e:4b:f6:c5:93:f1:21:e7:a9:8a:e6:21:2f:e8:35: + 34:86:48:a8:54:6b:77:47:b7:84:44:04:09:84:4f:20:5a:ce: + 0b:9b:29:c1:84:a6:1e:22:9f:6f:73:23:ff:a4:d3:90:3b:86: + f1:f1:37:45:04:2b:2c:e5:ab:c7:e7:ad:db:e2:3f:6f:27:2f: + 90:78:5c:fc:cb:ca:c2:8e:31:2f:01:21:3e:20:0a:b9:a0:5a: + 91:9a:46:21:b8:11:07:49:01:df:20:fc:23:08:f6:a2:4f:46: + f0:fc:01:f5 +-----BEGIN CERTIFICATE----- +MIICnzCCAYegAwIBAgIQSW486bUwwWqJssix6ZYynDANBgkqhkiG9w0BAQ0FADAU +MRIwEAYDVQQDDAlKRl9zZXJ2ZXIwHhcNMjUwNTEyMjAwNjMxWhcNMzUwMzIxMjAw +NjMxWjAOMQwwCgYDVQQDDANqZjIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARTPVWB +jrCyOUcbYtYbT3hdAkjCAAqACHTXOtrFtOX89satJbIgAzedmWcggWuHaeMGpn+3 +O3kwMwx4wZqi/FkiiTz/8exBUucKUak5bXJA7ND7Fhr2Mcsqo5vpNa+yb56jgaAw +gZ0wCQYDVR0TBAIwADAdBgNVHQ4EFgQUtIeQ3NjhZN6pkhqZEpwnYs81fCQwTwYD +VR0jBEgwRoAUiniQ5fBQ54x15LjAoejpm7IanTKhGKQWMBQxEjAQBgNVBAMMCUpG +X3NlcnZlcoIUXe37kz2yqgyL2xXfvaGRzlz7ywYwEwYDVR0lBAwwCgYIKwYBBQUH +AwIwCwYDVR0PBAQDAgeAMA0GCSqGSIb3DQEBDQUAA4IBAQCHDPKR/n+5xJ+OsXIN +dzX+U6du7HAUrUDzt2OM4auXEQ0umyNNVzaxjPWFzaIjr/W+HX5n9pXwg5nU+dbp ++8afHOSM92qrUN5oUCRpfLxBVcKitjKcQRltQkxCif5OCD2cUNv/6OVHXai6wwN6 +6jB9AOKi3jYjHWMBUJ35BJy7UfdqDoo6I0Vc0mkKHOFtmLDpMaVOS/bFk/Eh56mK +5iEv6DU0hkioVGt3R7eERAQJhE8gWs4LmynBhKYeIp9vcyP/pNOQO4bx8TdFBCss +5avH563b4j9vJy+QeFz8y8rCjjEvASE+IAq5oFqRmkYhuBEHSQHfIPwjCPaiT0bw +/AH1 +-----END CERTIFICATE----- + + +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBQv7N0YKNvqQhnUyHe +Dy00OLK8iRi1Zx3nC1QTTxNQKBDeXdg4EkRuY0By77lArkOhZANiAARTPVWBjrCy +OUcbYtYbT3hdAkjCAAqACHTXOtrFtOX89satJbIgAzedmWcggWuHaeMGpn+3O3kw +Mwx4wZqi/FkiiTz/8exBUucKUak5bXJA7ND7Fhr2Mcsqo5vpNa+yb54= +-----END PRIVATE KEY----- + + +# +# 2048 bit OpenVPN static key +# +-----BEGIN OpenVPN Static key V1----- +4c828cbf0e58f927758e9471c1b6f03b +2e77b2c634bad76df0570dd8f47184d6 +3921e25c6e6cbe4af4b64aad89d12425 +a9fca69ae08802b5ed583632c26678b0 +cc28c481c3831d1b2204dc30cd466395 +ccb8cd82cd2259c956b510c9a56e842a +8693c44dca462f0ab7be3856abe9bbe1 +95a6ffd3b0237225b9497c7a0df05ad8 +2f2e0a8bff97c927d2890906d0105947 +fa3430fc779583772382534fb880add6 +8d5592fa4ff384d3e96c560019b5835f +095da9b2fb33dbfbc1ffce9560908271 +ee96e02ccecc9d51b9dda79a77704a1d +4407d7c805e6950854fe232adee02a12 +b09af2d9bfe04868a9e2e942dc64eb81 +9e062ab9f781e52d263195a58db72ebe +-----END OpenVPN Static key V1----- + diff --git a/OpenVPN/server.conf b/OpenVPN/server.conf index aa857ec..4d023df 100644 --- a/OpenVPN/server.conf +++ b/OpenVPN/server.conf @@ -139,17 +139,9 @@ ifconfig-pool-persist /var/log/openvpn/ipp.txt # to know to route the OpenVPN client # address pool (10.8.0.0/255.255.255.0) # back to the OpenVPN server. - -# Route le subnet de la station Otarcik 2023 push "route 192.168.10.0 255.255.255.0" - -# Route le subnet de la statio Kayak push "route 192.168.11.0 255.255.255.0" - -#route le subnet de la station Otarcik 2025 push "route 192.168.12.0 255.255.255.0" - - ;push "route 192.168.30.0 255.255.255.0" # To assign specific IP addresses to specific @@ -167,6 +159,7 @@ client-config-dir ccd ;route 192.168.40.128 255.255.255.248 route 192.168.10.0 255.255.255.0 route 192.168.11.0 255.255.255.0 +route 192.168.12.0 255.255.255.0 # Then create a file ccd/Thelonious with this line: # iroute 192.168.40.128 255.255.255.248 diff --git a/Otarcik_CAN/Config/Station.cfg b/Otarcik_CAN/Config/Station.cfg index 6e96e215fdaf13e6ca5e8447762c0f60f24629f3..49a7610254e98a340624976220de05d4ef8e8162 100644 GIT binary patch delta 25 fcmX@gx|emsVMbma25*K$hDspLW{97BgYhi@VI>E{ delta 33 mcmdnXdX#m;VMb9A25*K$hDspLW{77nVlV(=)5#YY-vR)XA_$ZK diff --git a/Otarcik_CAN/Logs/SystemLog.txt b/Otarcik_CAN/Logs/SystemLog.txt index a75fbe2..d5f0a5e 100644 --- a/Otarcik_CAN/Logs/SystemLog.txt +++ b/Otarcik_CAN/Logs/SystemLog.txt @@ -1952,3 +1952,39 @@ Démarrage du logiciel Otarcik CAN version 1.08 le 2025-05-03 à 20:08:02 2025-05-03 20:08:07 Client MQTT metrics.yultek.dev déconnecté. 2025-05-03 20:08:07 Passage en mode buffering des messages MQTT pour metrics.yultek.dev 2025-05-03 20:08:07 Client MQTT 192.168.51.32 déconnecté. + + +******************************************************************** +Démarrage du logiciel Otarcik CAN version 1.08 le 2025-05-08 à 13:37:29 +******************************************************************** +2025-05-08 13:37:29 Chargement de la configuration système... +2025-05-08 13:37:29 Configuration système chargée avec succès! +2025-05-08 13:37:29 Initialisation du dispositif [MasterCAN] +2025-05-08 13:37:29 Démarrage d'un module CAN... +2025-05-08 13:37:29 Impossible de trouver le module CAN sur le channel 1 +2025-05-08 13:37:29 Démarrage du Watchdog CAN... +2025-05-08 13:37:29 Watchdog CAN initialisé pour le module sur le channel 1 +2025-05-08 13:37:29 Démarrage du logiciel OtarcikCAN +2025-05-08 13:37:29 Client MQTT metrics.yultek.dev en cours de connexion... +2025-05-08 13:37:29 Client MQTT 192.168.51.32 en cours de connexion... +2025-05-08 13:37:30 Client MQTT 192.168.51.32 connecté. +2025-05-08 13:37:30 LAN Device 192.168.51.2 is now ONLINE on network +2025-05-08 13:37:30 LAN Device 192.168.50.100 is now ONLINE on network +2025-05-08 13:37:30 LAN Device 192.168.50.1 is now ONLINE on network +2025-05-08 13:37:30 LAN Device 192.168.51.32 is now ONLINE on network +2025-05-08 13:37:30 LAN Device 192.168.50.110 is now ONLINE on network +2025-05-08 13:37:30 Client MQTT metrics.yultek.dev connecté. +2025-05-08 13:37:30 Internet Connecté... +2025-05-08 13:37:40 Client MQTT 192.168.51.32 déconnecté. +2025-05-08 13:37:48 Client MQTT metrics.yultek.dev déconnecté. +2025-05-08 13:37:48 Passage en mode buffering des messages MQTT pour metrics.yultek.dev +2025-05-08 13:37:48 Client MQTT metrics.yultek.dev en cours de connexion... +2025-05-08 13:37:48 Client MQTT 192.168.51.32 en cours de connexion... +2025-05-08 13:37:48 Sauvegarde de la configuration système... +2025-05-08 13:37:48 Client MQTT 192.168.51.32 connecté. +2025-05-08 13:37:48 Client MQTT metrics.yultek.dev connecté. +2025-05-08 13:38:34 Déinitialisation du module PCAN USB ID 81 +2025-05-08 13:38:34 Impossible de déinitialiser un module USB PCAN.. Error:The transmit buffer in CAN controller is full +2025-05-08 13:38:34 Client MQTT metrics.yultek.dev déconnecté. +2025-05-08 13:38:34 Passage en mode buffering des messages MQTT pour metrics.yultek.dev +2025-05-08 13:38:34 Client MQTT 192.168.51.32 déconnecté.