Summary
In buildSecurityContext (lib/core/security/ssl_certificate_support.dart, lines 89–102):
SecurityContext? buildSecurityContext(SslCertificatePaths paths) {
if (!paths.hasAny) return null;
final context = SecurityContext();
if (SslCertificatePaths._nonEmpty(paths.clientCert)) {
context.useCertificateChain(paths.clientCert!.trim());
}
if (SslCertificatePaths._nonEmpty(paths.clientKey)) {
context.usePrivateKey(paths.clientKey!.trim());
}
if (SslCertificatePaths._nonEmpty(paths.rootCert)) {
context.setTrustedCertificates(paths.rootCert!.trim());
}
return context;
}
In Dart dart:io, SecurityContext() defaults to withTrustedRoots: false.
When a user configures client certificate authentication (mTLS) with clientCert and clientKey, but does not provide a custom rootCert (expecting the server certificate to be validated against the operating system's trusted root CAs, such as for AWS RDS, Google Cloud SQL, or Supabase):
The resulting SecurityContext has zero trusted root certificates. The TLS handshake fails immediately with:
HandshakeException: Certificate verify failed (unable to get local issuer certificate).
Repro
- Configure a PostgreSQL, MySQL, or Redis connection with clientCert and clientKey, leaving Root CA empty.
- Attempt to connect to a cloud database with a valid public TLS certificate.
- Observe handshake failure due to missing trusted root certificates.
Scope
- Initialize
SecurityContext(withTrustedRoots: true) in buildSecurityContext so that system root CAs are available when no custom root certificate is provided.
- If a custom
rootCert is provided, add it via context.setTrustedCertificates().
Out of scope
- Insecure skip-verification flags (
badCertificateCallback).
Summary
In
buildSecurityContext(lib/core/security/ssl_certificate_support.dart, lines 89–102):In Dart
dart:io,SecurityContext()defaults towithTrustedRoots: false.When a user configures client certificate authentication (mTLS) with
clientCertandclientKey, but does not provide a customrootCert(expecting the server certificate to be validated against the operating system's trusted root CAs, such as for AWS RDS, Google Cloud SQL, or Supabase):The resulting
SecurityContexthas zero trusted root certificates. The TLS handshake fails immediately with:HandshakeException: Certificate verify failed (unable to get local issuer certificate).Repro
Scope
SecurityContext(withTrustedRoots: true)inbuildSecurityContextso that system root CAs are available when no custom root certificate is provided.rootCertis provided, add it viacontext.setTrustedCertificates().Out of scope
badCertificateCallback).