TrustPin class
TrustPin SSL certificate pinning SDK for Flutter applications.
Validates server certificates against pinning configuration to mitigate man-in-the-middle (MITM) attacks. Supports strict and permissive modes.
Use shared for a single-project app, or instance for libraries and multi-tenant setups.
Basic Usage
import 'package:trustpin_sdk/trustpin_sdk.dart';
// Initialize the shared instance with your project credentials
const config = TrustPinConfiguration(
organizationId: 'your-org-id',
projectId: 'your-project-id',
publicKey: 'your-base64-public-key',
mode: TrustPinMode.strict, // Use strict mode in production
);
await TrustPin.shared.setup(config);
// Verify a certificate manually
final pemCertificate = '''
-----BEGIN CERTIFICATE-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END CERTIFICATE-----
''';
try {
await TrustPin.shared.verify('api.example.com', pemCertificate);
print('Certificate is valid!');
} catch (e) {
print('Certificate validation failed: $e');
}
Multiple Instances
Libraries or multi-tenant apps can use named instances to avoid conflicts:
final pin = TrustPin.instance('com.mylib.networking');
await pin.setup(config);
await pin.verify('api.example.com', pem);
Integration with HTTP Clients
For automatic certificate validation, use the built-in HTTP interceptors:
// With Dio (uses TrustPin.shared by default)
final dio = Dio();
dio.interceptors.add(TrustPinDioInterceptor());
// With a named instance
dio.interceptors.add(TrustPinDioInterceptor(instance: pin));
// With http package
final client = TrustPinHttpClient.create();
final response = await client.get(Uri.parse('https://api.example.com'));
client.close();
Pinning Modes
- TrustPinMode.strict: Throws errors for unregistered domains (recommended for production)
- TrustPinMode.permissive: Allows unregistered domains to bypass pinning (development/testing)
Error Handling
TrustPin provides detailed error information through TrustPinException for proper error handling and security monitoring. All errors include specific error codes that can be checked programmatically:
try {
await TrustPin.shared.verify('api.example.com', certificate);
} on TrustPinException catch (e) {
if (e.isDomainNotRegistered) {
print('Domain not configured for pinning');
} else if (e.isPinsMismatch) {
print('Certificate doesn\'t match configured pins');
} else if (e.isAllPinsExpired) {
print('All pins for this domain have expired');
}
// Handle other error types...
}
Security Considerations
-
Use TrustPinMode.strict in production.
-
Keep your public key out of source control as plain text.
-
Note: Always call setup before performing certificate verification.
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
-
isConfigurationLoaded
→ Future<
bool> -
Whether a validated pinning payload is currently cached and usable by
verify / validateConnection without a new fetch.
no setter
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
awaitConfiguration(
{Duration? timeout}) → Future< void> - Waits until this instance's pinning configuration has been fetched, signature-verified, and accepted by the SDK's integrity check — the explicit fail-closed gate that complements the now non-blocking setup.
-
fetchCertificate(
String host, {int port = 443, Duration? timeout}) → Future< String> -
Returns the TLS leaf certificate served by
host:portas a PEM string. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
setLogLevel(
TrustPinLogLevel level) → Future< void> - Sets the log level for this instance.
-
setup(
TrustPinConfiguration configuration) → Future< void> -
Initializes this instance with the given
configuration. Must be called before verify or validateConnection. -
setupWithNativeBundle(
{String? iosFileName, String? androidFileName, String? macosFileName}) → Future< void> - Initializes this instance by loading credentials from a platform bundle file at the native layer. Must be called before validateConnection.
-
toString(
) → String -
A string representation of this object.
inherited
-
validateConnection(
String host, {int port = 443, Duration? timeout}) → Future< void> -
Validates that
host:portis allowed under this instance's pinning configuration. Returns normally on success. -
verify(
String domain, String certificate) → Future< void> -
Verifies that
certificateis valid fordomainunder this instance's pinning configuration. Returns normally on success.
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Static Properties
-
logs
→ Stream<
TrustPinLogEvent> -
A broadcast stream of the native SDK's log output, for routing SDK logs
into the host app's logging pipeline (an in-app console, a file logger,
a crash reporter's breadcrumbs, …).
no setter
-
The shared (default) TrustPin instance.
final
-
validationEvents
→ Stream<
TrustPinValidationEvent> -
A broadcast stream of definitive pin-validation verdicts, for field
telemetry (recording suspected machine-in-the-middle incidents) and for
monitoring a pinning rollout.
no setter