Support new OpenSSL/LibreSSL versions

This PR enhances support for the latest versions of OpenSSL and LibreSSL.

The development version of OpenSSL at https://github.com/openssl/openssl/ is version 3.0.0-dev. So, checks for OpenSSL versions need to support this version as well. At the same time, the latest versions of LibreSSL are 3.0.0, 3.0.1, and 3.0.2, so version number alone will no longer be sufficient to distinguish between OpenSSL and LibreSSL.

In addition to checks for these new version numbers, this PR addresses a couple of other issues:

 - In LibreSSL, the "$OPENSSL ciphers" command will not accept any protocol version other than "-tls1" as a parameter (and even including "-tls1" as an option is described as "deprecated").  So, this PR ensures that "$OPENSSL ciphers" is not passed any protocol version option other than "-tls1" is LibreSSL is being used.
- In OpenSSL 3.0.0-dev, the "$OPENSSL dgst" can no longer be used to compute HMACs, but a new "$OPENSSL mac" function has been created. So, this PR changes hmac() to use "$OPENSSL mac" with OpenSSL 3.0.0-dev.

Note that I have not tested the modified version of sub_session_resumption(). I am just assuming that OpenSSL 3.0.0-dev works the same as OpenSSL 1.1.1 and that all versions of LibreSSL work the same as OpenSSL 1.1.0 and earlier.
This commit is contained in:
David Cooper 2019-11-14 14:24:09 -05:00 committed by GitHub
parent 93169a3123
commit b15b39a5cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1797,7 +1797,10 @@ check_revocation_ocsp() {
else else
host_header=${uri##http://} host_header=${uri##http://}
host_header=${host_header%%/*} host_header=${host_header%%/*}
if [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == "1.1.0"* ]] || [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == "1.1.1"* ]]; then if [[ "$OSSL_NAME" =~ LibreSSL ]]; then
host_header="-header Host ${host_header}"
elif [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.0* ]] || [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.1* ]] || \
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 3.0.0* ]]; then
host_header="-header Host=${host_header}" host_header="-header Host=${host_header}"
else else
host_header="-header Host ${host_header}" host_header="-header Host ${host_header}"
@ -3454,7 +3457,7 @@ run_cipher_match(){
ossl_supported[nr_ciphers]=true ossl_supported[nr_ciphers]=true
nr_ciphers+=1 nr_ciphers+=1
fi fi
done < <(actually_supported_ciphers 'ALL:COMPLEMENTOFALL:@STRENGTH' 'ALL' "$ossl_ciphers_proto -V") done < <(actually_supported_ciphers 'ALL:COMPLEMENTOFALL:@STRENGTH' 'ALL' "-V")
fi fi
# Test the SSLv2 ciphers, if any. # Test the SSLv2 ciphers, if any.
@ -4016,8 +4019,11 @@ ciphers_by_strength() {
done done
else # no sockets, openssl! else # no sockets, openssl!
# The OpenSSL ciphers function, prior to version 1.1.0, could only understand -ssl2, -ssl3, and -tls1. # The OpenSSL ciphers function, prior to version 1.1.0, could only understand -ssl2, -ssl3, and -tls1.
if [[ "$proto" == "-ssl2" ]] || [[ "$proto" == -ssl3 ]] || \ if [[ "$OSSL_NAME" =~ LibreSSL ]]; then
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.0* ]] || [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.1* ]]; then ossl_ciphers_proto=""
elif [[ "$proto" == -ssl2 ]] || [[ "$proto" == -ssl3 ]] || \
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.0* ]] || [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.1* ]] || \
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 3.0.0* ]]; then
ossl_ciphers_proto="$proto" ossl_ciphers_proto="$proto"
else else
ossl_ciphers_proto="-tls1" ossl_ciphers_proto="-tls1"
@ -6093,7 +6099,9 @@ sub_session_resumption() {
debugme echo -n "Couldn't connect #1 " debugme echo -n "Couldn't connect #1 "
return 7 return 7
fi fi
if "$byID" && [[ $OSSL_VER_MINOR == 1.1 ]] && [[ $OSSL_VER_MAJOR == 1 ]] && [[ ! -s "$sess_data" ]]; then if "$byID" && [[ ! "$OSSL_NAME" =~ LibreSSL ]] && \
( [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.1* ]] || [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 3.0.0* ]] ) && \
[[ ! -s "$sess_data" ]]; then
# it seems OpenSSL indicates no Session ID resumption by just not generating output # it seems OpenSSL indicates no Session ID resumption by just not generating output
debugme echo -n "No session resumption byID (empty file)" debugme echo -n "No session resumption byID (empty file)"
ret=2 ret=2
@ -6879,7 +6887,7 @@ determine_trust() {
[[ -n $json_postfix ]] && spaces=" " [[ -n $json_postfix ]] && spaces=" "
case $OSSL_VER_MAJOR.$OSSL_VER_MINOR in case $OSSL_VER_MAJOR.$OSSL_VER_MINOR in
1.0.2|1.1.0|1.1.1|2.[1-9].*) # 2.x is LibreSSL. 2.1.1 was tested to work, below is not sure 1.0.2|1.1.0|1.1.1|2.[1-9].*|3.*) # 2.x is LibreSSL. 2.1.1 was tested to work, below is not sure
: :
;; ;;
*) addtl_warning="Your $OPENSSL <= 1.0.2 might be too unreliable to determine trust" *) addtl_warning="Your $OPENSSL <= 1.0.2 might be too unreliable to determine trust"
@ -10714,9 +10722,15 @@ hmac() {
local key="$2" text="$3" output local key="$2" text="$3" output
local -i ret local -i ret
output="$(asciihex_to_binary_file "$text" "/dev/stdout" | $OPENSSL dgst "$hash_fn" -mac HMAC -macopt hexkey:"$key" 2>/dev/null)" if [[ ! "$OSSL_NAME" =~ LibreSSL ]] && [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 3.0.0* ]]; then
ret=$? output="$(asciihex_to_binary_file "$text" "/dev/stdout" | $OPENSSL mac -macopt digest:"${hash_fn/-/}" -macopt hexkey:"$key" HMAC 2>/dev/null)"
tm_out "$(awk '/=/ { print $2 }' <<< "$output")" ret=$?
tm_out "$(strip_lf "$output")"
else
output="$(asciihex_to_binary_file "$text" "/dev/stdout" | $OPENSSL dgst "$hash_fn" -mac HMAC -macopt hexkey:"$key" 2>/dev/null)"
ret=$?
tm_out "$(awk '/=/ { print $2 }' <<< "$output")"
fi
return $ret return $ret
} }
@ -12749,18 +12763,26 @@ generate_key_share_extension() {
# with X25519 keys, so don't include the X25519 key share # with X25519 keys, so don't include the X25519 key share
# if the server's response needs to be decrypted and an # if the server's response needs to be decrypted and an
# older version of OpenSSL is being used. # older version of OpenSSL is being used.
[[ $i -gt 12 ]] && [[ $group -eq 29 ]] && [[ "$2" == "all" ]] && \ if [[ $i -gt 12 ]] && [[ $group -eq 29 ]] && [[ "$2" == all ]]; then
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR != "1.1.0"* ]] && \ [[ "$OSSL_NAME" =~ LibreSSL ]] && continue
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR != "1.1.1"* ]] && \ if [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR != 1.1.0* ]] && \
continue [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR != 1.1.1* ]] && \
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR != 3.0.0* ]]; then
continue
fi
fi
# Versions of OpenSSL prior to 1.1.1 cannot perform operations # Versions of OpenSSL prior to 1.1.1 cannot perform operations
# with X448 keys, so don't include the X448 key share # with X448 keys, so don't include the X448 key share
# if the server's response needs to be decrypted and an # if the server's response needs to be decrypted and an
# older version of OpenSSL is being used. # older version of OpenSSL is being used.
[[ $i -gt 12 ]] && [[ $group -eq 30 ]] && [[ "$2" == "all" ]] && \ if [[ $i -gt 12 ]] && [[ $group -eq 30 ]] && [[ "$2" == all ]]; then
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR != "1.1.1"* ]] && \ [[ "$OSSL_NAME" =~ LibreSSL ]] && continue
continue if [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR != 1.1.1* ]] && \
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR != 3.0.0* ]]; then
continue
fi
fi
# NOTE: The public keys could be extracted from the private keys # NOTE: The public keys could be extracted from the private keys
# (TLS13_KEY_SHARES) using $OPENSSL, but only OpenSSL 1.1.0 and newer can # (TLS13_KEY_SHARES) using $OPENSSL, but only OpenSSL 1.1.0 and newer can
@ -12922,8 +12944,9 @@ prepare_tls_clienthello() {
00, 01, 00, 02, 00, 03, 00, 0f, 00, 10, 00, 11" 00, 01, 00, 02, 00, 03, 00, 0f, 00, 10, 00, 11"
elif [[ 0x$tls_low_byte -gt 0x03 ]]; then elif [[ 0x$tls_low_byte -gt 0x03 ]]; then
# Supported Groups Extension # Supported Groups Extension
if [[ ! "$process_full" =~ all ]] || \ if [[ ! "$process_full" =~ all ]] || ( [[ ! "$OSSL_NAME" =~ LibreSSL ]] && \
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.1* ]]; then ( [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.1* ]] || \
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 3.0.0* ]] ) ); then
extension_supported_groups=" extension_supported_groups="
00,0a, # Type: Supported Groups, see RFC 8446 00,0a, # Type: Supported Groups, see RFC 8446
00,10, 00,0e, # lengths 00,10, 00,0e, # lengths
@ -16618,7 +16641,7 @@ find_openssl_binary() {
# see #190, reverting logic: unless otherwise proved openssl has no dh bits # see #190, reverting logic: unless otherwise proved openssl has no dh bits
case "$OSSL_VER_MAJOR.$OSSL_VER_MINOR" in case "$OSSL_VER_MAJOR.$OSSL_VER_MINOR" in
1.0.2|1.1.0|1.1.1) HAS_DH_BITS=true ;; 1.0.2|1.1.0|1.1.1|3.0.0) HAS_DH_BITS=true ;;
esac esac
if [[ "$OSSL_NAME" =~ LibreSSL ]]; then if [[ "$OSSL_NAME" =~ LibreSSL ]]; then
[[ ${OSSL_VER//./} -ge 210 ]] && HAS_DH_BITS=true [[ ${OSSL_VER//./} -ge 210 ]] && HAS_DH_BITS=true