Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TLS/SSL backend: Windows Schannel #3867

Merged
merged 22 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e7e4ace
Initial version (Working: connect, send/recv. Not working: param sett…
nanangizz Feb 15, 2024
bb5853a
Add getting cipher & cert info
nanangizz Feb 15, 2024
e57d4a8
Mem management: use preallocated send buffer instead of relying on sy…
nanangizz Feb 16, 2024
8cafc33
Implement TLS certificate setting: read cert from OS cert store.
nanangizz Feb 16, 2024
3245fed
Enable TLS protocol version setting, handling error code mapping & pr…
nanangizz Feb 19, 2024
0095be7
Add manual verification result, fix bug in setting up TLS protocol ve…
nanangizz Feb 20, 2024
68e5650
Minors: add comments about pj_status_t & SECURITY_STATUS mapping, cos…
nanangizz Feb 21, 2024
76fe133
Update certificate settings, fix setting TLS protocol version
nanangizz Feb 23, 2024
aed522b
Fix compile error on non-Windows
nanangizz Feb 23, 2024
7e87d3c
Slight modifications in TLS cert settings in PJSIP TLS transport & PJ…
nanangizz Feb 23, 2024
fcb55f5
Retry using SCHANNEL_CRED when using SCH_CREDENTIALS fails.
nanangizz Feb 23, 2024
5b31f80
Implement TLS renego (experimental).
nanangizz Mar 7, 2024
8fec190
Update PJLIB SSL socket test for Schannel backend.
nanangizz Mar 14, 2024
f044db6
Add ssl_sock_schannel.c to PJLIB project (vs14)
nanangizz Mar 14, 2024
51379b9
Modifications based on comments
nanangizz Mar 15, 2024
2d55fba
Update ci-win.yml
nanangizz Mar 18, 2024
9f50c22
Update ci-win.yml
nanangizz Mar 18, 2024
30a23a5
Update SSL socket test: disable cert lookup by default.
nanangizz Mar 18, 2024
e9d470b
Merge branch 'schannel' of https://github.com/pjsip/pjproject into sc…
nanangizz Mar 18, 2024
43cc47a
Update ci-win.yml
nanangizz Mar 18, 2024
ae1c9ec
Shorten docs of certificate lookup on various places (missing commit).
nanangizz Mar 20, 2024
d9e2552
Merge branch 'schannel' of https://github.com/pjsip/pjproject into sc…
nanangizz Mar 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 5 additions & 19 deletions .github/workflows/ci-win.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,25 +178,10 @@ jobs:
msbuild pjproject-vs14.sln /p:PlatformToolset=v143 /p:Configuration=Release /p:Platform=win32 /p:UseEnv=true
shell: cmd

windows-with-video-libvpx-unit-test-1:
windows-with-video-libvpx-schannel-unit-test-1:
runs-on: windows-latest
nanangizz marked this conversation as resolved.
Show resolved Hide resolved
steps:
- uses: actions/checkout@master
- name: get openssl
run: Invoke-WebRequest -Uri "https://github.com/pjsip/third_party_libs/raw/main/openssl-1.1.1s-win.zip" -OutFile ".\openssl.zip"
shell: powershell
- name: expand openssl
run: |
Expand-Archive -LiteralPath .\openssl.zip -DestinationPath .; pwd
cd openssl_build
Add-Content ..\openssl_dir.txt $pwd.Path
shell: powershell
- name: check openssl folder
run: |
set /P OPENSSL_DIR=<openssl_dir.txt
dir "%OPENSSL_DIR%\include"
dir "%OPENSSL_DIR%\lib"
shell: cmd
- name: get vpx
run: Invoke-WebRequest -Uri "https://github.com/pjsip/third_party_libs/raw/main/vpx-1.12-win.zip" -Outfile "vpx.zip"
shell: powershell
Expand Down Expand Up @@ -231,6 +216,8 @@ jobs:
run: |
cd pjlib/include/pj; cp config_site_test.h config_site.h
Add-Content config_site.h "#define PJ_HAS_SSL_SOCK 1"
Add-Content config_site.h "#define PJ_SSL_SOCK_IMP PJ_SSL_SOCK_IMP_SCHANNEL"
Add-Content config_site.h "#undef PJMEDIA_SRTP_HAS_DTLS"
Add-Content config_site.h "#define PJMEDIA_HAS_VIDEO 1"
Add-Content config_site.h "#define PJMEDIA_VIDEO_DEV_HAS_DSHOW 1"
Add-Content config_site.h "#define PJMEDIA_HAS_LIBYUV 1"
Expand Down Expand Up @@ -258,7 +245,7 @@ jobs:
set /P SDL_DIR=<sdl_dir.txt
cd tests/pjsua/tools
set INCLUDE=%INCLUDE%;%OPENSSL_DIR%\include;%VPX_DIR%\include;%SDL_DIR%\include
set LIB=%LIB%;%OPENSSL_DIR%\lib;%VPX_DIR%\lib;%SDL_DIR%\lib\x86
set LIB=%LIB%;%VPX_DIR%\lib;%SDL_DIR%\lib\x86
call "%PROGRAMFILES%\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat"
msbuild cmp_wav.vcxproj /p:PlatformToolset=v143 /p:Configuration=Release /p:Platform=win32 /p:UseEnv=true
shell: cmd
Expand All @@ -268,9 +255,8 @@ jobs:
python-version: '3.10'
- name: unit tests
run: |
$env:OPENSSL_DIR = Get-Content .\openssl_dir.txt
$env:SDL_DIR = Get-Content .\sdl_dir.txt
$env:PATH+=";$env:OPENSSL_DIR\bin;$env:SDL_DIR\lib\x86;"
$env:PATH+=";$env:SDL_DIR\lib\x86;"
cd tests/pjsua; python runall.py
cd ../../pjlib/bin; ./pjlib-test-i386-Win32-vc14-Release.exe --ci-mode
cd ../../pjlib-util/bin; ./pjlib-util-test-i386-Win32-vc14-Release.exe
Expand Down
3 changes: 2 additions & 1 deletion pjlib/build/pjlib.vcxproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug-Dynamic|ARM">
Expand Down Expand Up @@ -998,6 +998,7 @@
</ClCompile>
<ClCompile Include="..\src\pj\ssl_sock_ossl.c" />
<ClCompile Include="..\src\pj\ssl_sock_gtls.c" />
<ClCompile Include="..\src\pj\ssl_sock_schannel.c" />
<ClCompile Include="..\src\pj\string.c" />
<ClCompile Include="..\src\pj\symbols.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-Dynamic|Win32'">true</ExcludedFromBuild>
Expand Down
3 changes: 3 additions & 0 deletions pjlib/include/pj/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,9 @@
/** Using Apple's Network framework */
#define PJ_SSL_SOCK_IMP_APPLE 4

/** Using Windows's Schannel */
#define PJ_SSL_SOCK_IMP_SCHANNEL 5

/**
* Select which SSL socket implementation to use. Currently pjlib supports
* PJ_SSL_SOCK_IMP_OPENSSL, which uses OpenSSL, and PJ_SSL_SOCK_IMP_GNUTLS,
Expand Down
82 changes: 82 additions & 0 deletions pjlib/include/pj/ssl_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ typedef enum pj_ssl_cert_verify_flag_t
*/
PJ_SSL_CERT_ECHAIN_TOO_LONG = (1 << 8),

/**
* The certificate signature is created using a weak hashing algorithm.
*/
PJ_SSL_CERT_EWEAK_SIGNATURE = (1 << 9),

/**
* The server identity does not match to any identities specified in
* the certificate, e.g: subjectAltName extension, subject common name.
Expand Down Expand Up @@ -145,6 +150,59 @@ typedef enum pj_ssl_cert_name_type
PJ_SSL_CERT_NAME_IP
} pj_ssl_cert_name_type;

/**
* Field type for looking up SSL certificate in the certificate stores.
*/
typedef enum pj_ssl_cert_lookup_type
{
/**
* No certificate to be looked up.
*/
PJ_SSL_CERT_LOOKUP_NONE,

/**
* Lookup by subject, this will lookup any first certificate whose
* subject containing the specified keyword. Note that subject may not
* be unique in the store, so the lookup may end up selecting a wrong
* certificate.
*/
PJ_SSL_CERT_LOOKUP_SUBJECT,

/**
* Lookup by fingerprint/thumbprint (SHA1 hash), this will lookup
* any first certificate whose fingerprint matching the specified
* keyword. The keyword is an array of hash octets.
*/
PJ_SSL_CERT_LOOKUP_FINGERPRINT,

/**
* Lookup by friendly name, this will lookup any first certificate
* whose friendly name containing the specified keyword. Note that
* friendly name may not be unique in the store, so the lookup may end up
* selecting a wrong certificate.
*/
PJ_SSL_CERT_LOOKUP_FRIENDLY_NAME

} pj_ssl_cert_lookup_type;

/**
* Describe structure of certificate lookup criteria.
*/
typedef struct pj_ssl_cert_lookup_criteria
{
/**
* Certificate field type to look.
*/
pj_ssl_cert_lookup_type type;

/*
* Keyword to match on the field specified in \a type.
*/
pj_str_t keyword;

} pj_ssl_cert_lookup_criteria;


/**
* Describe structure of certificate info.
*/
Expand Down Expand Up @@ -273,6 +331,30 @@ PJ_DECL(pj_status_t) pj_ssl_cert_load_from_buffer(pj_pool_t *pool,
const pj_str_t *privkey_pass,
pj_ssl_cert_t **p_cert);

/**
* Create credential from OS certificate store, this function will lookup
* certificate using the specified criterias.
*
* Currently this is used by Windows Schannel backend only, it will lookup
* in the Current User store first, if no certificate with the specified
* criteria is not found, it will lookup in the Local Machine store.
*
* Note that for manual verification (e.g: when pj_ssl_sock_param.verify_peer
* is disabled), the backend will provide pre-verification result against
* trusted CA certificates in Current User store only (will not check CA
* certificates in the Local Machine store).
*
* @param pool The pool.
* @param criteria The lookup criteria.
* @param p_cert Pointer to credential instance to be created.
*
* @return PJ_SUCCESS when successful.
*/
PJ_DECL(pj_status_t) pj_ssl_cert_load_from_store(
pj_pool_t *pool,
const pj_ssl_cert_lookup_criteria *criteria,
pj_ssl_cert_t **p_cert);

/**
* Dump SSL certificate info.
*
Expand Down
6 changes: 4 additions & 2 deletions pjlib/src/pj/activesock.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,8 @@ static void ioqueue_on_read_complete(pj_ioqueue_key_t *key,
ret = (*asock->cb.on_data_read)(asock, r->pkt, r->size,
PJ_SUCCESS, &remainder);
PJ_ASSERT_ON_FAIL(
!asock->stream_oriented || remainder <= r->size, {
!ret || !asock->stream_oriented || remainder <= r->size,
{
PJ_LOG(2, ("",
"App bug! Invalid remainder length from "
"activesock on_data_read()."));
Expand Down Expand Up @@ -589,7 +590,8 @@ static void ioqueue_on_read_complete(pj_ioqueue_key_t *key,
ret = (*asock->cb.on_data_read)(asock, r->pkt, r->size,
status, &remainder);
PJ_ASSERT_ON_FAIL(
!asock->stream_oriented || remainder <= r->size, {
!ret || !asock->stream_oriented || remainder <= r->size,
{
PJ_LOG(2, ("",
"App bug! Invalid remainder length from "
"activesock on_data_read()."));
Expand Down
4 changes: 4 additions & 0 deletions pjlib/src/pj/ssl_sock_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ PJ_DEF(pj_status_t) pj_ssl_cert_get_verify_status_strings(
case PJ_SSL_CERT_ECHAIN_TOO_LONG:
p = "The certificate chain length is too long";
break;
case PJ_SSL_CERT_EWEAK_SIGNATURE:
p = "The certificate signature is created using a weak hashing "
"algorithm";
break;
case PJ_SSL_CERT_EIDENTITY_NOT_MATCH:
p = "The server identity does not match to any identities "
"specified in the certificate";
Expand Down
Loading
Loading