mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #4716 from julek-wolfssl/issue-4592
Verification: Domain check should only be performed on leaf certspull/4764/head
commit
15f501358d
|
@ -11222,36 +11222,39 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret,
|
|||
}
|
||||
#endif
|
||||
#if defined(OPENSSL_EXTRA)
|
||||
/* perform domain name check on the peer certificate */
|
||||
if (args->dCertInit && args->dCert && (ssl != NULL) &&
|
||||
ssl->param && ssl->param->hostName[0]) {
|
||||
/* If altNames names is present, then subject common name is ignored */
|
||||
if (args->dCert->altNames != NULL) {
|
||||
if (CheckForAltNames(args->dCert, ssl->param->hostName, NULL) != 1) {
|
||||
if (ret == 0) {
|
||||
ret = DOMAIN_NAME_MISMATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (args->dCert->subjectCN) {
|
||||
if (MatchDomainName(args->dCert->subjectCN,
|
||||
args->dCert->subjectCNLen,
|
||||
ssl->param->hostName) == 0) {
|
||||
/* Perform domain and IP check only for the leaf certificate */
|
||||
if (args->certIdx == 0) {
|
||||
/* perform domain name check on the peer certificate */
|
||||
if (args->dCertInit && args->dCert && (ssl != NULL) &&
|
||||
ssl->param && ssl->param->hostName[0]) {
|
||||
/* If altNames names is present, then subject common name is ignored */
|
||||
if (args->dCert->altNames != NULL) {
|
||||
if (CheckForAltNames(args->dCert, ssl->param->hostName, NULL) != 1) {
|
||||
if (ret == 0) {
|
||||
ret = DOMAIN_NAME_MISMATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (args->dCert->subjectCN) {
|
||||
if (MatchDomainName(args->dCert->subjectCN,
|
||||
args->dCert->subjectCNLen,
|
||||
ssl->param->hostName) == 0) {
|
||||
if (ret == 0) {
|
||||
ret = DOMAIN_NAME_MISMATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* perform IP address check on the peer certificate */
|
||||
if ((args->dCertInit != 0) && (args->dCert != NULL) && (ssl != NULL) &&
|
||||
(ssl->param != NULL) && (XSTRLEN(ssl->param->ipasc) > 0)) {
|
||||
if (CheckIPAddr(args->dCert, ssl->param->ipasc) != 0) {
|
||||
if (ret == 0) {
|
||||
ret = IPADDR_MISMATCH;
|
||||
/* perform IP address check on the peer certificate */
|
||||
if ((args->dCertInit != 0) && (args->dCert != NULL) && (ssl != NULL) &&
|
||||
(ssl->param != NULL) && (XSTRLEN(ssl->param->ipasc) > 0)) {
|
||||
if (CheckIPAddr(args->dCert, ssl->param->ipasc) != 0) {
|
||||
if (ret == 0) {
|
||||
ret = IPADDR_MISMATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
105
src/ssl.c
105
src/ssl.c
|
@ -12019,42 +12019,56 @@ int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses)
|
|||
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
|
||||
typedef struct {
|
||||
byte verifyPeer:1;
|
||||
byte verifyNone:1;
|
||||
byte failNoCert:1;
|
||||
byte failNoCertxPSK:1;
|
||||
byte verifyPostHandshake:1;
|
||||
} SetVerifyOptions;
|
||||
|
||||
static SetVerifyOptions ModeToVerifyOptions(int mode)
|
||||
{
|
||||
SetVerifyOptions opts;
|
||||
XMEMSET(&opts, 0, sizeof(SetVerifyOptions));
|
||||
|
||||
if (mode != WOLFSSL_VERIFY_DEFAULT) {
|
||||
opts.verifyNone = (mode == WOLFSSL_VERIFY_NONE);
|
||||
if (!opts.verifyNone) {
|
||||
opts.verifyPeer =
|
||||
(mode & WOLFSSL_VERIFY_PEER) != 0;
|
||||
opts.failNoCertxPSK =
|
||||
(mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) != 0;
|
||||
opts.failNoCert =
|
||||
(mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) != 0;
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
||||
opts.verifyPostHandshake =
|
||||
(mode & WOLFSSL_VERIFY_POST_HANDSHAKE) != 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
WOLFSSL_ABI
|
||||
void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc)
|
||||
{
|
||||
SetVerifyOptions opts;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
ctx->verifyPeer = 0;
|
||||
ctx->verifyNone = 0;
|
||||
ctx->failNoCert = 0;
|
||||
ctx->failNoCertxPSK = 0;
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
||||
ctx->verifyPostHandshake = 0;
|
||||
#endif
|
||||
opts = ModeToVerifyOptions(mode);
|
||||
|
||||
if (mode != WOLFSSL_VERIFY_DEFAULT) {
|
||||
if (mode == WOLFSSL_VERIFY_NONE) {
|
||||
ctx->verifyNone = 1;
|
||||
}
|
||||
else {
|
||||
if (mode & WOLFSSL_VERIFY_PEER) {
|
||||
ctx->verifyPeer = 1;
|
||||
}
|
||||
if (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) {
|
||||
ctx->failNoCertxPSK = 1;
|
||||
}
|
||||
if (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
|
||||
ctx->failNoCert = 1;
|
||||
}
|
||||
ctx->verifyNone = opts.verifyNone;
|
||||
ctx->verifyPeer = opts.verifyPeer;
|
||||
ctx->failNoCert = opts.failNoCert;
|
||||
ctx->failNoCertxPSK = opts.failNoCertxPSK;
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
||||
if (mode & WOLFSSL_VERIFY_POST_HANDSHAKE) {
|
||||
ctx->verifyPostHandshake = 1;
|
||||
}
|
||||
ctx->verifyPostHandshake = opts.verifyPostHandshake;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ctx->verifyCallback = vc;
|
||||
}
|
||||
|
@ -12075,21 +12089,20 @@ void wolfSSL_CTX_set_cert_verify_callback(WOLFSSL_CTX* ctx,
|
|||
|
||||
void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc)
|
||||
{
|
||||
SetVerifyOptions opts;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_set_verify");
|
||||
if (ssl == NULL)
|
||||
return;
|
||||
|
||||
/* Special case for verifyNone since WOLFSSL_VERIFY_NONE == 0 */
|
||||
ssl->options.verifyNone = mode == WOLFSSL_VERIFY_NONE;
|
||||
ssl->options.verifyPeer = (mode & WOLFSSL_VERIFY_PEER)
|
||||
== WOLFSSL_VERIFY_PEER;
|
||||
ssl->options.failNoCert = (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT)
|
||||
== WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
|
||||
ssl->options.failNoCertxPSK = (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK)
|
||||
== WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
|
||||
opts = ModeToVerifyOptions(mode);
|
||||
|
||||
ssl->options.verifyNone = opts.verifyNone;
|
||||
ssl->options.verifyPeer = opts.verifyPeer;
|
||||
ssl->options.failNoCert = opts.failNoCert;
|
||||
ssl->options.failNoCertxPSK = opts.failNoCertxPSK;
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
||||
ssl->options.verifyPostHandshake = (mode & WOLFSSL_VERIFY_POST_HANDSHAKE)
|
||||
== WOLFSSL_VERIFY_POST_HANDSHAKE;
|
||||
ssl->options.verifyPostHandshake = opts.verifyPostHandshake;
|
||||
#endif
|
||||
|
||||
ssl->verifyCallback = vc;
|
||||
|
@ -27467,30 +27480,32 @@ int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam,
|
|||
const char* name,
|
||||
unsigned int nameSz)
|
||||
{
|
||||
unsigned int sz = 0;
|
||||
WOLFSSL_ENTER("wolfSSL_X509_VERIFY_PARAM_set1_host");
|
||||
|
||||
if (pParam == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
XMEMSET(pParam->hostName, 0, WOLFSSL_HOST_NAME_MAX);
|
||||
|
||||
if (name == NULL)
|
||||
return WOLFSSL_SUCCESS;
|
||||
|
||||
sz = (unsigned int)XSTRLEN(name);
|
||||
|
||||
/* If name is NULL-terminated, namelen can be set to zero. */
|
||||
if (nameSz == 0 || nameSz > sz)
|
||||
nameSz = sz;
|
||||
if (nameSz == 0) {
|
||||
nameSz = (unsigned int)XSTRLEN(name);
|
||||
}
|
||||
|
||||
if (nameSz > 0 && name[nameSz - 1] == '\0')
|
||||
nameSz--;
|
||||
|
||||
if (nameSz > WOLFSSL_HOST_NAME_MAX-1)
|
||||
if (nameSz > WOLFSSL_HOST_NAME_MAX-1) {
|
||||
WOLFSSL_MSG("Truncating name");
|
||||
nameSz = WOLFSSL_HOST_NAME_MAX-1;
|
||||
}
|
||||
|
||||
if (nameSz > 0)
|
||||
if (nameSz > 0) {
|
||||
XMEMCPY(pParam->hostName, name, nameSz);
|
||||
XMEMSET(pParam->hostName + nameSz, 0,
|
||||
WOLFSSL_HOST_NAME_MAX - nameSz);
|
||||
}
|
||||
|
||||
pParam->hostName[nameSz] = '\0';
|
||||
|
||||
|
|
89
tests/api.c
89
tests/api.c
|
@ -36638,6 +36638,92 @@ static void test_wolfSSL_X509_VERIFY_PARAM(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_EXTRA) && defined(HAVE_IO_TESTS_DEPENDENCIES)
|
||||
|
||||
static int test_wolfSSL_check_domain_verify_count = 0;
|
||||
|
||||
static WC_INLINE int test_wolfSSL_check_domain_verify_cb(int preverify,
|
||||
WOLFSSL_X509_STORE_CTX* store)
|
||||
{
|
||||
AssertIntEQ(X509_STORE_CTX_get_error(store), 0);
|
||||
AssertIntEQ(preverify, 1);
|
||||
test_wolfSSL_check_domain_verify_count++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void test_wolfSSL_check_domain_client_cb(WOLFSSL* ssl)
|
||||
{
|
||||
X509_VERIFY_PARAM *param = SSL_get0_param(ssl);
|
||||
|
||||
/* Domain check should only be done on the leaf cert */
|
||||
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
|
||||
AssertIntEQ(X509_VERIFY_PARAM_set1_host(param,
|
||||
"wolfSSL Server Chain", 0), 1);
|
||||
wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_PEER,
|
||||
test_wolfSSL_check_domain_verify_cb);
|
||||
}
|
||||
|
||||
static void test_wolfSSL_check_domain_server_cb(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
/* Use a cert with different domains in chain */
|
||||
AssertIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx,
|
||||
"certs/intermediate/server-chain.pem"), WOLFSSL_SUCCESS);
|
||||
}
|
||||
|
||||
static void test_wolfSSL_check_domain(void)
|
||||
{
|
||||
tcp_ready ready;
|
||||
func_args client_args;
|
||||
func_args server_args;
|
||||
THREAD_TYPE serverThread;
|
||||
callback_functions func_cb_client;
|
||||
callback_functions func_cb_server;
|
||||
|
||||
printf(testingFmt, "wolfSSL_check_domain");
|
||||
|
||||
XMEMSET(&client_args, 0, sizeof(func_args));
|
||||
XMEMSET(&server_args, 0, sizeof(func_args));
|
||||
XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
|
||||
XMEMSET(&func_cb_server, 0, sizeof(callback_functions));
|
||||
#ifdef WOLFSSL_TIRTOS
|
||||
fdOpenSession(Task_self());
|
||||
#endif
|
||||
|
||||
StartTCP();
|
||||
InitTcpReady(&ready);
|
||||
|
||||
#if defined(USE_WINDOWS_API)
|
||||
/* use RNG to get random port if using windows */
|
||||
ready.port = GetRandomPort();
|
||||
#endif
|
||||
|
||||
server_args.signal = &ready;
|
||||
client_args.signal = &ready;
|
||||
|
||||
func_cb_client.ssl_ready = &test_wolfSSL_check_domain_client_cb;
|
||||
func_cb_server.ctx_ready = &test_wolfSSL_check_domain_server_cb;
|
||||
|
||||
client_args.callbacks = &func_cb_client;
|
||||
server_args.callbacks = &func_cb_server;
|
||||
|
||||
start_thread(test_server_nofail, &server_args, &serverThread);
|
||||
wait_tcp_ready(&server_args);
|
||||
test_client_nofail(&client_args, NULL);
|
||||
join_thread(serverThread);
|
||||
|
||||
AssertTrue(client_args.return_code);
|
||||
AssertTrue(server_args.return_code);
|
||||
|
||||
FreeTcpReady(&ready);
|
||||
|
||||
/* Should have been called once for each cert in sent chain */
|
||||
AssertIntEQ(test_wolfSSL_check_domain_verify_count, 3);
|
||||
|
||||
printf(resultFmt, passed);
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_EXTRA && HAVE_IO_TESTS_DEPENDENCIES */
|
||||
|
||||
static void test_wolfSSL_X509_get_X509_PUBKEY(void)
|
||||
{
|
||||
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD))
|
||||
|
@ -52295,6 +52381,9 @@ void ApiTest(void)
|
|||
test_wolfSSL_X509_sign2();
|
||||
test_wolfSSL_X509_get0_tbs_sigalg();
|
||||
test_wolfSSL_X509_ALGOR_get0();
|
||||
#if defined(OPENSSL_EXTRA) && defined(HAVE_IO_TESTS_DEPENDENCIES)
|
||||
test_wolfSSL_check_domain();
|
||||
#endif
|
||||
test_wolfSSL_X509_get_X509_PUBKEY();
|
||||
test_wolfSSL_X509_PUBKEY_RSA();
|
||||
test_wolfSSL_X509_PUBKEY_EC();
|
||||
|
|
Loading…
Reference in New Issue