Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions doc/dox_comments/header_files-ja/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5435,6 +5435,22 @@ int wolfSSL_want_read(WOLFSSL* ssl);
*/
int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn);

/*!
\ingroup Setup

\brief wolfSSL_connect() または wolfSSL_accept() の前にこの関数を呼ぶと、
ピア証明書の SAN iPAddress エントリに対する IP アドレス検証を追加します。

\return SSL_SUCCESS 成功。
\return SSL_FAILURE パラメータ不正またはメモリ確保失敗。

\param ssl wolfSSL_new() で作成された WOLFSSL 構造体へのポインタ。
\param ipaddr 検証する NULL 終端 ASCII IP アドレス文字列。

\sa wolfSSL_check_domain_name
*/
int wolfSSL_check_ip_address(WOLFSSL* ssl, const char* ipaddr);

/*!
\ingroup TLS

Expand Down
31 changes: 31 additions & 0 deletions doc/dox_comments/header_files/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -6432,6 +6432,37 @@ int wolfSSL_want_write(WOLFSSL* ssl);
*/
int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn);

/*!
\ingroup Setup

\brief Calling this function before wolfSSL_connect() or wolfSSL_accept()
adds an IP-address identity check against the peer certificate SAN
iPAddress entries.

\return SSL_SUCCESS upon success.
\return SSL_FAILURE if parameters are invalid or memory allocation fails.

\param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new().
\param ipaddr NULL-terminated ASCII IP address string to verify against the
peer certificate.

_Example_
\code
int ret = 0;
WOLFSSL* ssl;
const char* ip = "127.0.0.1";
...

ret = wolfSSL_check_ip_address(ssl, ip);
if (ret != SSL_SUCCESS) {
// failed to enable IP check
}
\endcode

\sa wolfSSL_check_domain_name
*/
int wolfSSL_check_ip_address(WOLFSSL* ssl, const char* ipaddr);

/*!
\ingroup TLS

Expand Down
14 changes: 13 additions & 1 deletion src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -8627,6 +8627,7 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl)
FreeHandshakeHashes(ssl);
#endif
XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
XFREE(ssl->buffers.ipasc.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);

/* clear keys struct after session */
ForceZero(&ssl->keys, sizeof(Keys));
Expand Down Expand Up @@ -16792,7 +16793,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
(char*)ssl->buffers.domainName.buffer,
(ssl->buffers.domainName.buffer == NULL ? 0 :
(word32)XSTRLEN(ssl->buffers.domainName.buffer)),
NULL, 0) != 1) {
NULL, 0, 0) != 1) {
WOLFSSL_MSG("DomainName match failed");
/* try to get peer key still */
ret = DOMAIN_NAME_MISMATCH;
Expand All @@ -16802,6 +16803,17 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
#endif /* WOLFSSL_ALL_NO_CN_IN_SAN */
}

#ifndef OPENSSL_EXTRA
if (!ssl->options.verifyNone && ssl->buffers.ipasc.buffer) {
if (CheckIPAddr(args->dCert,
(const char*)ssl->buffers.ipasc.buffer) != 0) {
WOLFSSL_MSG("IPAddr match on alt names failed");
ret = IPADDR_MISMATCH;
WOLFSSL_ERROR_VERBOSE(ret);
}
}
#endif

/* decode peer key */
switch (args->dCert->keyOID) {
#ifndef NO_RSA
Expand Down
42 changes: 42 additions & 0 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -7462,6 +7462,48 @@ int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
}
}

