Skip to content

Commit cc104e8

Browse files
authored
Expand certificate testing (#1324)
1 parent f90ef9e commit cc104e8

22 files changed

Lines changed: 786 additions & 54 deletions

.azure/azure-pipelines-int.ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ stages:
141141
tls: schannel
142142
logProfile: Full.Light
143143
extraArgs: -Filter -*CryptTest.HpMaskChaCha20:CryptTest.WellKnownChaChaPoly:Alpn.ValidAlpnLengths
144+
testCerts: true
144145

145146
#
146147
# Build Verification Tests (Kernel Mode)
@@ -169,6 +170,7 @@ stages:
169170
logProfile: Full.Light
170171
extraArgs: -Kernel -Filter -*Handshake/WithHandshakeArgs6.ConnectClientCertificate/*:Alpn.ValidAlpnLengths
171172
kernel: true
173+
testCerts: true
172174

173175
#
174176
# Package

.azure/azure-pipelines.ci.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ stages:
438438
logProfile: Full.Verbose
439439
extraArgs: -Kernel -Filter -*Handshake/WithHandshakeArgs6.ConnectClientCertificate/*:Alpn.ValidAlpnLengths
440440
kernel: true
441+
testCerts: true
441442

442443
#
443444
# Build Verification Tests
@@ -457,45 +458,46 @@ stages:
457458
tls: schannel
458459
logProfile: Full.Verbose
459460
extraArgs: -Filter -*CryptTest.HpMaskChaCha20:CryptTest.WellKnownChaChaPoly:Alpn.ValidAlpnLengths
461+
testCerts: true
460462
- template: ./templates/run-bvt.yml
461463
parameters:
462464
image: windows-latest
463465
platform: windows
464466
tls: mitls
465467
logProfile: Full.Light
466-
extraArgs: -Filter -*Unreachable/0:CryptTest/CryptTest.Encryption/2:CryptTest.WellKnownChaChaPoly:*HandshakeParam*
468+
extraArgs: -Filter -*Unreachable/0:CryptTest/CryptTest.Encryption/2:CryptTest.WellKnownChaChaPoly:*HandshakeParam*:CredValidation*
467469
- template: ./templates/run-bvt.yml
468470
parameters:
469471
image: windows-latest
470472
platform: windows
471473
tls: openssl
472-
extraArgs: -Filter -*Unreachable/0:AppData/*:Misc/*
474+
extraArgs: -Filter -*Unreachable/0:AppData/*:Misc/*:CredValidation*
473475
- template: ./templates/run-bvt.yml
474476
parameters:
475477
image: ubuntu-latest
476478
platform: linux
477479
tls: openssl
478-
extraArgs: -Filter -*.Tcp*
480+
extraArgs: -Filter -*.Tcp*:CredValidation*
479481
- template: ./templates/run-bvt.yml
480482
parameters:
481483
image: ubuntu-latest
482484
platform: linux
483485
tls: stub
484-
extraArgs: -Filter -*TlsTest.CertificateError:TlsTest.ExtraCertificateValidation:*.Tcp*:*HandshakeParam*:Handshake/WithHandshakeArgs6.ConnectClientCertificate/*:*ResumeRejection*
486+
extraArgs: -Filter -*TlsTest.CertificateError:TlsTest.ExtraCertificateValidation:*.Tcp*:*HandshakeParam*:Handshake/WithHandshakeArgs6.ConnectClientCertificate/*:*ResumeRejection*:CredValidation*
485487
- template: ./templates/run-bvt.yml
486488
parameters:
487489
image: macOS-10.15
488490
platform: macos
489491
tls: openssl
490492
logProfile: None
491-
extraArgs: -Filter -*.Tcp*
493+
extraArgs: -Filter -*.Tcp*:CredValidation*
492494
- template: ./templates/run-bvt.yml
493495
parameters:
494496
image: ubuntu-latest
495497
platform: linux
496498
tls: openssl
497499
extraArtifactDir: '_SystemCrypto'
498-
extraArgs: -Filter -*.Tcp* -ExtraArtifactDir SystemCrypto
500+
extraArgs: -Filter -*.Tcp*:CredValidation* -ExtraArtifactDir SystemCrypto
499501

500502
#
501503
# SpinQuic Tests

.azure/templates/run-bvt.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ parameters:
1111
codeCoverage: false
1212
logProfile: 'Basic.Light'
1313
extraArgs: ''
14+
testCerts: false
1415
extraArtifactDir: ''
1516

1617
jobs:
@@ -41,7 +42,10 @@ jobs:
4142
inputs:
4243
pwsh: true
4344
filePath: scripts/prepare-machine.ps1
44-
arguments: -Configuration Test
45+
${{ if eq(parameters.testCerts, true) }}:
46+
arguments: -Configuration Test -TestCertificates
47+
${{ if eq(parameters.testCerts, false) }}:
48+
arguments: -Configuration Test
4549

4650
- task: PowerShell@2
4751
displayName: Run BVTs

scripts/prepare-machine.ps1

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ on the provided configuration.
1919
.PARAMETER Kernel
2020
Indicates build is for kernel mode.
2121
22+
.PARAMETER TestCertificates
23+
Generate test certificates. Only supported for Windows test configuration.
24+
2225
.EXAMPLE
2326
prepare-machine.ps1 -Configuration Build
2427
@@ -45,7 +48,10 @@ param (
4548
[switch]$Kernel,
4649

4750
[Parameter(Mandatory = $false)]
48-
[switch]$FailOnError
51+
[switch]$FailOnError,
52+
53+
[Parameter(Mandatory = $false)]
54+
[switch]$TestCertificates
4955
)
5056

5157
#Requires -RunAsAdministrator
@@ -174,6 +180,68 @@ if ($IsWindows) {
174180
}
175181

176182
if ($Configuration -eq "Test") {
183+
if ($TestCertificates) {
184+
# Install test certificates on windows
185+
$PfxPassword = ConvertTo-SecureString -String "TestCert" -Force -AsPlainText
186+
$NewRoot = $false
187+
Write-Host "Searching for MsQuicTestRoot certificate..."
188+
$RootCert = Get-ChildItem -path Cert:\LocalMachine\Root\* -Recurse | Where-Object {$_.Subject -eq "CN=MsQuicTestRoot"}
189+
if (!$RootCert) {
190+
Write-Host "MsQuicTestRoot not found! Creating new MsQuicTestRoot certificate..."
191+
$RootCert = New-SelfSignedCertificate -Subject "CN=MsQuicTestRoot" -FriendlyName MsQuicTestRoot -KeyUsageProperty Sign -KeyUsage CertSign,DigitalSignature -CertStoreLocation cert:\CurrentUser\My -HashAlgorithm SHA256 -Provider "Microsoft Software Key Storage Provider" -KeyExportPolicy Exportable -KeyAlgorithm ECDSA_nistP521 -CurveExport CurveName -NotAfter(Get-Date).AddYears(5) -TextExtension @("2.5.29.19 = {text}ca=1&pathlength=0") -Type Custom
192+
$TempRootPath = Join-Path $Env:TEMP "MsQuicTestRoot.cer"
193+
Export-Certificate -Type CERT -Cert $RootCert -FilePath $TempRootPath
194+
CertUtil.exe -addstore Root $TempRootPath
195+
Remove-Item $TempRootPath
196+
$NewRoot = $true
197+
Write-Host "New MsQuicTestRoot certificate installed!"
198+
} else {
199+
Write-Host "Found existing MsQuicTestRoot certificate!"
200+
}
201+
Write-Host "Searching for MsQuicTestServer certificate..."
202+
$ServerCert = Get-ChildItem -path Cert:\LocalMachine\My\* -Recurse | Where-Object {$_.Subject -eq "CN=MsQuicTestServer"}
203+
if (!$ServerCert) {
204+
Write-Host "MsQuicTestServer not found! Creating new MsQuicTestServer certificate..."
205+
$ServerCert = New-SelfSignedCertificate -Subject "CN=MsQuicTestServer" -DnsName $env:computername,localhost,"127.0.0.1","::1" -FriendlyName MsQuicTestServer -KeyUsageProperty Sign -KeyUsage DigitalSignature -CertStoreLocation cert:\CurrentUser\My -HashAlgorithm SHA256 -Provider "Microsoft Software Key Storage Provider" -KeyExportPolicy Exportable -KeyAlgorithm ECDSA_nistP256 -CurveExport CurveName -NotAfter(Get-Date).AddYears(5) -TextExtension @("2.5.29.19 = {text}","2.5.29.37 = {text}1.3.6.1.5.5.7.3.1") -Signer $RootCert
206+
$TempServerPath = Join-Path $Env:TEMP "MsQuicTestServerCert.pfx"
207+
Export-PfxCertificate -Cert $ServerCert -Password $PfxPassword -FilePath $TempServerPath
208+
Import-PfxCertificate -FilePath $TempServerPath -Password $PfxPassword -Exportable -CertStoreLocation Cert:\LocalMachine\My
209+
Remove-Item $TempServerPath
210+
Write-Host "New MsQuicTestServer certificate installed!"
211+
} else {
212+
Write-Host "Found existing MsQuicTestServer certificate!"
213+
}
214+
Write-Host "Searching for MsQuicTestExpiredServer certificate..."
215+
$ExpiredServerCert = Get-ChildItem -path Cert:\LocalMachine\My\* -Recurse | Where-Object {$_.Subject -eq "CN=MsQuicTestExpiredServer"}
216+
if (!$ExpiredServerCert) {
217+
Write-Host "MsQuicTestExpiredServer not found! Creating new MsQuicTestExpiredServer certificate..."
218+
$ExpiredServerCert = New-SelfSignedCertificate -Subject "CN=MsQuicTestExpiredServer" -DnsName $env:computername,localhost,"127.0.0.1","::1" -FriendlyName MsQuicTestExpiredServer -KeyUsageProperty Sign -KeyUsage DigitalSignature -CertStoreLocation cert:\CurrentUser\My -HashAlgorithm SHA256 -Provider "Microsoft Software Key Storage Provider" -KeyExportPolicy Exportable -KeyAlgorithm ECDSA_nistP256 -CurveExport CurveName -NotBefore (Get-Date).AddYears(-2) -NotAfter(Get-Date).AddYears(-1) -TextExtension @("2.5.29.19 = {text}","2.5.29.37 = {text}1.3.6.1.5.5.7.3.1") -Signer $RootCert
219+
$TempExpiredServerPath = Join-Path $Env:TEMP "MsQuicTestExpiredServerCert.pfx"
220+
Export-PfxCertificate -Cert $ExpiredServerCert -Password $PfxPassword -FilePath $TempExpiredServerPath
221+
Import-PfxCertificate -FilePath $TempExpiredServerPath -Password $PfxPassword -Exportable -CertStoreLocation Cert:\LocalMachine\My
222+
Remove-Item $TempExpiredServerPath
223+
Write-Host "New MsQuicTestExpiredServer certificate installed!"
224+
} else {
225+
Write-Host "Found existing MsQuicTestExpiredServer certificate!"
226+
}
227+
Write-Host "Searching for MsQuicTestClient certificate..."
228+
$ClientCert = Get-ChildItem -path Cert:\LocalMachine\My\* -Recurse | Where-Object {$_.Subject -eq "CN=MsQuicTestClient"}
229+
if (!$ClientCert) {
230+
Write-Host "MsQuicTestClient not found! Creating new MsQuicTestClient certificate..."
231+
$ClientCert = New-SelfSignedCertificate -Subject "CN=MsQuicTestClient" -FriendlyName MsQuicTestClient -KeyUsageProperty Sign -KeyUsage DigitalSignature -CertStoreLocation cert:\CurrentUser\My -HashAlgorithm SHA256 -Provider "Microsoft Software Key Storage Provider" -KeyExportPolicy Exportable -KeyAlgorithm ECDSA_nistP256 -CurveExport CurveName -NotAfter(Get-Date).AddYears(5) -TextExtension @("2.5.29.19 = {text}","2.5.29.37 = {text}1.3.6.1.5.5.7.3.2") -Signer $RootCert
232+
$TempClientPath = Join-Path $Env:TEMP "MsQuicTestClientCert.pfx"
233+
Export-PfxCertificate -Cert $ClientCert -Password $PfxPassword -FilePath $TempClientPath
234+
Import-PfxCertificate -FilePath $TempClientPath -Password $PfxPassword -Exportable -CertStoreLocation Cert:\LocalMachine\My
235+
Remove-Item $TempClientPath
236+
Write-Host "New MsQuicTestClient certificate installed!"
237+
}else {
238+
Write-Host "Found existing MsQuicTestClient certificate!"
239+
}
240+
if ($NewRoot) {
241+
Write-Host "Deleting MsQuicTestRoot from MY store..."
242+
Remove-Item $rootCert.PSPath
243+
}
244+
}
177245
# Install OpenCppCoverage on test machines
178246
if (!(Test-Path "C:\Program Files\OpenCppCoverage\OpenCppCoverage.exe")) {
179247
# Download the installer.

src/core/connection.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1403,7 +1403,11 @@ QuicErrorCodeToStatus(
14031403
case QUIC_ERROR_CRYPTO_USER_CANCELED: return QUIC_STATUS_USER_CANCELED;
14041404
case QUIC_ERROR_CRYPTO_HANDSHAKE_FAILURE: return QUIC_STATUS_HANDSHAKE_FAILURE;
14051405
case QUIC_ERROR_CRYPTO_NO_APPLICATION_PROTOCOL: return QUIC_STATUS_ALPN_NEG_FAILURE;
1406-
default: return QUIC_STATUS_INTERNAL_ERROR;
1406+
default:
1407+
if (IS_QUIC_CRYPTO_ERROR(ErrorCode)) {
1408+
return QUIC_STATUS_TLS_ALERT(ErrorCode);
1409+
}
1410+
return QUIC_STATUS_INTERNAL_ERROR;
14071411
}
14081412
}
14091413

src/core/crypto.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,7 @@ QuicCryptoProcessTlsCompletion(
12971297
"[conn][%p] ERROR, %u, %s.",
12981298
Connection,
12991299
Crypto->TlsState.AlertCode,
1300-
"Received alert from TLS.");
1300+
"Received alert from TLS");
13011301
QuicConnTransportError(
13021302
Connection,
13031303
QUIC_ERROR_CRYPTO_ERROR(0xFF & Crypto->TlsState.AlertCode));
@@ -1829,7 +1829,11 @@ QuicCryptoProcessAppData(
18291829
&DataLength,
18301830
&Crypto->TlsState);
18311831
if (Crypto->ResultFlags & CXPLAT_TLS_RESULT_ERROR) {
1832-
Status = QUIC_STATUS_INTERNAL_ERROR;
1832+
if (Crypto->TlsState.AlertCode != 0) {
1833+
Status = QUIC_STATUS_TLS_ALERT(Crypto->TlsState.AlertCode);
1834+
} else {
1835+
Status = QUIC_STATUS_INTERNAL_ERROR;
1836+
}
18331837
goto Error;
18341838
}
18351839

src/core/frame.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
// described in Section 4.8 of [QUIC-TLS].
8585
//
8686
#define QUIC_ERROR_CRYPTO_ERROR(TlsAlertCode) ((QUIC_VAR_INT)(0x100 | (TlsAlertCode)))
87+
#define IS_QUIC_CRYPTO_ERROR(QuicCryptoError) ((QuicCryptoError & 0x100) == 0x100)
8788

8889
#define QUIC_ERROR_CRYPTO_USER_CANCELED QUIC_ERROR_CRYPTO_ERROR(22) // TLS error code for 'user_canceled'
8990
#define QUIC_ERROR_CRYPTO_HANDSHAKE_FAILURE QUIC_ERROR_CRYPTO_ERROR(40) // TLS error code for 'handshake_failure'

src/inc/msquic_posix.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ inline ENUMTYPE &operator ^= (ENUMTYPE &a, ENUMTYPE b) throw() { return (ENUMTYP
118118
#define ERROR_ALPN_NEG_FAILURE 20 + ERROR_BASE
119119
#define ERROR_STREAM_LIMIT_REACHED 21 + ERROR_BASE
120120

121+
#define TLS_ERROR_BASE 256 + ERROR_BASE
122+
121123
#define QUIC_STATUS_SUCCESS ((QUIC_STATUS)ERROR_SUCCESS)
122124
#define QUIC_STATUS_PENDING ((QUIC_STATUS)ERROR_NOT_READY)
123125
#define QUIC_STATUS_CONTINUE ((QUIC_STATUS)ERROR_CONTINUE)
@@ -146,6 +148,12 @@ inline ENUMTYPE &operator ^= (ENUMTYPE &a, ENUMTYPE b) throw() { return (ENUMTYP
146148
#define QUIC_STATUS_ALPN_NEG_FAILURE ((QUIC_STATUS)ERROR_ALPN_NEG_FAILURE)
147149
#define QUIC_STATUS_STREAM_LIMIT_REACHED ((QUIC_STATUS)ERROR_STREAM_LIMIT_REACHED)
148150

151+
#define QUIC_STATUS_TLS_ALERT(Alert) ((QUIC_STATUS)(0xff & Alert) + TLS_ERROR_BASE)
152+
153+
#define QUIC_STATUS_CLOSE_NOTIFY QUIC_STATUS_TLS_ALERT(0) // Close notify
154+
#define QUIC_STATUS_BAD_CERTIFICATE QUIC_STATUS_TLS_ALERT(42) // Bad Certificate
155+
#define QUIC_STATUS_EXPIRED_CERTIFICATE QUIC_STATUS_TLS_ALERT(45) // Expired Certificate
156+
149157
typedef unsigned char BOOLEAN;
150158
typedef struct in_addr IN_ADDR;
151159
typedef struct in6_addr IN6_ADDR;

src/inc/msquic_winkernel.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ typedef UINT64 uint64_t;
7676
#define STATUS_QUIC_STREAM_LIMIT_REACHED ((NTSTATUS)0xC0240008L)
7777
#endif
7878

79+
#ifndef QUIC_TLS_ALERT_NTSTATUS_PREFIX
80+
#define QUIC_TLS_ALERT_NTSTATUS_PREFIX ((NTSTATUS)0xC0240100L)
81+
#endif
82+
7983
#define QUIC_API NTAPI
8084
#define QUIC_STATUS NTSTATUS
8185
#define QUIC_FAILED(X) (!NT_SUCCESS(X))
@@ -104,6 +108,12 @@ typedef UINT64 uint64_t;
104108
#define QUIC_STATUS_ALPN_NEG_FAILURE STATUS_QUIC_ALPN_NEG_FAILURE
105109
#define QUIC_STATUS_STREAM_LIMIT_REACHED STATUS_QUIC_STREAM_LIMIT_REACHED
106110

111+
#define QUIC_STATUS_TLS_ALERT(Alert) (QUIC_TLS_ALERT_NTSTATUS_PREFIX | (0xff & Alert))
112+
113+
#define QUIC_STATUS_CLOSE_NOTIFY QUIC_STATUS_TLS_ALERT(0) // Close notify
114+
#define QUIC_STATUS_BAD_CERTIFICATE QUIC_STATUS_TLS_ALERT(42) // Bad Certificate
115+
#define QUIC_STATUS_EXPIRED_CERTIFICATE QUIC_STATUS_TLS_ALERT(45) // Expired Certificate
116+
107117
//
108118
// Swaps byte orders between host and network endianness.
109119
//

src/inc/msquic_winuser.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@
6969
#define ERROR_QUIC_STREAM_LIMIT_REACHED _HRESULT_TYPEDEF_(0x80410008L)
7070
#endif
7171

72+
#ifndef QUIC_TLS_ALERT_HRESULT_PREFIX
73+
#define QUIC_TLS_ALERT_HRESULT_PREFIX _HRESULT_TYPEDEF_(0x80410100L)
74+
#endif
75+
7276
#define QUIC_API __cdecl
7377
#define QUIC_MAIN_EXPORT __cdecl
7478
#define QUIC_STATUS HRESULT
@@ -99,6 +103,12 @@
99103
#define QUIC_STATUS_ALPN_NEG_FAILURE ERROR_QUIC_ALPN_NEG_FAILURE
100104
#define QUIC_STATUS_STREAM_LIMIT_REACHED ERROR_QUIC_STREAM_LIMIT_REACHED
101105

106+
#define QUIC_STATUS_TLS_ALERT(Alert) (QUIC_TLS_ALERT_HRESULT_PREFIX | (0xff & Alert))
107+
108+
#define QUIC_STATUS_CLOSE_NOTIFY QUIC_STATUS_TLS_ALERT(0) // Close notify
109+
#define QUIC_STATUS_BAD_CERTIFICATE QUIC_STATUS_TLS_ALERT(42) // Bad Certificate
110+
#define QUIC_STATUS_EXPIRED_CERTIFICATE QUIC_STATUS_TLS_ALERT(45) // Expired Certificate
111+
102112
//
103113
// Swaps byte orders between host and network endianness.
104114
//

0 commit comments

Comments
 (0)