From 5effd9466cf092b4ae2e2f7e03ef3577c9b24fb7 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 16 Aug 2024 17:25:37 +0100 Subject: [PATCH 1/8] Move sourcing Tools-lib to source_easyrsa_tools_lib() Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 53 ++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 19aa5b5b..066d21b1 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -5326,6 +5326,34 @@ CREATE_SSL_CONFIG esac } # => create_legacy_stream() +# Load easyrsa-tools.lib +source_easyrsa_tools_lib() { + if [ -f "$EASYRSA_TOOLS_LIB" ]; then + export EASYRSA_TOOLS_CALLER=1 + # shellcheck disable=SC1090 # can't follow non-constant.. + . "$EASYRSA_TOOLS_LIB" || \ + die "Source failed: $EASYRSA_TOOLS_LIB" + unset -v EASYRSA_TOOLS_CALLER tools_error + + verbose "EASYRSA_TOOLS_LIB: $EASYRSA_TOOLS_LIB" + verbose "EASYRSA_TOOLS_VERSION: $EASYRSA_TOOLS_VERSION" + + # Verify tools version + if [ "$EASYRSA_TOOLS_VERSION" -lt 321 ]; then + warn "\ +EasyRSA Tools version is out of date: +* EASYRSA_TOOLS_VERSION: $EASYRSA_TOOLS_VERSION" + fi + else + tools_error="Missing: easyrsa-tools.lib + +Use of command '$cmd' requires Easy-RSA tools library, source: +* https://github.com/OpenVPN/easy-rsa/dev/easyrsa-tools.lib + +Place a copy of easyrsa-tools.lib in a standard system location." + fi +} # => source_easyrsa_tools_lib() + # Version information print_version() { ssl_version="$( @@ -5839,30 +5867,7 @@ case "$cmd" in verify_working_env # easyrsa-tools.lib is required - if [ -f "$EASYRSA_TOOLS_LIB" ]; then - export EASYRSA_TOOLS_CALLER=1 - # shellcheck disable=SC1090 # can't follow non-constant.. - . "$EASYRSA_TOOLS_LIB" || \ - die "Source failed: $EASYRSA_TOOLS_LIB" - unset -v EASYRSA_TOOLS_CALLER tools_error - - verbose "EASYRSA_TOOLS_LIB: $EASYRSA_TOOLS_LIB" - verbose "EASYRSA_TOOLS_VERSION: $EASYRSA_TOOLS_VERSION" - - # Verify tools version - if [ "$EASYRSA_TOOLS_VERSION" -lt 321 ]; then - warn "\ -EasyRSA Tools version is out of date: -* EASYRSA_TOOLS_VERSION: $EASYRSA_TOOLS_VERSION" - fi - else - tools_error="Missing: easyrsa-tools.lib - -Use of command '$cmd' requires Easy-RSA tools library, source: -* https://github.com/OpenVPN/easy-rsa/dev/easyrsa-tools.lib - -Place a copy of easyrsa-tools.lib in a standard system location." - fi + source_easyrsa_tools_lib case "$cmd" in renew) From cf0da16dc00c71ef1384454a963a4b746d1b54cb Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 16 Aug 2024 17:37:44 +0100 Subject: [PATCH 2/8] Tools-Lib: Introduce OpenVPN TLS Key generation for TLS-AUTH, TLS-CRYPT-V1 Signed-off-by: Richard T Bonhomme --- dev/easyrsa-tools.lib | 74 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/dev/easyrsa-tools.lib b/dev/easyrsa-tools.lib index a9152f8e..4d299f19 100644 --- a/dev/easyrsa-tools.lib +++ b/dev/easyrsa-tools.lib @@ -11,6 +11,80 @@ fi # Set tools version export EASYRSA_TOOLS_VERSION=321 +# Verify OpenVPN binary +verify_openvpn() { + # Try to find openvpn + set_var EASYRSA_OPENVPN "$(which openvpn)" + if [ -f "$EASYRSA_OPENVPN" ]; then + verbose "verify_openvpn - $EASYRSA_OPENVPN" + else + user_error "Cannot find an OpenVPN binary." + fi +} # => verify_openvpn() + +# OpenVPN TLS Auth/Crypt Key +tls_key_gen() { + case "$1" in + tls-auth) + tls_key_type=TLS-AUTH + ;; + tls-crypt) + tls_key_type=TLS-CRYPT + ;; + tls-crypt-v2) + print "Unavailable." + cleanup + ;; + *) + die "Unknown key type: '$1'" + esac + tls_key_file="$EASYRSA_PKI/private/easyrsa-tls.key" + + # Forbid overwrite + if [ -f "$tls_key_file" ]; then + tls_key_data="$(cat "$tls_key_file")" + case "$tls_key_data" in + *'TLS-AUTH'*) + tls_key_type=TLS-AUTH + ;; + *'TLS-CRYPT'*) + tls_key_type=TLS-CRYPT + ;; + *) + tls_key_type=UNKNOWN + esac + + user_error "\ +Cannot overwrite existing $tls_key_type Key: +* $tls_key_file + +If this file is changed then it MUST be redistributed to ALL servers +AND clients, to be in effect. Do NOT change the existing file." + fi + + verify_openvpn + + tls_key_tmp= + easyrsa_mktemp tls_key_tmp || \ + die "tls_key_gen - easyrsa_mktemp tls_key_tmp" + + # Generate TLS Key + "$EASYRSA_OPENVPN" --genkey "$1" "$tls_key_tmp" || \ + die "tls_key_gen - --genkey $tls_key_type FAIL" + + # Insert type label + { + print "# Easy-RSA $tls_key_type Key" + cat "$tls_key_tmp" + } > "$tls_key_file" || \ + die "tls_key_gen - Insert type label FAIL" + + notice "\ +$tls_key_type Key generated at: +* $tls_key_file" + verbose "tls_key_gen: openvpn --genkey $tls_key_type OK" +} # => tls_key_gen() + # Get certificate start date # shellcheck disable=2317 # Unreach - ssl_cert_not_before_date() ssl_cert_not_before_date() { From 6e9e4a2b2dd693def2868104ecffb046e51ae6d4 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 17 Aug 2024 14:55:46 +0100 Subject: [PATCH 3/8] Introduce OpenVPN TLS Key generation and inlining for TLS-AUTH, TLS-CRYPT-V1 Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 78 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 066d21b1..eccbb5ae 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -56,6 +56,7 @@ A list of commands is shown below: export-p8 [ cmd-opts ] export-p12 [ cmd-opts ] set-pass [ cmd-opts ] + gen-tls-auth-key / gen-tls-crypt-key write [ cmd-opts ]" # collect/show dir status: @@ -507,6 +508,17 @@ These commands require easyrsa-tools.lib to be installed: show-expire (Optional) show-revoke (Optional) show-renew (Optional)" + ;; + gen-tls*) + text_only=1 + text=" +Generate TLS keys for use with OpenVPN: + + gen-tls-auth-key : Generate OpenVPN TLS-AUTH key + gen-tls-crypt-key : Generate OpenVPN TLS-CRYPT key (Preferred) + +Only ONE TLS key is allowed to exist. (pki/private/easyrsa-tls.key) +This TLS key will be automatically added to inline files." ;; opts|options) opt_usage @@ -535,7 +547,7 @@ These commands require easyrsa-tools.lib to be installed: : # ok - No opts message required else print " -Available command options [ cmd-opts ]: + Available command options [ cmd-opts ]: ${opts:- * No supported command options}" fi @@ -2090,6 +2102,9 @@ self-sign: Use ALGO:'$EASYRSA_ALGO' / CURVE:'$EASYRSA_CURVE'" die "Failed to move new key/cert files." fi + # inline key/cert/fingerprint + inline_file "$file_name_base" + # User info notice "\ Self-signed '$EASYRSA_ALGO/$EASYRSA_CURVE' \ @@ -2097,8 +2112,6 @@ key and certificate created: * $key_out * $crt_out" - # inline key/cert/fingerprint - inline_file "$file_name_base" } # => self_sign() # gen-dh backend: @@ -2767,14 +2780,14 @@ Signing failed (openssl output above may have more detail)" die "Failed to move temp certificate file." fi + # inline file + inline_file "$file_name_base" + # Success messages notice "\ Certificate created at: * $crt_out" - # inline file - inline_file "$file_name_base" - return 0 } # => sign_req() @@ -2914,7 +2927,6 @@ See error messages above for details." fi verbose "build_full: END sign_req" - return 0 } # => build_full() # Generate inline file V2 @@ -2925,6 +2937,7 @@ inline_file() { crt_source="${EASYRSA_PKI}/issued/${1}.crt" key_source="${EASYRSA_PKI}/private/${1}.key" ca_source="${EASYRSA_PKI}/ca.crt" + tls_source="${EASYRSA_PKI}"/private/easyrsa-tls.key # output inline_out="${EASYRSA_PKI}/inline/${1}.inline" @@ -3008,6 +3021,34 @@ $(cat "$ca_source") # " fi + # TLS auth|crypt key + if [ -f "$tls_source" ]; then + tls_key_data="$(cat "$tls_source")" + case "$tls_key_data" in + *'TLS-AUTH'*) + tls_key_label=tls-auth + ;; + *'TLS-CRYPT'*) + tls_key_label=tls-crypt + ;; + *) + tls_key_label= + esac + + if [ "$tls_key_label" ]; then + tls_data="\ +<${tls_key_label}> +${tls_key_data} +" + else + inline_incomplete=1 + tls_data="# Easy-RSA TLS Key not recognised!" + fi + else + inline_incomplete=1 + tls_data="# Easy-RSA TLS Key not found!" + fi + # Print data print "\ # Easy-RSA Inline file @@ -3021,6 +3062,8 @@ $crt_data $key_data $ca_data + +$tls_data " > "$inline_out" if [ "$inline_incomplete" ]; then @@ -3033,7 +3076,6 @@ Inline file created: * $inline_out" fi - return 0 } # => inline_file() # revoke backend @@ -5915,6 +5957,26 @@ using command 'expire' and sign the original request with 'sign-req'." die "Unknown command: '$cmd'" esac ;; + gen-tls-*) + verify_working_env + + # easyrsa-tools.lib is required + source_easyrsa_tools_lib + + case "$cmd" in + gen-tls-auth|gen-tls-auth-*) + tls_key_gen tls-auth "$@" + ;; + gen-tls-crypt|gen-tls-crypt-*) + tls_key_gen tls-crypt "$@" + ;; + gen-tls-cryptv2|gen-tls-cryptv2-*) + tls_key_gen tls-crypt-v2 "$@" + ;; + *) + die "Command '$cmd' not currently implemented." + esac + ;; write) verify_working_env From 6964130217af678fc07e0370e843615a2ad9ecc0 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 17 Aug 2024 15:08:47 +0100 Subject: [PATCH 4/8] ChangLog: OpenVPN TLS Key generation and inlining Signed-off-by: Richard T Bonhomme --- ChangeLog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index c7ab3ab1..0c0a7584 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ Easy-RSA 3 ChangeLog 3.2.1 (TBD) + * inline: OpenVPN TLS Keys inlining for TLS-AUTH, TLS-CRYPT-V1 (6e9e4a2) (#1185) + Note: Command inline only writes directly to inline file not stdout. + * easyrsa-tools.lib: OpenVPN TLS Key gen. TLS-AUTH, TLS-CRYPT-V1 (cf0da16) (#1185) * easyrsa-tools.lib: expire_status_v2() (show-expire version 2) (1e43bf5) (#1214) * sign-req: Require 128bit serial number (806ee19) (#1213) * Move command 'verify-cert' to Tools-lib; drop 'verify' shortcut (ddbf304) (#1209) From 5e43e61dca4d2a56f7a1cf6dd13c272027b25669 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 17 Aug 2024 17:42:52 +0100 Subject: [PATCH 5/8] Complete integration of source_easyrsa_tools_lib() Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index eccbb5ae..e21f57c7 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -5387,6 +5387,7 @@ EasyRSA Tools version is out of date: * EASYRSA_TOOLS_VERSION: $EASYRSA_TOOLS_VERSION" fi else + verbose "Missing: easyrsa-tools.lib" tools_error="Missing: easyrsa-tools.lib Use of command '$cmd' requires Easy-RSA tools library, source: @@ -5448,7 +5449,7 @@ unset -v \ selfsign_eku \ internal_batch mv_temp_error \ easyrsa_exit_with_error error_info \ - write_recursion + write_recursion tools_error # Used by build-ca->cleanup to restore prompt # after user interrupt when using manual password @@ -5918,36 +5919,35 @@ case "$cmd" in A certificate can be renewed without EasyRSA Tools. Expire the certificate using command 'expire' and sign the original request with 'sign-req'." - else - [ -z "$alias_days" ] || \ - export EASYRSA_CERT_EXPIRE="$alias_days" - renew "$@" fi + [ -z "$alias_days" ] || \ + export EASYRSA_CERT_EXPIRE="$alias_days" + renew "$@" ;; show-expire) if [ "$tools_error" ]; then user_error "$tools_error" - else - [ -z "$alias_days" ] || \ - export EASYRSA_PRE_EXPIRY_WINDOW="$alias_days" - status expire "$@" fi + [ -z "$alias_days" ] || \ + export EASYRSA_PRE_EXPIRY_WINDOW="$alias_days" + status expire "$@" ;; show-revoke) if [ "$tools_error" ]; then user_error "$tools_error" - else - status revoke "$@" fi + status revoke "$@" ;; show-renew) if [ "$tools_error" ]; then user_error "$tools_error" - else - status renew "$@" fi + status renew "$@" ;; verify-cert) + if [ "$tools_error" ]; then + user_error "$tools_error" + fi # Called with --batch, this will return error # when the certificate fails verification. # Therefore, on error, exit with error. @@ -5962,6 +5962,9 @@ using command 'expire' and sign the original request with 'sign-req'." # easyrsa-tools.lib is required source_easyrsa_tools_lib + if [ "$tools_error" ]; then + user_error "$tools_error" + fi case "$cmd" in gen-tls-auth|gen-tls-auth-*) From de66cf93f428bd30673db704c39725511e08d793 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 17 Aug 2024 19:46:59 +0100 Subject: [PATCH 6/8] inline: Only support OpenVPN client|server certificates Add OpenVPN --key-direction for TLS-AUTH keys. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index e21f57c7..a542dbef 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -3049,6 +3049,24 @@ ${tls_key_data} tls_data="# Easy-RSA TLS Key not found!" fi + # Only support inline files for OpenVPN server/client use + case "$crt_type" in + server) + key_direction="key-direction 0" + ;; + client) + key_direction="key-direction 1" + ;; + *) + verbose "inline: Unsupported certificate type: $crt_type" + return 0 + esac + + # Add --key-direction for TLS-AUTH + if [ "$tls_key_label" = tls-auth ]; then + tls_data="${tls_data}${NL}${NL}${key_direction}" + fi + # Print data print "\ # Easy-RSA Inline file @@ -3066,6 +3084,7 @@ $ca_data $tls_data " > "$inline_out" + # interactive feedback if [ "$inline_incomplete" ]; then warn "\ INCOMPLETE Inline file created: @@ -3075,7 +3094,6 @@ INCOMPLETE Inline file created: Inline file created: * $inline_out" fi - } # => inline_file() # revoke backend From 30fd9ef2d5d692768ac6da8de140010d0aba496f Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 17 Aug 2024 20:06:52 +0100 Subject: [PATCH 7/8] init-pki: Add notice to generate a TLS Key Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index a542dbef..137f0c6b 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -515,7 +515,7 @@ These commands require easyrsa-tools.lib to be installed: Generate TLS keys for use with OpenVPN: gen-tls-auth-key : Generate OpenVPN TLS-AUTH key - gen-tls-crypt-key : Generate OpenVPN TLS-CRYPT key (Preferred) + gen-tls-crypt-key : Generate OpenVPN TLS-CRYPT-V1 key (Preferred) Only ONE TLS key is allowed to exist. (pki/private/easyrsa-tls.key) This TLS key will be automatically added to inline files." @@ -1456,6 +1456,8 @@ and initialize a fresh PKI here." notice "\ 'init-pki' complete; you may now create a CA or requests. +Create a TLS-AUTH|TLS-CRYPT-V1 key now: See 'help gen-tls' + Your newly created PKI dir is: * $EASYRSA_PKI" From a1158594307322010d931c2818e7d810727f06b6 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sun, 18 Aug 2024 11:46:39 +0100 Subject: [PATCH 8/8] inline: Enable for all certificate types; Selectively inline TLS Keys Only inline TLS Keys for certificate type 'server' and 'client'. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 137f0c6b..c0bc7748 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -3061,7 +3061,8 @@ ${tls_key_data} ;; *) verbose "inline: Unsupported certificate type: $crt_type" - return 0 + tls_key_label= + tls_data="# No TLS Key support for cert-type: $crt_type" esac # Add --key-direction for TLS-AUTH