/* call before SSL_connect, if verifying will add IP SAN check to
date check and signature check */
WOLFSSL_ABI
int wolfSSL_check_ip_address(WOLFSSL* ssl, const char* ipaddr)
{
WOLFSSL_ENTER("wolfSSL_check_ip_address");

if (ssl == NULL || ipaddr == NULL) {
WOLFSSL_MSG("Bad function argument: NULL");
return WOLFSSL_FAILURE;
}

if (ssl->buffers.ipasc.buffer != NULL) {
XFREE(ssl->buffers.ipasc.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
ssl->buffers.ipasc.buffer = NULL;
ssl->buffers.ipasc.length = 0;
}

ssl->buffers.ipasc.length = (word32)XSTRLEN(ipaddr);
ssl->buffers.ipasc.buffer = (byte*)XMALLOC(ssl->buffers.ipasc.length + 1,
ssl->heap, DYNAMIC_TYPE_DOMAIN);
if (ssl->buffers.ipasc.buffer == NULL) {
ssl->error = MEMORY_ERROR;
return WOLFSSL_FAILURE;
}

XMEMCPY(ssl->buffers.ipasc.buffer, ipaddr, ssl->buffers.ipasc.length);
ssl->buffers.ipasc.buffer[ssl->buffers.ipasc.length] = '\0';

#ifdef OPENSSL_EXTRA
if (ssl->param == NULL) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(ssl->param, ipaddr) !=
WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
#endif

return WOLFSSL_SUCCESS;
}

#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
const char *wolfSSL_get0_peername(WOLFSSL *ssl) {
if (ssl == NULL) {
Expand Down
100 changes: 100 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -15288,6 +15288,8 @@ static int test_wolfSSL_check_domain_basic_client_ssl(WOLFSSL* ssl)

return EXPECT_RESULT();
}
/* Verify wolfSSL_check_domain_name() controls DNS-name matching during
* handshake with expected fail/pass outcomes. */
static int test_wolfSSL_check_domain_basic(void)
{
EXPECT_DECLS;
Expand Down Expand Up @@ -15320,6 +15322,102 @@ static int test_wolfSSL_check_domain_basic(void)
}
#endif /* HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */

#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
(defined(WOLFSSL_IP_ALT_NAME) || defined(OPENSSL_ALL)) && \
!defined(OPENSSL_COMPATIBLE_DEFAULTS) && !defined(NO_SHA256)
static const char* ipaddr = NULL;
static int test_wolfSSL_check_ip_param_client_ssl(WOLFSSL* ssl)
{
EXPECT_DECLS;
X509_VERIFY_PARAM* param = NULL;

ExpectNotNull(param = SSL_get0_param(ssl));
ExpectIntEQ(X509_VERIFY_PARAM_set1_ip_asc(param, ipaddr), WOLFSSL_SUCCESS);

return EXPECT_RESULT();
}

/* Verify the OpenSSL-compat verify-param path:
* SSL_get0_param() + X509_VERIFY_PARAM_set1_ip_asc() controls IP SAN matching
* during handshake. */
static int test_wolfSSL_check_ip_param_basic(void)
{
EXPECT_DECLS;
test_ssl_cbf func_cb_client;
test_ssl_cbf func_cb_server;

XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

func_cb_client.ssl_ready = &test_wolfSSL_check_ip_param_client_ssl;

ipaddr = "127.0.0.2";
/* Expect to fail: cert SAN IP is 127.0.0.1 */
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), -1001);

ipaddr = "127.0.0.1";
/* Expect to succeed */
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), TEST_SUCCESS);

return EXPECT_RESULT();
}
#else
static int test_wolfSSL_check_ip_param_basic(void)
{
EXPECT_DECLS;
return EXPECT_RESULT();
}
#endif

#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(OPENSSL_COMPATIBLE_DEFAULTS) && !defined(NO_SHA256) && \
defined(WOLFSSL_IP_ALT_NAME)
static const char* ipaddr_api = NULL;
static int test_wolfSSL_check_ip_address_basic_client_ssl(WOLFSSL* ssl)
{
EXPECT_DECLS;

ExpectIntEQ(wolfSSL_check_ip_address(ssl, ipaddr_api), WOLFSSL_SUCCESS);

return EXPECT_RESULT();
}

/* Verify wolfSSL convenience API path:
* wolfSSL_check_ip_address() enables IP SAN matching during handshake,
* including the non-OPENSSL_EXTRA storage/verification flow. */
static int test_wolfSSL_check_ip_address_basic(void)
{
EXPECT_DECLS;
test_ssl_cbf func_cb_client;
test_ssl_cbf func_cb_server;

XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));

func_cb_client.ssl_ready = &test_wolfSSL_check_ip_address_basic_client_ssl;

ipaddr_api = "127.0.0.2";
/* Expect to fail: cert SAN IP is 127.0.0.1 */
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), -1001);

ipaddr_api = "127.0.0.1";
/* Expect to succeed */
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), TEST_SUCCESS);

return EXPECT_RESULT();
}
#else
static int test_wolfSSL_check_ip_address_basic(void)
{
EXPECT_DECLS;
return EXPECT_RESULT();
}
#endif

static int test_wolfSSL_BUF(void)
{
EXPECT_DECLS;
Expand Down Expand Up @@ -33192,6 +33290,8 @@ TEST_CASE testCases[] = {

TEST_DECL(test_wolfSSL_check_domain),
TEST_DECL(test_wolfSSL_check_domain_basic),
TEST_DECL(test_wolfSSL_check_ip_param_basic),
TEST_DECL(test_wolfSSL_check_ip_address_basic),
TEST_DECL(test_wolfSSL_cert_cb),
TEST_DECL(test_wolfSSL_cert_cb_dyn_ciphers),
TEST_DECL(test_wolfSSL_ciphersuite_auth),
Expand Down
1 change: 1 addition & 0 deletions wolfssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -4876,6 +4876,7 @@ typedef struct Buffers {
ThreadCrypt encrypt[WOLFSSL_THREADED_CRYPT_CNT];
#endif
buffer domainName; /* for client check */
buffer ipasc; /* for client IP SAN check */
buffer clearOutputBuffer;
buffer sig; /* signature data */
buffer digest; /* digest data */
Expand Down
3 changes: 3 additions & 0 deletions wolfssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3356,6 +3356,9 @@ WOLFSSL_API int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
/* call before SSL_connect, if verifying will add name check to
date check and signature check */
WOLFSSL_ABI WOLFSSL_API int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn);
/* call before SSL_connect, if verifying will add IP address check to
date check and signature check */
WOLFSSL_ABI WOLFSSL_API int wolfSSL_check_ip_address(WOLFSSL* ssl, const char* ipaddr);


/* need to call once to load library (session cache) */
Expand Down
Loading