Skip to content

Commit

Permalink
Add TLS/SSL backend: Windows Schannel (#3867)
Browse files Browse the repository at this point in the history
  • Loading branch information
nanangizz committed May 8, 2024
1 parent 30829f0 commit 1dab9b6
Show file tree
Hide file tree
Showing 18 changed files with 2,071 additions and 90 deletions.
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
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

0 comments on commit 1dab9b6

Please sign in to comment.