From fb3223fd5e203886af945ef3f0a61838c4703c1e Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 5 Aug 2023 15:55:36 +0100 Subject: [PATCH 1/5] New command x509-eku: Extract X509v3 Extended Key Usage from cert Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 36d173f..491ea82 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -4352,6 +4352,57 @@ Showing details for CA certificate, at: die "OpenSSL failure to process the input" } # => show_ca() +# Certificate X509v3 Extended Key Usage +ssl_cert_x509v3_eku() { + [ "$1" ] || die "ssl_cert_x509v3_eku - Missing input" + + # check input file name + if [ -e "$1" ]; then + __crt="$1" + else + __crt="${EASYRSA_PKI}/issued/${1}.crt" + [ -e "$__crt" ] || \ + die "ssl_cert_x509v3_eku - Missing cert '$__crt'" + fi + + # Set output variable + __var="$2" + shift "$#" + + # required variables + __pattern="X509v3 Extended Key Usage:" + __cli="TLS Web Client Authentication" + __srv="TLS Web Server Authentication" + __srv_cli="${__srv}, ${__cli}" + + # Extract certificate usage from old cert + __eku="$( + easyrsa_openssl x509 -in "${__crt}" -noout -text | \ + sed -n "/${__pattern}/{n;s/^ *//g;p;}" + )" + + case "$__eku" in + "$__cli") + __type=client + ;; + "$__srv") + __type=server + ;; + "$__srv_cli") + __type=serverClient + ;; + *) die "Unknown key usage: $__eku" + esac + + # Set variable to return + if [ "$__var" ]; then + force_set_var "$__var" "$__type" + else + information "${NL}* EasyRSA Certificate type: $__type" + fi + unset -v __crt __var __pattern __eku __type +} # => ssl_cert_x509v3_eku() + # get the serial number of the certificate -> serial=XXXX ssl_cert_serial() { [ "$#" = 2 ] || die "ssl_cert_serial - input error" @@ -7296,6 +7347,10 @@ case "$cmd" in verify_working_env default_server_san "$@" ;; + x509-eku) + verify_working_env + ssl_cert_x509v3_eku "$@" + ;; upgrade) verify_working_env up23_manage_upgrade_23 "$@" From 77a05343473d0707c754e7a7e87dfe5580975f57 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 5 Aug 2023 15:57:52 +0100 Subject: [PATCH 2/5] New command inline: Inline available data for certificate Expose 'inline' command to command line. Inline available data and ignore missing files. This function prints the available inline data to stdout. To create inline files the data must be redirected to a file. Internally, this redirection is taken care of. Return 'soft' error when any data is missing but always print available data. This behaviour allows for incomplete inline files. For example, when a CA signs a certificate but does not have the private key. Any combination of missing files is allowed. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 101 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 16 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 491ea82..6ac77e8 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -33,6 +33,7 @@ A list of commands is shown below: build-client-full [ cmd-opts ] build-server-full [ cmd-opts ] build-serverClient-full [ cmd-opts ] + inline revoke [ cmd-opts ] renew revoke-renewed [ cmd-opts ] @@ -182,6 +183,15 @@ cmd_help() { * nopass - Do not encrypt the private key (Default: encrypted) (Equivalent to global option '--nopass|--no-pass')" ;; + inline) + text=" +* inline + + Print inline data for , with key and CA. + + * NOTE: To create an inline-file the output must be redirected. + If the output is incomplete then an error is retruned." + ;; revoke) text=" * revoke [reason] @@ -2589,27 +2599,81 @@ Inline file created: * $inline_out" else warn "\ -Failed to write inline file: +INCOMPLETE Inline file created: * $inline_out" fi return 0 } # => build_full() -# Create inline credentials file for this node -inline_creds () -{ - [ "$1" ] || die "inline_creds - Name missing" - printf "%s\n\n" "# $crt_type: $1" - printf "%s\n" "" - cat "$crt_out" - printf "%s\n\n" "" - printf "%s\n" "" - [ -e "$key_out" ] && cat "$key_out" - printf "%s\n\n" "" - printf "%s\n" "" - cat "$EASYRSA_PKI/ca.crt" - printf "%s\n\n" "" +# Print inline data for file_name_base +inline_creds () { + [ "$1" ] || die "inline_creds - Missing file_name_base" + + # Source files + crt_source="${EASYRSA_PKI}/issued/${1}.crt" + key_source="${EASYRSA_PKI}/private/${1}.key" + ca_source="$EASYRSA_PKI/ca.crt" + incomplete=0 + + # Generate data + if [ -e "$crt_source" ]; then + # Get EasyRSA cert type + ssl_cert_x509v3_eku "$1" type_data + + crt_data="\ + +$(cat "$crt_source") +" + else + # Set EasyRSA cert type to 'undefined' + type_data=undefined + incomplete=1 + crt_data="\ + +* Paste your user certificate here * +" + fi + + if [ -e "$key_source" ]; then + key_data="\ + +$(cat "$key_source") +" + else + incomplete=1 + key_data="\ + +* Paste your private key here * +" + fi + + if [ -e "$ca_source" ]; then + ca_data="\ + +$(cat "$ca_source") +" + else + incomplete=1 + ca_data="\ + +* Paste your CA certificate here * +" + fi + + # Print data + print "\ +# Easy-RSA Type: ${type_data} +# Name: ${1} + +$crt_data + +$key_data + +$ca_data +" + # If inline file is incomplete then return error + return "$incomplete" } # => inline_creds () # revoke backend @@ -2992,7 +3056,7 @@ Inline file created: * $inline_in" else warn "\ -Failed to write inline file: +INCOMPLETE Inline file created: * $inline_in" fi @@ -7249,6 +7313,11 @@ case "$cmd" in verify_working_env import_req "$@" ;; + inline) + verify_working_env + inline_creds "$@" || \ + easyrsa_exit_with_error=1 + ;; export-p12) verify_working_env export_pkcs p12 "$@" From 98e9f43be60d2cc5773be603051ae769a287f4ee Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 5 Aug 2023 15:58:25 +0100 Subject: [PATCH 3/5] renew: Use new ssl_cert_x509v3_eku() Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 6ac77e8..5156614 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2619,7 +2619,7 @@ inline_creds () { # Generate data if [ -e "$crt_source" ]; then # Get EasyRSA cert type - ssl_cert_x509v3_eku "$1" type_data + ssl_cert_x509v3_eku "$crt_source" type_data crt_data="\ @@ -2971,23 +2971,7 @@ Cannot renew this certificate, a conflicting file exists: die "Failed to create inline directoy." # 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 Auth"*", TLS Web Client Auth"*) - cert_type=serverClient - ;; - *) die "Unknown key usage: $cert_ext_key_usage" - esac + ssl_cert_x509v3_eku "$crt_in" cert_type # Use SAN from --san if set else use SAN from old cert if echo "$EASYRSA_EXTRA_EXTS" | grep -q subjectAltName From b637e9b695d64f9b68f41dcc46f37da771f80a0f Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 5 Aug 2023 15:58:56 +0100 Subject: [PATCH 4/5] Move creating 'inline' folder from 'build-ca' to 'init-pki' This allows a client that has not built a CA to use 'inline'. The CA and signed client certificate can be sent to the client, allowing the client to create a complete X509 based inline file, without creating a redundant CA. Also, add 'inline' command to the list of commands which do not require a CA. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 5156614..4f57a8e 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1335,7 +1335,7 @@ and initialize a fresh PKI here." fi # new dirs: - for i in private reqs; do + for i in private reqs inline; do mkdir -p "$EASYRSA_PKI/$i" || \ die "\ Failed to create PKI file structure (permissions?)" @@ -1656,7 +1656,7 @@ current CA. To start a new CA, run init-pki first." # create necessary dirs: err_msg="\ Unable to create necessary PKI files (permissions?)" - for i in issued inline certs_by_serial \ + for i in issued certs_by_serial \ revoked/certs_by_serial revoked/private_by_serial \ revoked/reqs_by_serial do @@ -7204,7 +7204,7 @@ case "$cmd" in require_pki=1 case "$cmd" in gen-req|gen-dh|build-ca|show-req| \ - make-safe-ssl|export-p*) + make-safe-ssl|export-p*|inline) unset -v require_ca ;; *) From 352b8db0fc9fe6a2140c840b136a3b79d8258942 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 5 Aug 2023 16:42:39 +0100 Subject: [PATCH 5/5] ChangeLog: New commands 'inline' and 'x509-eku' Signed-off-by: Richard T Bonhomme --- ChangeLog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7494ca3..6af8cf7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ Easy-RSA 3 ChangeLog 3.1.6 (2023-10-13) + * New commands: 'inline' and 'x509-eku' (#993) + inline: Build an inline file for a commonName + x509-eku: Extract X509v3 extended key usage from a certificate * Expose serial-check, display-dn, display-san and default-san to command line. (#980) (Debugging functions, which remain undocumented) * Expand default status to include vars-file and CA status (#973)