Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: fc7c2fa58bb93ead23f03d5120ded2fac488bb66
      
https://github.com/WebKit/WebKit/commit/fc7c2fa58bb93ead23f03d5120ded2fac488bb66
  Author: Basuke Suzuki <[email protected]>
  Date:   2026-08-10 (Mon, 10 Aug 2026)

  Changed paths:
    M 
Source/WebKit/NetworkProcess/Authentication/cocoa/AuthenticationManagerCocoa.mm

  Log Message:
  -----------
  [WebKit Networking] Client certificate authentication challenge is never 
completed when the SecKeyProxy identity cannot be created, hanging the page load
https://bugs.webkit.org/show_bug.cgi?id=321435
rdar://182381982

Reviewed by Alex Christensen.

WebKit does not move a client certificate's private key between processes. The 
UI process wraps the
chosen SecIdentity in a SecKeyProxy and sends only the XPC endpoint plus the 
certificate chain to the
network process, which rebuilds the identity with -[SecKeyProxy 
createIdentityFromEndpoint:error:].
That call round-trips back to the UI process, so it fails whenever the private 
key's Keychain ACL
denies access - for instance a certificate provisioned by a third-party 
application whose ACL is bound
to that application's Team ID.

On failure the XPC handler only logged and returned, without completing the 
challenge. The same was
true of every other early return in the handler: a missing or non-endpoint XPC 
endpoint, a missing
certificate data array, a certificate that fails SecCertificateCreateWithData, 
and an out-of-range
persistence value. Abandoning the challenge leaves the Challenge object, which 
owns CFNetwork's
challenge completion handler, in AuthenticationManager::m_challenges forever. 
There is no timeout and
no fallback, so the TLS handshake keeps waiting for a client certificate and 
the page load stalls
indefinitely with no error shown to the user.

Move the credential reconstruction into 
credentialFromClientCertificateMessage() so that all of those
failures collapse into a single std::nullopt, and complete the challenge with 
PerformDefaultHandling
when it returns nothing. That matches the fallback 
NetworkProcessProxy::processAuthenticationChallenge
already uses for non-server-trust schemes, and turns the hang into a reportable 
load failure.

The remaining early return has to stay: there is no identifier to complete, and 
constructing one anyway
would hit the RELEASE_ASSERT in ObjectIdentifier's constructor and crash the 
network process. Validate
with ObjectIdentifier::isValidIdentifier() so the guard rejects exactly what 
that constructor rejects,
which includes the hash table deleted value as well as zero. It only gets an 
ASSERT_NOT_REACHED,
matching the message name check above it, since an invalid identifier means a 
malformed message rather
than a challenge we could fail.

This does not make client certificate authentication succeed when the ACL 
denies access; that denial
is by design and needs the certificate to be provisioned with an ACL that 
permits the requesting
applications.

No new tests (the failure path needs a Keychain ACL denial, which cannot be 
simulated in the test
harness). The unchanged success path stays covered by 
TestWebKitAPI.Challenge.ClientCertificate.

* 
Source/WebKit/NetworkProcess/Authentication/cocoa/AuthenticationManagerCocoa.mm:
(WebKit::credentialFromClientCertificateMessage):
(WebKit::AuthenticationManager::initializeConnection):

Canonical link: https://commits.webkit.org/318936@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to