diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c index 0d07286cf11..6b5df3520a7 100644 --- a/dlls/secur32/schannel.c +++ b/dlls/secur32/schannel.c @@ -555,16 +555,15 @@ static SECURITY_STATUS acquire_credentials_handle(ULONG fCredentialUse, if (schanCred) { - const unsigned dtls_protocols = SP_PROT_DTLS_CLIENT | SP_PROT_DTLS1_2_CLIENT; - const unsigned tls_protocols = SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_0_CLIENT | SP_PROT_TLS1_1_CLIENT | - SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_3_CLIENT; + const unsigned dtls_protocols = SP_PROT_DTLS1_X; + const unsigned non_dtls_protocols = (SP_PROT_X_CLIENTS | SP_PROT_X_SERVERS) & ~SP_PROT_DTLS1_X; status = get_cert(schanCred, &cert); if (status != SEC_E_OK && status != SEC_E_NO_CREDENTIALS) return status; cred_enabled_protocols = get_enabled_protocols(schanCred); - if ((cred_enabled_protocols & tls_protocols) && + if ((cred_enabled_protocols & non_dtls_protocols) && (cred_enabled_protocols & dtls_protocols)) return SEC_E_ALGORITHM_MISMATCH; status = SEC_E_OK; @@ -579,9 +578,13 @@ static SECURITY_STATUS acquire_credentials_handle(ULONG fCredentialUse, enabled_protocols = cred_enabled_protocols & config_enabled_protocols; else enabled_protocols = config_enabled_protocols & ~config_default_disabled_protocols; + if (!(fCredentialUse & SECPKG_CRED_OUTBOUND)) + enabled_protocols &= ~SP_PROT_X_CLIENTS; + if (!(fCredentialUse & SECPKG_CRED_INBOUND)) + enabled_protocols &= ~SP_PROT_X_SERVERS; if(!enabled_protocols) { ERR("Could not find matching protocol\n"); - return SEC_E_NO_AUTHENTICATING_AUTHORITY; + return SEC_E_ALGORITHM_MISMATCH; } if (!(creds = malloc(sizeof(*creds)))) return SEC_E_INSUFFICIENT_MEMORY; diff --git a/dlls/secur32/tests/schannel.c b/dlls/secur32/tests/schannel.c index 33915351cb3..455fcb97aa7 100644 --- a/dlls/secur32/tests/schannel.c +++ b/dlls/secur32/tests/schannel.c @@ -351,6 +351,8 @@ static void testAcquireSecurityContext(void) ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", st); if(st == SEC_E_OK) FreeCredentialsHandle(&cred); + st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &cred, NULL); + ok(st == SEC_E_NO_CREDENTIALS, "st = %08lx\n", st); memset(&cred, 0, sizeof(cred)); st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, &cred, &exp); @@ -363,6 +365,22 @@ static void testAcquireSecurityContext(void) FreeCredentialsHandle(&cred); + /* Should fail if no enabled protocols are available */ + init_cred(&schanCred); + schanCred.grbitEnabledProtocols = SP_PROT_TLS1_X_SERVER; + st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &schanCred, NULL, NULL, &cred, &exp); + ok(st == SEC_E_ALGORITHM_MISMATCH, "st = %08lx\n", st); + st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND, NULL, &schanCred, NULL, NULL, &cred, &exp); + ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", st); + FreeCredentialsHandle(&cred); + + schanCred.grbitEnabledProtocols = SP_PROT_TLS1_X_CLIENT; + st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &schanCred, NULL, NULL, &cred, &exp); + ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", st); + FreeCredentialsHandle(&cred); + st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND, NULL, &schanCred, NULL, NULL, &cred, &exp); + ok(st == SEC_E_ALGORITHM_MISMATCH, "st = %08lx\n", st); + /* Bad version in SCHANNEL_CRED */ memset(&schanCred, 0, sizeof(schanCred)); st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, @@ -1668,7 +1686,7 @@ static void test_dtls(void) SECURITY_STATUS status; TimeStamp exp; SCHANNEL_CRED cred; - CredHandle cred_handle; + CredHandle cred_handle, cred_handle2; CtxtHandle ctx_handle, ctx_handle2; SecBufferDesc buffers[3]; ULONG flags_req, flags_ret, attr, prev_buf_len; @@ -1687,6 +1705,19 @@ static void test_dtls(void) } ok( status == SEC_E_OK, "got %08lx\n", status ); + /* Should fail if both DTLS and TLS protocols are requested */ + cred.grbitEnabledProtocols |= SP_PROT_TLS1_CLIENT; + status = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &cred_handle2, &exp); + ok(status == SEC_E_ALGORITHM_MISMATCH, "status = %08lx\n", status); + + cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_CLIENT | SP_PROT_TLS1_SERVER; + status = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &cred_handle2, &exp); + ok(status == SEC_E_ALGORITHM_MISMATCH, "status = got %08lx\n", status); + + cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_CLIENT | SP_PROT_SSL3_SERVER; + status = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &cred_handle2, &exp); + ok(status == SEC_E_ALGORITHM_MISMATCH, "status = got %08lx\n", status); + flags_req = ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_EXTENDED_ERROR | ISC_REQ_DATAGRAM | ISC_REQ_USE_SUPPLIED_CREDS | ISC_REQ_CONFIDENTIALITY | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT; test_context_output_buffer_size(SP_PROT_DTLS_CLIENT | SP_PROT_DTLS1_2_CLIENT, SCH_CRED_NO_DEFAULT_CREDS, flags_req);