Compare commits
22 Commits
Author | SHA1 | Date |
---|---|---|
Nanang Izzuddin | d9e2552918 | |
Nanang Izzuddin | ae1c9ecb9b | |
Nanang Izzuddin | 43cc47af90 | |
Nanang Izzuddin | e9d470b3ed | |
Nanang Izzuddin | 30a23a5b59 | |
Nanang Izzuddin | 9f50c22cdd | |
Nanang Izzuddin | 2d55fbac52 | |
Nanang Izzuddin | 51379b9288 | |
Nanang Izzuddin | f044db6d77 | |
Nanang Izzuddin | 8fec1902c5 | |
Nanang Izzuddin | 5b31f80326 | |
Nanang Izzuddin | fcb55f5960 | |
Nanang Izzuddin | 7e87d3c117 | |
Nanang Izzuddin | aed522b581 | |
Nanang Izzuddin | 76fe133ac6 | |
Nanang Izzuddin | 68e565077c | |
Nanang Izzuddin | 0095be7706 | |
Nanang Izzuddin | 3245fed529 | |
Nanang Izzuddin | 8cafc330b4 | |
Nanang Izzuddin | e57d4a8eb9 | |
Nanang Izzuddin | bb5853af3d | |
Nanang Izzuddin | e7e4ace40a |
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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">
|
||||
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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()."));
|
||||
|
@ -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()."));
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -52,9 +52,22 @@ static pj_bool_t asock_on_data_sent (pj_activesock_t *asock,
|
|||
*******************************************************************
|
||||
*/
|
||||
|
||||
static pj_size_t next_pow2(pj_size_t n)
|
||||
{
|
||||
/* Next 32-bit power of two */
|
||||
pj_size_t power = 1;
|
||||
while (power < n && power < 0x8000000) {
|
||||
power <<= 1;
|
||||
}
|
||||
return power;
|
||||
}
|
||||
|
||||
static pj_status_t circ_init(pj_pool_factory *factory,
|
||||
circ_buf_t *cb, pj_size_t cap)
|
||||
{
|
||||
/* Round-up cap */
|
||||
cap = next_pow2(cap);
|
||||
|
||||
cb->cap = cap;
|
||||
cb->readp = 0;
|
||||
cb->writep = 0;
|
||||
|
@ -68,17 +81,24 @@ static pj_status_t circ_init(pj_pool_factory *factory,
|
|||
/* Allocate circular buffer */
|
||||
cb->buf = pj_pool_alloc(cb->pool, cap);
|
||||
if (!cb->buf) {
|
||||
pj_pool_release(cb->pool);
|
||||
pj_pool_secure_release(&cb->pool);
|
||||
return PJ_ENOMEM;
|
||||
}
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
static void circ_reset(circ_buf_t* cb)
|
||||
{
|
||||
cb->readp = 0;
|
||||
cb->writep = 0;
|
||||
cb->size = 0;
|
||||
}
|
||||
|
||||
static void circ_deinit(circ_buf_t *cb)
|
||||
{
|
||||
if (cb->pool) {
|
||||
pj_pool_release(cb->pool);
|
||||
pj_pool_secure_release(&cb->pool);
|
||||
cb->pool = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -104,6 +124,8 @@ static void circ_read(circ_buf_t *cb, pj_uint8_t *dst, pj_size_t len)
|
|||
pj_size_t tbc = PJ_MIN(size_after, len);
|
||||
pj_size_t rem = len - tbc;
|
||||
|
||||
pj_assert(cb->size >= len);
|
||||
|
||||
pj_memcpy(dst, cb->buf + cb->readp, tbc);
|
||||
pj_memcpy(dst + tbc, cb->buf, rem);
|
||||
|
||||
|
@ -113,6 +135,21 @@ static void circ_read(circ_buf_t *cb, pj_uint8_t *dst, pj_size_t len)
|
|||
cb->size -= len;
|
||||
}
|
||||
|
||||
/* Cancel previous read, partially or fully.
|
||||
* Should be called in the same mutex block as circ_read().
|
||||
*/
|
||||
static void circ_read_cancel(circ_buf_t* cb, pj_size_t len)
|
||||
{
|
||||
pj_assert(cb->cap - cb->size >= len);
|
||||
|
||||
if (cb->readp < len)
|
||||
cb->readp = cb->cap - (len - cb->readp);
|
||||
else
|
||||
cb->readp -= len;
|
||||
|
||||
cb->size += len;
|
||||
}
|
||||
|
||||
static pj_status_t circ_write(circ_buf_t *cb,
|
||||
const pj_uint8_t *src, pj_size_t len)
|
||||
{
|
||||
|
@ -121,14 +158,8 @@ static pj_status_t circ_write(circ_buf_t *cb,
|
|||
/* Minimum required capacity */
|
||||
pj_size_t min_cap = len + cb->size;
|
||||
|
||||
/* Next 32-bit power of two */
|
||||
min_cap--;
|
||||
min_cap |= min_cap >> 1;
|
||||
min_cap |= min_cap >> 2;
|
||||
min_cap |= min_cap >> 4;
|
||||
min_cap |= min_cap >> 8;
|
||||
min_cap |= min_cap >> 16;
|
||||
min_cap++;
|
||||
/* Round-up minimum capacity */
|
||||
min_cap = next_pow2(min_cap);
|
||||
|
||||
/* Create a new pool to hold a bigger buffer, using the same factory */
|
||||
pj_pool_t *pool = pj_pool_create(cb->pool->factory, "tls-circ%p",
|
||||
|
@ -153,7 +184,7 @@ static pj_status_t circ_write(circ_buf_t *cb,
|
|||
cb->size = old_size;
|
||||
|
||||
/* Release the previous pool */
|
||||
pj_pool_release(cb->pool);
|
||||
pj_pool_secure_release(&cb->pool);
|
||||
|
||||
/* Update circular buffer members */
|
||||
cb->pool = pool;
|
||||
|
@ -1737,7 +1768,7 @@ static pj_status_t ssl_send (pj_ssl_sock_t *ssock,
|
|||
unsigned flags)
|
||||
{
|
||||
pj_status_t status;
|
||||
int nwritten;
|
||||
int nwritten = 0;
|
||||
|
||||
/* Write the plain data to SSL, after SSL encrypts it, the buffer will
|
||||
* contain the secured data to be sent via socket. Note that re-
|
||||
|
@ -2241,8 +2272,9 @@ static void wipe_buf(pj_str_t *buf)
|
|||
}
|
||||
|
||||
PJ_DEF(void) pj_ssl_cert_wipe_keys(pj_ssl_cert_t *cert)
|
||||
{
|
||||
{
|
||||
if (cert) {
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
wipe_buf(&cert->CA_file);
|
||||
wipe_buf(&cert->CA_path);
|
||||
wipe_buf(&cert->cert_file);
|
||||
|
@ -2251,6 +2283,10 @@ PJ_DEF(void) pj_ssl_cert_wipe_keys(pj_ssl_cert_t *cert)
|
|||
wipe_buf(&cert->CA_buf);
|
||||
wipe_buf(&cert->cert_buf);
|
||||
wipe_buf(&cert->privkey_buf);
|
||||
#else
|
||||
cert->criteria.type = PJ_SSL_CERT_LOOKUP_NONE;
|
||||
wipe_buf(&cert->criteria.keyword);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2274,6 +2310,7 @@ PJ_DEF(pj_status_t) pj_ssl_cert_load_from_files2(pj_pool_t *pool,
|
|||
const pj_str_t *privkey_pass,
|
||||
pj_ssl_cert_t **p_cert)
|
||||
{
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
pj_ssl_cert_t *cert;
|
||||
|
||||
PJ_ASSERT_RETURN(pool && (CA_file || CA_path) && cert_file &&
|
||||
|
@ -2294,6 +2331,16 @@ PJ_DEF(pj_status_t) pj_ssl_cert_load_from_files2(pj_pool_t *pool,
|
|||
*p_cert = cert;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
#else
|
||||
PJ_UNUSED_ARG(pool);
|
||||
PJ_UNUSED_ARG(CA_file);
|
||||
PJ_UNUSED_ARG(CA_path);
|
||||
PJ_UNUSED_ARG(cert_file);
|
||||
PJ_UNUSED_ARG(privkey_file);
|
||||
PJ_UNUSED_ARG(privkey_pass);
|
||||
PJ_UNUSED_ARG(p_cert);
|
||||
return PJ_ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
PJ_DEF(pj_status_t) pj_ssl_cert_load_from_buffer(pj_pool_t *pool,
|
||||
|
@ -2303,6 +2350,7 @@ PJ_DEF(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)
|
||||
{
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
pj_ssl_cert_t *cert;
|
||||
|
||||
PJ_ASSERT_RETURN(pool && CA_buf && cert_buf && privkey_buf, PJ_EINVAL);
|
||||
|
@ -2316,8 +2364,44 @@ PJ_DEF(pj_status_t) pj_ssl_cert_load_from_buffer(pj_pool_t *pool,
|
|||
*p_cert = cert;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
#else
|
||||
PJ_UNUSED_ARG(pool);
|
||||
PJ_UNUSED_ARG(CA_buf);
|
||||
PJ_UNUSED_ARG(cert_buf);
|
||||
PJ_UNUSED_ARG(privkey_buf);
|
||||
PJ_UNUSED_ARG(privkey_pass);
|
||||
PJ_UNUSED_ARG(p_cert);
|
||||
return PJ_ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PJ_DEF(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)
|
||||
{
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
pj_ssl_cert_t *cert;
|
||||
|
||||
PJ_ASSERT_RETURN(pool && criteria && p_cert, PJ_EINVAL);
|
||||
|
||||
cert = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t);
|
||||
pj_memcpy(&cert->criteria, criteria, sizeof(*criteria));
|
||||
pj_strdup_with_null(pool, &cert->criteria.keyword, &criteria->keyword);
|
||||
|
||||
*p_cert = cert;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
#else
|
||||
PJ_UNUSED_ARG(pool);
|
||||
PJ_UNUSED_ARG(criteria);
|
||||
PJ_UNUSED_ARG(p_cert);
|
||||
return PJ_ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Set SSL socket credentials. */
|
||||
PJ_DEF(pj_status_t) pj_ssl_sock_set_certificate(
|
||||
pj_ssl_sock_t *ssock,
|
||||
|
@ -2330,6 +2414,8 @@ PJ_DEF(pj_status_t) pj_ssl_sock_set_certificate(
|
|||
|
||||
cert_ = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t);
|
||||
pj_memcpy(cert_, cert, sizeof(pj_ssl_cert_t));
|
||||
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
pj_strdup_with_null(pool, &cert_->CA_file, &cert->CA_file);
|
||||
pj_strdup_with_null(pool, &cert_->CA_path, &cert->CA_path);
|
||||
pj_strdup_with_null(pool, &cert_->cert_file, &cert->cert_file);
|
||||
|
@ -2339,6 +2425,10 @@ PJ_DEF(pj_status_t) pj_ssl_sock_set_certificate(
|
|||
pj_strdup(pool, &cert_->CA_buf, &cert->CA_buf);
|
||||
pj_strdup(pool, &cert_->cert_buf, &cert->cert_buf);
|
||||
pj_strdup(pool, &cert_->privkey_buf, &cert->privkey_buf);
|
||||
#else
|
||||
pj_strdup_with_null(pool, &cert_->criteria.keyword,
|
||||
&cert->criteria.keyword);
|
||||
#endif
|
||||
|
||||
ssock->cert = cert_;
|
||||
|
||||
|
|
|
@ -152,6 +152,7 @@ struct pj_ssl_sock_t
|
|||
*/
|
||||
struct pj_ssl_cert_t
|
||||
{
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
pj_str_t CA_file;
|
||||
pj_str_t CA_path;
|
||||
pj_str_t cert_file;
|
||||
|
@ -162,6 +163,9 @@ struct pj_ssl_cert_t
|
|||
pj_ssl_cert_buffer CA_buf;
|
||||
pj_ssl_cert_buffer cert_buf;
|
||||
pj_ssl_cert_buffer privkey_buf;
|
||||
#else
|
||||
pj_ssl_cert_lookup_criteria criteria;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* ssl available ciphers */
|
||||
|
@ -205,9 +209,11 @@ static pj_status_t flush_delayed_send(pj_ssl_sock_t *ssock);
|
|||
static pj_status_t circ_init(pj_pool_factory *factory,
|
||||
circ_buf_t *cb, pj_size_t cap);
|
||||
static void circ_deinit(circ_buf_t *cb);
|
||||
static void circ_reset(circ_buf_t* cb);
|
||||
static pj_bool_t circ_empty(const circ_buf_t *cb);
|
||||
static pj_size_t circ_size(const circ_buf_t *cb);
|
||||
static void circ_read(circ_buf_t *cb, pj_uint8_t *dst, pj_size_t len);
|
||||
static void circ_read_cancel(circ_buf_t* cb, pj_size_t len);
|
||||
static pj_status_t circ_write(circ_buf_t *cb,
|
||||
const pj_uint8_t *src, pj_size_t len);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -540,6 +540,39 @@ static pj_status_t load_cert_to_buf(pj_pool_t *pool, const pj_str_t *file_name,
|
|||
}
|
||||
#endif
|
||||
|
||||
static pj_status_t load_cert_from_store(pj_pool_t *pool,
|
||||
pj_ssl_cert_t **p_cert)
|
||||
{
|
||||
#if 0
|
||||
/* To test loading certificate from the store, follow these steps:
|
||||
* 1. Install the certificate & the private-key pair to the store,
|
||||
* and optionally set the friendly-name for it.
|
||||
* 2. Update the lookup criteria below (field & keyword).
|
||||
*/
|
||||
pj_ssl_cert_lookup_criteria crit = {0};
|
||||
|
||||
/* Lookup by subject */
|
||||
crit.type = PJ_SSL_CERT_LOOKUP_SUBJECT;
|
||||
pj_cstr(&crit.keyword, "test.pjsip.org");
|
||||
|
||||
/* Lookup by friendly-name */
|
||||
//crit.type = PJ_SSL_CERT_LOOKUP_FRIENDLY_NAME;
|
||||
//pj_cstr(&crit.keyword, "schannel-test");
|
||||
|
||||
/* Lookup by fingerprint */
|
||||
//crit.type = PJ_SSL_CERT_LOOKUP_FINGERPRINT;
|
||||
//pj_cstr(&crit.keyword, "\x08\x3a\x6c\xdc\xd0\x19\x59\xec\x28\xc3"
|
||||
// "\x81\xb8\xc0\x21\x09\xe9\xd5\xf6\x57\x7d");
|
||||
|
||||
return pj_ssl_cert_load_from_store(pool, &crit, p_cert);
|
||||
#else
|
||||
/* Set no certificate, Schannel will use self-signed cert */
|
||||
PJ_UNUSED_ARG(pool);
|
||||
PJ_UNUSED_ARG(p_cert);
|
||||
return PJ_ENOTFOUND;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
|
||||
pj_ssl_cipher srv_cipher, pj_ssl_cipher cli_cipher,
|
||||
pj_bool_t req_client_cert, pj_bool_t client_provide_cert)
|
||||
|
@ -602,6 +635,19 @@ static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
|
|||
}
|
||||
|
||||
/* Set server cert */
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
/* Schannel backend currently can only load certificates from
|
||||
* OS cert store. If the certificate loading fails, we'll skip setting
|
||||
* certificate, so the SSL socket will create & use a self-signed cert.
|
||||
*/
|
||||
status = load_cert_from_store(pool, &cert);
|
||||
if (status == PJ_SUCCESS) {
|
||||
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
pj_str_t ca_file = pj_str(CERT_CA_FILE);
|
||||
pj_str_t cert_file = pj_str(CERT_FILE);
|
||||
|
@ -643,6 +689,7 @@ static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
|
|||
goto on_return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
status = pj_ssl_sock_start_accept(ssock_serv, pool, &addr, pj_sockaddr_get_len(&addr));
|
||||
if (status != PJ_SUCCESS) {
|
||||
|
@ -686,9 +733,22 @@ static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
|
|||
goto on_return;
|
||||
}
|
||||
|
||||
/* Set cert for client */
|
||||
{
|
||||
/* Set cert for client.
|
||||
* Reusing certificate for server above, but if client_provide_cert
|
||||
* is not set, override the certificate with CA certificate.
|
||||
*/
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
if (client_provide_cert) {
|
||||
status = load_cert_from_store(pool, &cert);
|
||||
if (status == PJ_SUCCESS)
|
||||
status = pj_ssl_sock_set_certificate(ssock_cli, pool, cert);
|
||||
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
if (!client_provide_cert) {
|
||||
pj_str_t ca_file = pj_str(CERT_CA_FILE);
|
||||
pj_str_t null_str = pj_str("");
|
||||
|
@ -720,6 +780,7 @@ static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
|
|||
goto on_return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
status = pj_ssl_sock_start_connect(ssock_cli, pool, &addr, &listen_addr, pj_sockaddr_get_len(&addr));
|
||||
if (status == PJ_SUCCESS) {
|
||||
|
@ -926,7 +987,41 @@ static int client_non_ssl(unsigned ms_timeout)
|
|||
goto on_return;
|
||||
}
|
||||
|
||||
pj_ssl_sock_param_default(¶m);
|
||||
param.cb.on_accept_complete2 = &ssl_on_accept_complete;
|
||||
param.cb.on_data_read = &ssl_on_data_read;
|
||||
param.cb.on_data_sent = &ssl_on_data_sent;
|
||||
param.ioqueue = ioqueue;
|
||||
param.timer_heap = timer;
|
||||
param.timeout.sec = 0;
|
||||
param.timeout.msec = ms_timeout;
|
||||
pj_time_val_normalize(¶m.timeout);
|
||||
|
||||
/* SERVER */
|
||||
param.user_data = &state_serv;
|
||||
state_serv.pool = pool;
|
||||
state_serv.is_server = PJ_TRUE;
|
||||
state_serv.is_verbose = PJ_TRUE;
|
||||
|
||||
status = pj_ssl_sock_create(pool, ¶m, &ssock_serv);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
|
||||
/* Set cert */
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
/* Schannel backend currently can only load certificates from
|
||||
* OS cert store. If the certificate loading fails, we'll skip setting
|
||||
* certificate, so the SSL socket will create & use a self-signed cert.
|
||||
*/
|
||||
status = load_cert_from_store(pool, &cert);
|
||||
if (status == PJ_SUCCESS) {
|
||||
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
pj_str_t ca_file = pj_str(CERT_CA_FILE);
|
||||
pj_str_t cert_file = pj_str(CERT_FILE);
|
||||
|
@ -964,31 +1059,11 @@ static int client_non_ssl(unsigned ms_timeout)
|
|||
}
|
||||
}
|
||||
|
||||
pj_ssl_sock_param_default(¶m);
|
||||
param.cb.on_accept_complete2 = &ssl_on_accept_complete;
|
||||
param.cb.on_data_read = &ssl_on_data_read;
|
||||
param.cb.on_data_sent = &ssl_on_data_sent;
|
||||
param.ioqueue = ioqueue;
|
||||
param.timer_heap = timer;
|
||||
param.timeout.sec = 0;
|
||||
param.timeout.msec = ms_timeout;
|
||||
pj_time_val_normalize(¶m.timeout);
|
||||
|
||||
/* SERVER */
|
||||
param.user_data = &state_serv;
|
||||
state_serv.pool = pool;
|
||||
state_serv.is_server = PJ_TRUE;
|
||||
state_serv.is_verbose = PJ_TRUE;
|
||||
|
||||
status = pj_ssl_sock_create(pool, ¶m, &ssock_serv);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
|
||||
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Init bind address */
|
||||
{
|
||||
|
@ -1261,7 +1336,49 @@ static int perf_test(unsigned clients, unsigned ms_handshake_timeout)
|
|||
goto on_return;
|
||||
}
|
||||
|
||||
pj_ssl_sock_param_default(¶m);
|
||||
param.cb.on_accept_complete2 = &ssl_on_accept_complete;
|
||||
param.cb.on_connect_complete = &ssl_on_connect_complete;
|
||||
param.cb.on_data_read = &ssl_on_data_read;
|
||||
param.cb.on_data_sent = &ssl_on_data_sent;
|
||||
param.ioqueue = ioqueue;
|
||||
param.timer_heap = timer;
|
||||
param.timeout.sec = 0;
|
||||
param.timeout.msec = ms_handshake_timeout;
|
||||
pj_time_val_normalize(¶m.timeout);
|
||||
|
||||
/* Init default bind address */
|
||||
{
|
||||
pj_str_t tmp_st;
|
||||
pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
|
||||
}
|
||||
|
||||
/* SERVER */
|
||||
param.user_data = &state_serv;
|
||||
|
||||
state_serv.pool = pool;
|
||||
state_serv.echo = PJ_TRUE;
|
||||
state_serv.is_server = PJ_TRUE;
|
||||
|
||||
status = pj_ssl_sock_create(pool, ¶m, &ssock_serv);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
|
||||
/* Set cert */
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
/* Schannel backend currently can only load certificates from
|
||||
* OS cert store. If the certificate loading fails, we'll skip setting
|
||||
* certificate, so the SSL socket will create & use a self-signed cert.
|
||||
*/
|
||||
status = load_cert_from_store(pool, &cert);
|
||||
if (status == PJ_SUCCESS) {
|
||||
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
pj_str_t ca_file = pj_str(CERT_CA_FILE);
|
||||
pj_str_t cert_file = pj_str(CERT_FILE);
|
||||
|
@ -1299,39 +1416,11 @@ static int perf_test(unsigned clients, unsigned ms_handshake_timeout)
|
|||
}
|
||||
}
|
||||
|
||||
pj_ssl_sock_param_default(¶m);
|
||||
param.cb.on_accept_complete2 = &ssl_on_accept_complete;
|
||||
param.cb.on_connect_complete = &ssl_on_connect_complete;
|
||||
param.cb.on_data_read = &ssl_on_data_read;
|
||||
param.cb.on_data_sent = &ssl_on_data_sent;
|
||||
param.ioqueue = ioqueue;
|
||||
param.timer_heap = timer;
|
||||
param.timeout.sec = 0;
|
||||
param.timeout.msec = ms_handshake_timeout;
|
||||
pj_time_val_normalize(¶m.timeout);
|
||||
|
||||
/* Init default bind address */
|
||||
{
|
||||
pj_str_t tmp_st;
|
||||
pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
|
||||
}
|
||||
|
||||
/* SERVER */
|
||||
param.user_data = &state_serv;
|
||||
|
||||
state_serv.pool = pool;
|
||||
state_serv.echo = PJ_TRUE;
|
||||
state_serv.is_server = PJ_TRUE;
|
||||
|
||||
status = pj_ssl_sock_create(pool, ¶m, &ssock_serv);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
|
||||
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
#endif
|
||||
|
||||
status = pj_ssl_sock_start_accept(ssock_serv, pool, &addr, pj_sockaddr_get_len(&addr));
|
||||
if (status != PJ_SUCCESS) {
|
||||
|
@ -1535,6 +1624,15 @@ int ssl_sock_test(void)
|
|||
* which require SSL server, for now.
|
||||
*/
|
||||
|
||||
/* Schannel backend notes:
|
||||
* - currently it does not support ciphers settings, so we exclude tests
|
||||
* whose ciphers setting is specified.
|
||||
* - TLS protocol older than 1.0 is not supported, TLS 1.0 & 1.1 will be
|
||||
* disabled soon, TLS 1.3 is supported since Windows 11, so for now
|
||||
* we only include tests with TLS 1.2.
|
||||
*/
|
||||
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
PJ_LOG(3,("", "..echo test w/ TLSv1 and PJ_TLS_RSA_WITH_AES_256_CBC_SHA cipher"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1, PJ_SSL_SOCK_PROTO_TLS1,
|
||||
PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
|
@ -1548,6 +1646,7 @@ int ssl_sock_test(void)
|
|||
PJ_FALSE, PJ_FALSE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
PJ_LOG(3,("", "..echo test w/ compatible proto: server TLSv1.2 vs client TLSv1.2"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1_2, PJ_SSL_SOCK_PROTO_TLS1_2,
|
||||
|
@ -1556,6 +1655,7 @@ int ssl_sock_test(void)
|
|||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
PJ_LOG(3,("", "..echo test w/ compatible proto: server TLSv1.2+1.3 vs client TLSv1.3"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1_2 | PJ_SSL_SOCK_PROTO_TLS1_3, PJ_SSL_SOCK_PROTO_TLS1_3,
|
||||
-1, -1,
|
||||
|
@ -1569,9 +1669,10 @@ int ssl_sock_test(void)
|
|||
PJ_FALSE, PJ_FALSE);
|
||||
if (ret == 0)
|
||||
return PJ_EBUG;
|
||||
#endif
|
||||
|
||||
/* We can't set min/max proto for TLS protocol higher than 1.0. */
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_DARWIN)
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_DARWIN && PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
PJ_LOG(3,("", "..echo test w/ incompatible proto: server TLSv1.2 vs client TLSv1.3"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1_2, PJ_SSL_SOCK_PROTO_TLS1_3,
|
||||
-1, -1,
|
||||
|
@ -1584,7 +1685,7 @@ int ssl_sock_test(void)
|
|||
* deprecated and we only have sec_protocol_options_append_tls_ciphersuite(),
|
||||
* but there's no API to remove certain or all ciphers.
|
||||
*/
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_APPLE)
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_APPLE && PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
PJ_LOG(3,("", "..echo test w/ incompatible ciphers"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT,
|
||||
PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
|
@ -1593,6 +1694,7 @@ int ssl_sock_test(void)
|
|||
return PJ_EBUG;
|
||||
#endif
|
||||
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
PJ_LOG(3,("", "..echo test w/ client cert required but not provided"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT,
|
||||
PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
|
@ -1606,6 +1708,7 @@ int ssl_sock_test(void)
|
|||
PJ_TRUE, PJ_TRUE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
#if WITH_BENCHMARK
|
||||
PJ_LOG(3,("", "..performance test"));
|
||||
|
|
|
@ -223,6 +223,14 @@ typedef struct pj_turn_sock_tls_cfg
|
|||
*/
|
||||
pj_str_t password;
|
||||
|
||||
/**
|
||||
* Lookup certificate from OS certificate store with specified criteria.
|
||||
*
|
||||
* Currently only used by TLS backend Windows Schannel, please check
|
||||
* pj_ssl_cert_load_from_store() for more info.
|
||||
*/
|
||||
pj_ssl_cert_lookup_criteria cert_lookup;
|
||||
|
||||
/**
|
||||
* The ssl socket parameter.
|
||||
* These fields are used by TURN TLS:
|
||||
|
|
|
@ -1389,12 +1389,21 @@ static void turn_on_state(pj_turn_session *sess,
|
|||
&turn_sock->setting.tls_cfg.privkey_buf,
|
||||
&turn_sock->setting.tls_cfg.password,
|
||||
&turn_sock->cert);
|
||||
} else if (turn_sock->setting.tls_cfg.cert_lookup.type !=
|
||||
PJ_SSL_CERT_LOOKUP_NONE &&
|
||||
turn_sock->setting.tls_cfg.cert_lookup.keyword.slen)
|
||||
{
|
||||
status = pj_ssl_cert_load_from_store(
|
||||
turn_sock->pool,
|
||||
&turn_sock->setting.tls_cfg.cert_lookup,
|
||||
&turn_sock->cert);
|
||||
}
|
||||
if (status != PJ_SUCCESS) {
|
||||
turn_sock_destroy(turn_sock, status);
|
||||
pj_grp_lock_release(turn_sock->grp_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (turn_sock->cert) {
|
||||
pj_turn_sock_tls_cfg_wipe_keys(&turn_sock->setting.tls_cfg);
|
||||
}
|
||||
|
|
|
@ -184,6 +184,14 @@ typedef enum pj_ssl_cert_verify_flag_t
|
|||
PJ_SSL_CERT_EUNKNOWN = 1 << 31
|
||||
} pj_ssl_cert_verify_flag_t;
|
||||
|
||||
typedef enum pj_ssl_cert_lookup_type
|
||||
{
|
||||
PJ_SSL_CERT_LOOKUP_NONE,
|
||||
PJ_SSL_CERT_LOOKUP_SUBJECT,
|
||||
PJ_SSL_CERT_LOOKUP_FINGERPRINT,
|
||||
PJ_SSL_CERT_LOOKUP_FRIENDLY_NAME
|
||||
} pj_ssl_cert_lookup_type;
|
||||
|
||||
typedef enum pj_ice_sess_trickle
|
||||
{
|
||||
PJ_ICE_SESS_TRICKLE_DISABLED,
|
||||
|
|
|
@ -2,7 +2,7 @@ pj/types.h pj_status_t pj_constants_ pj_uint8_t pj_int32_t pj_uint32_t pj_uint
|
|||
pj/file_io.h pj_file_access
|
||||
pj/log.h pj_log_decoration
|
||||
pj/sock_qos.h pj_qos_type pj_qos_flag pj_qos_wmm_prio pj_qos_params
|
||||
pj/ssl_sock.h pj_ssl_cipher pj_ssl_sock_proto pj_ssl_cert_name_type pj_ssl_cert_verify_flag_t
|
||||
pj/ssl_sock.h pj_ssl_cipher pj_ssl_sock_proto pj_ssl_cert_name_type pj_ssl_cert_verify_flag_t pj_ssl_cert_lookup_type
|
||||
|
||||
pjnath/ice_session.h pj_ice_sess_trickle
|
||||
pjnath/nat_detect.h pj_stun_nat_type
|
||||
|
|
|
@ -188,6 +188,14 @@ typedef struct pjsip_tls_setting
|
|||
*/
|
||||
pj_ssl_cert_buffer privkey_buf;
|
||||
|
||||
/**
|
||||
* Lookup certificate from OS certificate store with specified criteria.
|
||||
*
|
||||
* Currently only used by TLS backend Windows Schannel, please check
|
||||
* pj_ssl_cert_load_from_store() for more info.
|
||||
*/
|
||||
pj_ssl_cert_lookup_criteria cert_lookup;
|
||||
|
||||
/**
|
||||
* Password to open private key.
|
||||
*/
|
||||
|
@ -474,6 +482,9 @@ PJ_INLINE(void) pjsip_tls_setting_copy(pj_pool_t *pool,
|
|||
pj_strdup(pool, &dst->cert_buf, &src->cert_buf);
|
||||
pj_strdup(pool, &dst->privkey_buf, &src->privkey_buf);
|
||||
|
||||
pj_strdup_with_null(pool, &dst->cert_lookup.keyword,
|
||||
&src->cert_lookup.keyword);
|
||||
|
||||
if (src->ciphers_num) {
|
||||
unsigned i;
|
||||
dst->ciphers = (pj_ssl_cipher*) pj_pool_calloc(pool, src->ciphers_num,
|
||||
|
|
|
@ -174,6 +174,25 @@ struct TlsConfig : public PersistentObject
|
|||
*/
|
||||
string privKeyBuf;
|
||||
|
||||
/**
|
||||
* Lookup certificate from OS certificate store, this setting will
|
||||
* specify the field type to lookup.
|
||||
*
|
||||
* Currently only used by Windows Schannel backend, see also
|
||||
* \a pj_ssl_cert_load_from_store() for more info.
|
||||
*/
|
||||
pj_ssl_cert_lookup_type certLookupType;
|
||||
|
||||
/**
|
||||
* Lookup certificate from OS certificate store, this setting will
|
||||
* specify the keyword to match on the field specified in
|
||||
* \a certLookupType above.
|
||||
*
|
||||
* Currently only used by Windows Schannel backend, see also
|
||||
* \a pj_ssl_cert_load_from_store() for more info.
|
||||
*/
|
||||
string certLookupKeyword;
|
||||
|
||||
/**
|
||||
* TLS protocol method from #pjsip_ssl_method. In the future, this field
|
||||
* might be deprecated in favor of <b>proto</b> field. For now, this field
|
||||
|
|
|
@ -647,6 +647,16 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,
|
|||
&listener->cert);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
} else if (listener->tls_setting.cert_lookup.type !=
|
||||
PJ_SSL_CERT_LOOKUP_NONE &&
|
||||
listener->tls_setting.cert_lookup.keyword.slen)
|
||||
{
|
||||
status = pj_ssl_cert_load_from_store(
|
||||
pool,
|
||||
&listener->tls_setting.cert_lookup,
|
||||
&listener->cert);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
/* Register to transport manager */
|
||||
|
|
|
@ -192,6 +192,8 @@ pjsip_tls_setting TlsConfig::toPj() const
|
|||
ts.ca_buf = str2Pj(this->CaBuf);
|
||||
ts.cert_buf = str2Pj(this->certBuf);
|
||||
ts.privkey_buf = str2Pj(this->privKeyBuf);
|
||||
ts.cert_lookup.type = this->certLookupType;
|
||||
ts.cert_lookup.keyword = str2Pj(this->certLookupKeyword);
|
||||
ts.method = this->method;
|
||||
ts.ciphers_num = (unsigned)this->ciphers.size();
|
||||
ts.proto = this->proto;
|
||||
|
@ -221,6 +223,8 @@ void TlsConfig::fromPj(const pjsip_tls_setting &prm)
|
|||
this->CaBuf = pj2Str(prm.ca_buf);
|
||||
this->certBuf = pj2Str(prm.cert_buf);
|
||||
this->privKeyBuf = pj2Str(prm.privkey_buf);
|
||||
this->certLookupType= prm.cert_lookup.type;
|
||||
this->certLookupKeyword = pj2Str(prm.cert_lookup.keyword);
|
||||
this->method = (pjsip_ssl_method)prm.method;
|
||||
this->proto = prm.proto;
|
||||
// The following will only work if sizeof(enum)==sizeof(int)
|
||||
|
@ -256,6 +260,8 @@ void TlsConfig::readObject(const ContainerNode &node) PJSUA2_THROW(Error)
|
|||
NODE_READ_NUM_T ( this_node, pj_qos_type, qosType);
|
||||
readQosParams ( this_node, qosParams);
|
||||
NODE_READ_BOOL ( this_node, qosIgnoreError);
|
||||
NODE_READ_NUM_T ( this_node, pj_ssl_cert_lookup_type, certLookupType);
|
||||
NODE_READ_STRING ( this_node, certLookupKeyword);
|
||||
}
|
||||
|
||||
void TlsConfig::writeObject(ContainerNode &node) const PJSUA2_THROW(Error)
|
||||
|
@ -278,6 +284,8 @@ void TlsConfig::writeObject(ContainerNode &node) const PJSUA2_THROW(Error)
|
|||
NODE_WRITE_NUM_T ( this_node, pj_qos_type, qosType);
|
||||
writeQosParams ( this_node, qosParams);
|
||||
NODE_WRITE_BOOL ( this_node, qosIgnoreError);
|
||||
NODE_WRITE_NUM_T ( this_node, pj_ssl_cert_lookup_type, certLookupType);
|
||||
NODE_WRITE_STRING ( this_node, certLookupKeyword);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue