Skip to content

Commit

Permalink
Add platform unit tests (#162)
Browse files Browse the repository at this point in the history
Adds testing of the platform layers, and fixes an issue in the OpenSSL hash calculation discovered by these tests.
Fixes #93

Co-authored-by: Nick Banks <nibanks@microsoft.com>
  • Loading branch information
anrossi and nibanks authored Feb 24, 2020
1 parent 2aacc7f commit e2e2a90
Show file tree
Hide file tree
Showing 16 changed files with 1,083 additions and 3,980 deletions.
2 changes: 1 addition & 1 deletion .azure/azure-pipelines.ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ stages:
arch: x64
tls: mitls
logProfile: Full.Light
extraArgs: -Filter -*Unreachable/0
extraArgs: -Filter -*Unreachable/0:CryptTest/CryptTest.Encryption/2
# OpenSSL tests are broken because they can't load on a different
# machine from where they were built.
# - template: ./templates/run-bvt.yml
Expand Down
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(QUIC_COMMON_FLAGS "${QUIC_COMMON_FLAGS} -DQUIC_DISABLE_0RTT")
endif()

if(QUIC_TLS STREQUAL "stub")
set(QUIC_COMMON_FLAGS "${QUIC_COMMON_FLAGS} -DQUIC_TLS_STUB")
endif()

if(QUIC_SANITIZE_ADDRESS)
message(STATUS "Address sanitizer unsupported on this platform.")
endif()
Expand Down Expand Up @@ -135,6 +139,10 @@ else()
set(QUIC_COMMON_FLAGS "${QUIC_COMMON_FLAGS} -fsanitize=address -fno-omit-frame-pointer -Wno-maybe-uninitialized -O0 -Og -g")
endif()

if(QUIC_TLS STREQUAL "stub")
set(QUIC_COMMON_FLAGS "${QUIC_COMMON_FLAGS} -DQUIC_TLS_STUB")
endif()

set(QUIC_C_FLAGS "${QUIC_COMMON_FLAGS}")
set(QUIC_CXX_FLAGS "${QUIC_COMMON_FLAGS} --std=c++17 -g -Wno-reorder -Wno-sign-compare -Wno-format")
endif()
Expand Down Expand Up @@ -196,6 +204,7 @@ if(QUIC_BUILD_TEST)
add_subdirectory(submodules/googletest)

add_subdirectory(src/core/unittest)
add_subdirectory(src/platform/unittest)
add_subdirectory(src/test/lib)
add_subdirectory(src/test/bin)
endif()
18 changes: 12 additions & 6 deletions scripts/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ This script provides helpers for building msquic.
.PARAMETER InstallOutput
Installs the build output to the current machine.
.PARAMETER Parallel
Enables CMake to build in parallel, where possible.
.EXAMPLE
build.ps1 -InstallDependencies
Expand Down Expand Up @@ -82,7 +85,10 @@ param (
[switch]$Clean = $false,

[Parameter(Mandatory = $false)]
[switch]$InstallOutput = $false
[switch]$InstallOutput = $false,

[Parameter(Mandatory = $false)]
[int32]$Parallel = -1
)

Set-StrictMode -Version 'Latest'
Expand Down Expand Up @@ -195,16 +201,16 @@ function CMake-Generate {
# Uses cmake to generate the build configuration files.
function CMake-Build {
$Arguments = "--build ."
if ($Parallel -gt 0) {
$Arguments += " --parallel $($Parallel)"
} elseif ($Parallel -eq 0) {
$Arguments += " --parallel"
}
if ($IsWindows) {
$Arguments += " --config " + $Config
}

CMake-Execute $Arguments

if ($Tls -eq "openssl") {
$OpensslDir = Join-Path $BuildDir "openssl" "lib" "*"
Copy-Item $OpensslDir -Destination $ArtifactsDir -Recurse
}
}

# Installs all the build output.
Expand Down
4 changes: 4 additions & 0 deletions scripts/test.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,15 @@ $RunTest = Join-Path $RootDir ".azure/scripts/run-gtest.ps1"
# Path to the msquictest exectuable.
$MsQuicTest = $null
$MsQuicCoreTest = $null
$MsQuicPlatTest = $null
if ($IsWindows) {
$MsQuicTest = Join-Path $RootDir "\artifacts\windows\$($Arch)_$($Config)_$($Tls)\msquictest.exe"
$MsQuicCoreTest = Join-Path $RootDir "\artifacts\windows\$($Arch)_$($Config)_$($Tls)\msquiccoretest.exe"
$MsQuicPlatTest = Join-Path $RootDir "\artifacts\windows\$($Arch)_$($Config)_$($Tls)\msquicplatformtest.exe"
} else {
$MsQuicTest = Join-Path $RootDir "/artifacts/linux/$($Arch)_$($Config)_$($Tls)/msquictest"
$MsQuicCoreTest = Join-Path $RootDir "/artifacts/linux/$($Arch)_$($Config)_$($Tls)/msquiccoretest"
$MsQuicPlatTest = Join-Path $RootDir "/artifacts/linux/$($Arch)_$($Config)_$($Tls)/msquicplatformtest"
}

# Build up all the arguments to pass to the Powershell script.
Expand Down Expand Up @@ -178,4 +181,5 @@ if ($CompressOutput) {

# Run the script.
Invoke-Expression ($RunTest + " -Path $($MsQuicCoreTest) " + $TestArguments)
Invoke-Expression ($RunTest + " -Path $($MsQuicPlatTest) " + $TestArguments)
Invoke-Expression ($RunTest + " -Path $($MsQuicTest) " + $TestArguments)
11 changes: 0 additions & 11 deletions src/core/inline.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,6 @@ QuicKeyTypeToEncryptLevel(
QUIC_PACKET_KEY_TYPE KeyType
);

uint16_t
QuicKeyLength(
QUIC_AEAD_TYPE Type
);

QUIC_PACKET_KEY_TYPE
QuicPacketTypeToKeyType(
uint8_t PacketType
Expand Down Expand Up @@ -612,9 +607,3 @@ int64_t
QuicTimeEpochMs64(
void
);

void
QuicTraceStubVarArgs(
_In_ const void* Fmt,
...
);
2 changes: 1 addition & 1 deletion src/inc/quic_platform_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ QuicPlatformUninitialize(

#define UNREFERENCED_PARAMETER(P) (P)

#define QuicNetByteSwapShort(x) htons((x)
#define QuicNetByteSwapShort(x) htons((x))

#define SIZEOF_STRUCT_MEMBER(StructType, StructMember) sizeof(((StructType *)0)->StructMember)
#define TYPEOF_STRUCT_MEMBER(StructType, StructMember) typeof(((StructType *)0)->StructMember)
Expand Down
11 changes: 11 additions & 0 deletions src/platform/inline.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ QuicHashLength(
QUIC_HASH_TYPE Type
);

uint16_t
QuicKeyLength(
QUIC_AEAD_TYPE Type
);

uint64_t
QuicTimeDiff64(
_In_ uint64_t T1,
Expand All @@ -158,3 +163,9 @@ QuicTimeAtOrBefore32(
_In_ uint32_t T1,
_In_ uint32_t T2
);

void
QuicTraceStubVarArgs(
_In_ const void* Fmt,
...
);
133 changes: 44 additions & 89 deletions src/platform/tls_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,18 +399,6 @@ QuicTlsHeaderMask(
_In_ const EVP_CIPHER *Aead
);

static
BOOLEAN
QuicTlsHash(
_Out_writes_bytes_(OutputBufferLen) uint8_t *OutputBuffer,
_In_ size_t OutputBufferLen,
_In_reads_bytes_(SecretLen) const uint8_t *Secret,
_In_ size_t SecretLen,
_In_reads_bytes_(SaltLen) const uint8_t *Salt,
_In_ size_t SaltLen,
_In_ QUIC_HASH *Hash
);

static
void
QuicTlsSecConfigDelete(
Expand Down Expand Up @@ -1992,16 +1980,50 @@ QuicHashCompute(
_Out_writes_all_(OutputLength) uint8_t* const Output
)
{
return
QuicTlsHash(
Output,
OutputLength,
Input,
InputLength,
Hash->Salt,
Hash->SaltLength,
Hash) != 0 ?
QUIC_STATUS_SUCCESS : QUIC_STATUS_INTERNAL_ERROR;
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
EVP_MD_CTX* HashContext = NULL;
EVP_PKEY* HmacKey = NULL;

HashContext = EVP_MD_CTX_create();
if (HashContext == NULL) {
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Error;
}

HmacKey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, Hash->Salt, Hash->SaltLength);
if (HmacKey == NULL) {
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Error;
}

if (!EVP_DigestSignInit(HashContext, NULL, Hash->Md, NULL, HmacKey)) {
Status = QUIC_STATUS_INTERNAL_ERROR;
goto Error;
}

if (!EVP_DigestSignUpdate(HashContext, Input, InputLength)) {
Status = QUIC_STATUS_INTERNAL_ERROR;
goto Error;
}

size_t ActualOutputSize = OutputLength;
if (!EVP_DigestSignFinal(HashContext, Output, &ActualOutputSize)) {
Status = QUIC_STATUS_INTERNAL_ERROR;
goto Error;
}

QUIC_FRE_ASSERT(ActualOutputSize == OutputLength);

Error:
if (HashContext != NULL) {
EVP_MD_CTX_free(HashContext);
}

if (HmacKey != NULL) {
EVP_PKEY_free(HmacKey);
}

return Status;
}

static
Expand Down Expand Up @@ -2886,70 +2908,3 @@ QuicTlsHeaderMask(

return Ret;
}

static
BOOLEAN
QuicTlsHash(
_Out_writes_bytes_(OutputBufferLen) uint8_t *OutputBuffer,
_In_ size_t OutputBufferLen,
_In_reads_bytes_(SecretLen) const uint8_t *Secret,
_In_ size_t SecretLen,
_In_reads_bytes_(SaltLen) const uint8_t *Salt,
_In_ size_t SaltLen,
_In_ QUIC_HASH *Hash
)
{
BOOLEAN Ret = TRUE;
EVP_PKEY_CTX *KeyCtx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);

if (KeyCtx == NULL) {
QuicTraceLogError("[ tls] KeyCtx alloc failed.");
Ret = FALSE;
goto Exit;
}

if (EVP_PKEY_derive_init(KeyCtx) != 1) {
QuicTraceLogError("[ tls] EVP_PKEY_derive_init failed.");
Ret = FALSE;
goto Exit;
}

if (EVP_PKEY_CTX_hkdf_mode(KeyCtx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) != 1) {
QuicTraceLogError("[ tls] EVP_PKEY_CTX_hkdf_mode failed.");
Ret = FALSE;
goto Exit;
}

if (EVP_PKEY_CTX_set_hkdf_md(KeyCtx, Hash->Md) != 1) {
QuicTraceLogError("[ tls] EVP_PKEY_CTX_set_hkdf_md failed.");
Ret = FALSE;
goto Exit;
}

if (EVP_PKEY_CTX_set1_hkdf_salt(KeyCtx, Salt, SaltLen) != 1) {
QuicTraceLogError("[ tls] EVP_PKEY_CTX_set1_hkdf_salt failed.");
Ret = FALSE;
goto Exit;
}

if (EVP_PKEY_CTX_set1_hkdf_key(KeyCtx, Secret, SecretLen) != 1) {
QuicTraceLogError("[ tls] EVP_PKEY_CTX_set1_hkdf_key failed.");
Ret = FALSE;
goto Exit;
}

if (EVP_PKEY_derive(KeyCtx, OutputBuffer, &OutputBufferLen) != 1) {
QuicTraceLogError("[ tls] EVP_PKEY_derive failed.");
Ret = FALSE;
goto Exit;
}

Exit:

if (KeyCtx != NULL) {
EVP_PKEY_CTX_free(KeyCtx);
KeyCtx = NULL;
}

return Ret;
}
37 changes: 37 additions & 0 deletions src/platform/unittest/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

include_directories(${CMAKE_SOURCE_DIR}/src/platform)
include_directories(${CMAKE_SOURCE_DIR}/submodules/googletest/googletest/include)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QUIC_CXX_FLAGS}")

set(
SOURCES
main.cpp
CryptTest.cpp
DataPathTest.cpp
# StorageTest.cpp
TlsTest.cpp
)

add_executable(msquicplatformtest ${SOURCES})

if(WIN32)
target_link_libraries(msquicplatformtest ntdll ws2_32 bcrypt)
endif()

if(QUIC_TLS STREQUAL "schannel")
target_link_libraries(msquicplatformtest schannel ncrypt crypt32)
elseif(QUIC_TLS STREQUAL "openssl")
add_dependencies(msquicplatformtest OpenSSL)
target_link_libraries(msquicplatformtest
${QUIC_BUILD_DIR}/openssl/lib/libcrypto.so
${QUIC_BUILD_DIR}/openssl/lib/libssl.so)
elseif(QUIC_TLS STREQUAL "mitls")
target_link_libraries(msquicplatformtest kremlib evercrypt mitls quiccrypto ncrypt crypt32)
endif()

target_link_libraries(msquicplatformtest platform gtest)

add_test(msquicplatformtest msquicplatformtest)
Loading

0 comments on commit e2e2a90

Please sign in to comment.