Skip to content

Commit dacd828

Browse files
authored
Add documentation of how trust roots settings affect validators (#548)
Motivation: The trust roots settings have sometimes got non-obvious impacts on which validator is used. These are a legacy behaviour and so changing them is likely to cause services to encounter challenging bugs, so it's probably not worth fixing this behaviour without doing a deprecate-and-replace cycle. A deprecate-and-replace of TLSConfiguration is going to be necessary in the near-term because it is a suboptimal structure that is carrying a lot of load. For now, however, let's just make it possible for users to diagnose what is going on. Modifications: - Document the existing behaviour Result: Users have a chance of figuring out what is going on.
1 parent 8d6730f commit dacd828

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

Sources/NIOSSL/Docs.docc/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ SwiftNIO SSL | Minimum Swift Version
7070
### Articles
7171

7272
- <doc:quantum-secure-tls>
73+
- <doc:trust-roots-behavior>
7374

7475
### Channel Handlers
7576

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Trust Roots and Certificate Validation Behavior
2+
3+
Understanding how ``TLSConfiguration/trustRoots`` and ``TLSConfiguration/additionalTrustRoots`` affect certificate validation across different platforms.
4+
5+
## Overview
6+
7+
SwiftNIO SSL provides two properties in ``TLSConfiguration`` for configuring certificate validation: ``TLSConfiguration/trustRoots`` and ``TLSConfiguration/additionalTrustRoots``. The behavior of these properties differs significantly between Apple platforms and other platforms, which can lead to unexpected certificate validation failures.
8+
9+
This article explains the behavioral matrix and helps you choose the right configuration for your use case.
10+
11+
## Certificate Validation Backends
12+
13+
SwiftNIO SSL uses different certificate validation backends depending on your configuration:
14+
15+
- **SecTrust** (Apple platforms only): The system's native certificate validator, which is stricter and follows Apple's certificate validation policies
16+
- **BoringSSL**: The embedded certificate validator, which is more permissive and consistent across platforms
17+
18+
## Behavioral Matrix
19+
20+
The choice of validation backend depends on your ``TLSConfiguration/trustRoots`` and ``TLSConfiguration/additionalTrustRoots`` settings:
21+
22+
| Configuration | Apple Platforms | Other Platforms |
23+
|---------------|-----------------|-----------------|
24+
| `trustRoots = .default`, no additional trust roots | SecTrust with default settings | BoringSSL with system PEM files |
25+
| `trustRoots = nil`, no additional trust roots | SecTrust with default settings | BoringSSL with system PEM files |
26+
| `trustRoots = .file(_)`, no additional trust roots | BoringSSL with specified file | BoringSSL with specified file |
27+
| `trustRoots = .certificates(_)`, no additional trust roots | BoringSSL with specified certificates | BoringSSL with specified certificates |
28+
| `trustRoots = .default`, additional trust roots provided | SecTrust with additional roots via `SecTrustSetAnchorCertificates` | BoringSSL with system PEM files and additional roots |
29+
| `trustRoots = nil`, additional trust roots provided | SecTrust with additional roots via `SecTrustSetAnchorCertificates` | BoringSSL with system PEM files and additional roots |
30+
| `trustRoots = .file(_)`, additional trust roots provided | BoringSSL with specified file and additional roots | BoringSSL with specified file and additional roots |
31+
| `trustRoots = .certificates(_)`, additional trust roots provided | BoringSSL with specified certificates and additional roots | BoringSSL with specified certificates and additional roots |
32+
33+
## Key Behavioral Differences
34+
35+
**SecTrust:**
36+
- Used when `trustRoots` is `.default` or `nil` on Apple platforms
37+
- Enforces stricter certificate chain validation rules
38+
- May reject certificate chains that BoringSSL accepts
39+
- Behaves the same way that Safari and most other browsers do
40+
41+
**BoringSSL:**
42+
- Used in all other cases, including on Apple platforms when `trustRoots` is `.file(_)` or `.certificates(_)`
43+
- More lenient about certificate formatting and extensions
44+
- Consistent behavior across all platforms
45+
46+
## Debugging Certificate Issues
47+
48+
When certificate validation fails, check the system logs for detailed error messages:
49+
50+
```bash
51+
# macOS/iOS system logs often contain detailed certificate validation errors
52+
log show --predicate 'subsystem == "com.apple.security"' --last 1m
53+
```
54+
55+
The error messages will help you understand whether the issue is with certificate formatting, missing extensions, or chain validation problems.
56+
57+
## Topics
58+
59+
### Related Configuration
60+
61+
- ``TLSConfiguration/trustRoots``
62+
- ``TLSConfiguration/additionalTrustRoots``
63+
- ``TLSConfiguration/certificateVerification``
64+
- ``NIOSSLTrustRoots``
65+
- ``NIOSSLAdditionalTrustRoots``

Sources/NIOSSL/TLSConfiguration.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,16 @@ public struct TLSConfiguration {
320320
///
321321
/// - NOTE: If a directory path is used here to load a directory of certificates into a configuration, then the
322322
/// certificates in this directory must be formatted by `c_rehash` to create the rehash file format of `HHHHHHHH.D` with a symlink.
323+
///
324+
/// - NOTE: The choice of trust roots affects which certificate validation backend is used. See <doc:trust-roots-behavior>
325+
/// for detailed information about platform-specific behavior differences.
323326
public var trustRoots: NIOSSLTrustRoots?
324327

325328
/// Additional trust roots to use to validate certificates, used in addition to ``trustRoots``.
329+
///
330+
/// - NOTE: The combination of ``trustRoots`` and ``additionalTrustRoots`` affects which certificate validation
331+
/// backend is used on Apple platforms. See <doc:trust-roots-behavior> for detailed information about
332+
/// platform-specific behavior differences.
326333
public var additionalTrustRoots: [NIOSSLAdditionalTrustRoots]
327334

328335
/// The certificates to offer during negotiation. If not present, no certificates will be offered.

0 commit comments

Comments
 (0)