|
| 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`` |
0 commit comments