wolfssl-sys 4.0.0

System bindings for WolfSSL
Documentation
#!/usr/bin/env bash
# Test WolfSSL/OpenSSL srtp interoperability
#
# TODO: add OpenSSL client with WolfSSL server

set -e

if ! test -n "$WOLFSSL_OPENSSL_TEST"; then
    echo "WOLFSSL_OPENSSL_TEST NOT set, won't run"
    exit 0
fi

OPENSSL=${OPENSSL:="openssl"}
WOLFSSL_CLIENT=${WOLFSSL_CLIENT:="./examples/client/client"}

# need a unique port since may run the same time as testsuite
# Track ports already assigned in this script run to prevent intra-run collisions
used_ports=()

generate_port() {
    #-------------------------------------------------------------------------#
    # Generate a random port number, guaranteed unique within this script run.
    # Checks both the intra-run used_ports list and system-level bound ports.
    #-------------------------------------------------------------------------#
    local attempts=0 collision p

    while true; do
        if [[ "$OSTYPE" == "linux"* ]]; then
            p=$(($(od -An -N2 /dev/urandom) % (65535-49512) + 49512))
        elif [[ "$OSTYPE" == "darwin"* ]]; then
            p=$(($(od -An -N2 /dev/random) % (65535-49512) + 49512))
        else
            echo "Unknown OS TYPE"
            exit 1
        fi

        # Check against ports already assigned in this run
        collision=0
        for up in "${used_ports[@]}"; do
            if [ "$up" = "$p" ]; then
                collision=1
                break
            fi
        done

        # Also check if the port is already bound on this system
        if [ "$collision" -eq 0 ]; then
            if command -v ss &>/dev/null; then
                ss -lnt 2>/dev/null | grep -q ":${p}[[:space:]]" && collision=1
            elif command -v netstat &>/dev/null; then
                netstat -lnt 2>/dev/null | grep -q ":${p}[[:space:]]" && collision=1
            fi
        fi

        [ "$collision" -eq 0 ] && break

        attempts=$((attempts + 1))
        if [ "$attempts" -ge 100 ]; then
            echo "ERROR: generate_port could not find a free port after 100 attempts"
            exit 1
        fi
    done

    port=$p
    used_ports+=("$p")
}

# get size of key material based on the profile
# $1 srtp profile
get_key_material_size() {
    case "$1" in
        "SRTP_AES128_CM_SHA1_80")
            ekm_size=60 ;;
        "SRTP_AES128_CM_SHA1_32")
            ekm_size=60 ;;
        "SRTP_NULL_SHA1_80")
            ekm_size=28 ;;
        "SRTP_NULL_SHA1_32")
            ekm_size=27 ;;
        "SRTP_AEAD_AES_128_GCM")
            ekm_size=56;;
        "SRTP_AEAD_AES_256_GCM")
            ekm_size=88;;
        *)
            echo "SRTP profile $1 unsupported"
            exit 1
    esac
}


# Start an OpenSSL server dtls with srtp
# $1: dtsl version [1.0, 1.2]
# $2: srtp profile string
start_openssl_server() {
    generate_port
    server_port=$port
    srtp_profile=$2

    if [ "$1" = "1.0" ]; then
        dtls_version=dtls1
    elif [ "$1" = "1.2" ]; then
        dtls_version=dtls1_2
    fi

    get_key_material_size "$srtp_profile"

    server_output_file=/tmp/openssl_srtp_out

    # hackish but OpenSSL doesn't work if input is fed before handshaking and
    # the wolfSSL client needs a reply to stop
    (sleep 1;echo -n "I hear you fa shizzle...") | \
        ${OPENSSL} s_server \
                   -${dtls_version} \
                   -port "${server_port}" \
                   -debug \
                   -use_srtp "${srtp_profile}" \
                   -keymatexport EXTRACTOR-dtls_srtp \
                   -keymatexportlen "$ekm_size" \
                   -cert ./certs/server-cert.pem \
                   -key ./certs/server-key.pem >"$server_output_file" &

    # make sure the server is up
    sleep 0.1
}

# Start an wolfssl client dtls with srtp
# $1: dtsl version [1.0, 1.2]
# $2: srtp profile string
start_wolfssl_client() {
    srtp_profile=$2

    if [ "$1" = "1.0" ]; then
        dtls_version=2
    elif [ "$1" = "1.2" ]; then
        dtls_version=3
    fi

    client_output_file=/tmp/wolfssl_srtp_out
    ${WOLFSSL_CLIENT} -u\
                      -x \
                      -v${dtls_version} \
                      --srtp "${srtp_profile}" \
                      -p${server_port} >"$client_output_file"
}

# $1 openssl file
# $2 wolfssl file
check_ekm() {
    openssl_ekm=$(grep "Keying material: " < "$1" | cut -d ':' -f 2)
    echo "OPENSSL EKM: $openssl_ekm"
    wolfssl_ekm=$(grep "DTLS SRTP: Exported key material: " < "$2" | cut -d ':' -f 3)
    echo "WOLFSSL EKM: $wolfssl_ekm"

    if [ "$openssl_ekm" = "$wolfssl_ekm" ];then
        check_ret=0
    else
        check_ret=1
    fi
}

# $1 dtsl version
# $2 srtp profile
check_dtls_srtp() {
    start_openssl_server "$1" "$2"
    start_wolfssl_client "$1" "$2"
    check_ekm "$server_output_file" "$client_output_file"
    echo -n "check dtls $1 $2... "
    if [ "$check_ret" -ne 0 ];then
        echo "failed"
        exit 1
    else
        echo "ok"
    fi
}

# SRTP_NULL_SHA1_80" and SRTP_NULL_SHA1_32 aren't supported by OpenSSL
PROFILES="SRTP_AES128_CM_SHA1_80 \
        SRTP_AES128_CM_SHA1_32 \
        SRTP_AEAD_AES_128_GCM \
        SRTP_AEAD_AES_256_GCM"

for DTLS in 1.0 1.2;do
    for SRTP_PROF in $PROFILES;do
        check_dtls_srtp "$DTLS" "$SRTP_PROF"
    done
done