Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8bca259
Partially implemented ssl error decision
Colman Oct 3, 2024
32b3c83
Partially implemented ssl error decision
Colman Oct 3, 2024
f24ded9
Partially implemented ssl error decision
Colman Oct 7, 2024
c44a50d
Partially implemented ssl error decision
Colman Oct 7, 2024
b1ed63e
Partially implemented ssl error decision
Colman Oct 7, 2024
90b1457
Partially implemented ssl error decision
Colman Oct 7, 2024
de9acf9
Partially implemented ssl error decision
Colman Oct 7, 2024
fdaa89f
Partially implemented ssl error decision
Colman Oct 7, 2024
0458aba
Partially implemented ssl error decision
Colman Oct 7, 2024
e2cb3a1
Partially implemented ssl error decision
Colman Oct 7, 2024
ca81379
Partially implemented ssl error decision
Colman Oct 7, 2024
5a94528
Partially implemented ssl error decision
Colman Oct 8, 2024
ae64dae
Partially implemented ssl error decision
Colman Oct 8, 2024
a06c18c
Partially implemented ssl error decision
Colman Oct 9, 2024
7634b1f
Partially implemented ssl error decision
Colman Oct 9, 2024
c9edcdc
Partially implemented ssl error decision
Colman Oct 9, 2024
81d045a
Partially implemented ssl error decision
Colman Oct 11, 2024
a81420d
Partially implemented ssl error decision
Colman Oct 15, 2024
384e94c
Partially implemented ssl error decision
Colman Oct 15, 2024
55fb7ef
Partially implemented ssl error decision
Colman Oct 16, 2024
8cd4127
Partially implemented ssl error decision
Colman Oct 16, 2024
515580a
Partially implemented ssl error decision
Colman Oct 16, 2024
97d26ea
Partially implemented ssl error decision
Colman Oct 16, 2024
3a9f7c6
Partially implemented ssl error decision
Colman Oct 16, 2024
464dba3
Partially implemented ssl error decision
Colman Oct 16, 2024
e8a591e
Partially implemented ssl error decision
Colman Oct 16, 2024
1f396ca
Partially implemented ssl error decision
Colman Oct 16, 2024
ffe9f00
Partially implemented ssl error decision
Colman Oct 16, 2024
7a3b559
Partially implemented ssl error decision
Colman Oct 16, 2024
ffe6662
Partially implemented ssl error decision
Colman Oct 16, 2024
4988352
Partially implemented ssl error test
Colman Oct 16, 2024
9333d5d
Partially implemented ssl error test
Colman Oct 16, 2024
ac544c9
Partially implemented ssl error decision
Colman Oct 17, 2024
afe3943
Partially implemented ssl error decision
Colman Oct 17, 2024
998e334
Partially implemented ssl error decision
Colman Oct 17, 2024
941915c
Partially implemented ssl error decision
Colman Oct 17, 2024
7ef9309
Fixed versions
Colman Oct 17, 2024
b62371c
Fixed versions
Colman Oct 17, 2024
b0735a7
Added test
Colman Oct 17, 2024
7a10765
Merge branch 'main' into add-an-option-to-bypass-ssl-checks
Colman Oct 18, 2024
64266f6
Fixed change logs
Colman Oct 18, 2024
91cdee9
Added path based dependency overrides
Colman Oct 18, 2024
ae9162d
Added Dart unit tests to the Android package
Colman Oct 18, 2024
f2e0b64
Formatted files
Colman Oct 18, 2024
af4a93a
Fixed switch statements
Colman Oct 18, 2024
0fffc68
Merge branch 'main' into add-an-option-to-bypass-ssl-checks
Colman Oct 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Partially implemented ssl error decision
  • Loading branch information
Colman committed Oct 11, 2024
commit 81d045a051a32cc50dcbdbb187ddd6cf024db584
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,23 @@ NSURLCredentialPersistence FWFNativeNSURLCredentialPersistenceFromFWFNSUrlCreden

return -1;
}


FWFSslErrorTypeData FWFSslErrorTypeDataFromSecTrustResult(SecTrustResultType result) {
switch (result) {
case kSecTrustResultInvalid:
return FWFSslErrorTypeDataInvalid;
case kSecTrustResultDeny:
return FWFSslErrorTypeDataDeny;
case kSecTrustResultUnspecified:
return FWFSslErrorTypeDataUnspecified;
case kSecTrustResultRecoverableTrustFailure:
return FWFSslErrorTypeDataRecoverableTrustFailure;
case kSecTrustResultFatalTrustFailure:
return FWFSslErrorTypeDataFatalTrustFailure;
case kSecTrustResultOtherError:
return FWFSslErrorTypeDataOtherError;
default:
return -1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3395,14 +3395,14 @@ - (void)createWithIdentifier:(NSInteger)arg_identifier host:(nullable NSString *
}
}];
}
- (void)createWithIdentifier:(NSInteger)arg_identifier host:(nullable NSString *)arg_host protocol:(nullable NSString *)arg_protocol port:(NSInteger)arg_port sslError:(nullable FWFSslErrorTypeDataBox *)arg_sslError sslCertificate:(FWFSslCertificateData *)arg_sslCertificate completion:(void (^)(FlutterError *_Nullable))completion {
- (void)createWithIdentifier:(NSInteger)arg_identifier protocol:(nullable NSString *)arg_protocol host:(nullable NSString *)arg_host port:(NSInteger)arg_port sslErrorType:(nullable FWFSslErrorTypeDataBox *)arg_sslErrorType sslCertificate:(FWFSslCertificateData *)arg_sslCertificate completion:(void (^)(FlutterError *_Nullable))completion {
NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlProtectionSpaceFlutterApi.createWithServerTrust", _messageChannelSuffix];
FlutterBasicMessageChannel *channel =
[FlutterBasicMessageChannel
messageChannelWithName:channelName
binaryMessenger:self.binaryMessenger
codec:FWFNSUrlProtectionSpaceFlutterApiGetCodec()];
[channel sendMessage:@[@(arg_identifier), arg_host ?: [NSNull null], arg_protocol ?: [NSNull null], @(arg_port), arg_sslError == nil ? [NSNull null] : [NSNumber numberWithInteger:arg_sslError.value], arg_sslCertificate ?: [NSNull null]] reply:^(NSArray<id> *reply) {
[channel sendMessage:@[@(arg_identifier), arg_protocol ?: [NSNull null], arg_host ?: [NSNull null], @(arg_port), arg_sslErrorType == nil ? [NSNull null] : [NSNumber numberWithInteger:arg_sslErrorType.value], arg_sslCertificate ?: [NSNull null]] reply:^(NSArray<id> *reply) {
if (reply != nil) {
if (reply.count > 1) {
completion([FlutterError errorWithCode:reply[0] message:reply[1] details:reply[2]]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#import "./include/webview_flutter_wkwebview/FWFURLAuthenticationChallengeHostApi.h"
#import "./include/webview_flutter_wkwebview/FWFURLProtectionSpaceHostApi.h"
#import "./include/webview_flutter_wkwebview/FWFDataConverters.h"

@interface FWFURLAuthenticationChallengeFlutterApiImpl ()
// BinaryMessenger must be weak to prevent a circular reference with the host API it
Expand Down Expand Up @@ -36,13 +37,45 @@ - (void)createWithInstance:(NSURLAuthenticationChallenge *)instance
FWFURLProtectionSpaceFlutterApiImpl *protectionSpaceApi =
[[FWFURLProtectionSpaceFlutterApiImpl alloc] initWithBinaryMessenger:self.binaryMessenger
instanceManager:self.instanceManager];
[protectionSpaceApi createWithInstance:protectionSpace
host:protectionSpace.host
realm:protectionSpace.realm
authenticationMethod:protectionSpace.authenticationMethod
completion:^(FlutterError *error) {
NSAssert(!error, @"%@", error);
}];

if (protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
SecTrustRef serverTrust = protectionSpace.serverTrust;

SecTrustResultType result;
SecTrustEvaluate(serverTrust, &result);
FWFSslErrorTypeData sslErrorTypeData = FWFSslErrorTypeDataFromSecTrustResult(result);
FWFSslErrorTypeDataBox* sslErrorTypeDataBox = NULL;
if (sslErrorTypeData != -1) {
sslErrorTypeDataBox = [[FWFSslErrorTypeDataBox alloc] initWithValue: sslErrorTypeData];
}

SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
NSData* certificateDer = (NSData*)CFBridgingRelease(SecCertificateCopyData(certificate));
FlutterStandardTypedData* flutterTypedData = [FlutterStandardTypedData typedDataWithBytes:certificateDer];

FWFSslCertificateData* sslCertificateData = [FWFSslCertificateData makeWithIssuedBy:NULL
issuedTo:NULL
validNotAfterIso8601Date:NULL
validNotBeforeIso8601Date:NULL
x509CertificateDer:flutterTypedData];

[protectionSpaceApi createWithInstance:protectionSpace
host:protectionSpace.host
protocol:protectionSpace.protocol
port: protectionSpace.port
sslErrorTypeBoxed:sslErrorTypeDataBox
sslCertificate:sslCertificateData completion:^(FlutterError *error) {
NSAssert(!error, @"%@", error);
}];
} else {
[protectionSpaceApi createWithInstance:protectionSpace
host:protectionSpace.host
realm:protectionSpace.realm
authenticationMethod:protectionSpace.authenticationMethod
completion:^(FlutterError *error) {
NSAssert(!error, @"%@", error);
}];
}

[self.api createWithIdentifier:[self.instanceManager addHostCreatedInstance:instance]
protectionSpaceIdentifier:[self.instanceManager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,23 @@ - (void)createWithInstance:(NSURLProtectionSpace *)instance
completion:completion];
}
}

- (void)createWithInstance:(NSURLProtectionSpace *)instance
host:(nullable NSString *)host
protocol:(nullable NSString *)protocol
port:(NSInteger)port
sslErrorTypeBoxed:(nullable FWFSslErrorTypeDataBox *) sslErrorTypeBoxed
sslCertificate:(FWFSslCertificateData *) sslCertificate
completion:(void (^)(FlutterError *_Nullable))completion {
if (![self.instanceManager containsInstance:instance]) {
[self.api createWithIdentifier:[self.instanceManager addHostCreatedInstance:instance]
host:host
protocol:protocol
port:port
sslErrorType:sslErrorTypeBoxed
sslCertificate:sslCertificate
completion:completion];
}
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,11 @@ extern NSURLCredentialPersistence
FWFNativeNSURLCredentialPersistenceFromFWFNSUrlCredentialPersistence(
FWFNSUrlCredentialPersistence value);

/// Converts an SecTrustResultType to an FWFSslErrorTypeData.
///
/// @param value The object containing information to create an FWFSslErrorTypeData.
///
/// @return A FWFSslErrorTypeData or -1 if data could not be converted.
extern FWFSslErrorTypeData FWFSslErrorTypeDataFromSecTrustResult(SecTrustResultType value);

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,7 @@ NSObject<FlutterMessageCodec> *FWFNSUrlProtectionSpaceFlutterApiGetCodec(void);
/// Create a new Dart instance and add it to the `InstanceManager`.
- (void)createWithIdentifier:(NSInteger)identifier host:(nullable NSString *)host realm:(nullable NSString *)realm authenticationMethod:(nullable NSString *)authenticationMethod completion:(void (^)(FlutterError *_Nullable))completion;
/// Create a new Dart instance and add it to the `InstanceManager`.
- (void)createWithIdentifier:(NSInteger)identifier host:(nullable NSString *)host protocol:(nullable NSString *)protocol port:(NSInteger)port sslError:(nullable FWFSslErrorTypeDataBox *)sslErrorBoxed sslCertificate:(FWFSslCertificateData *)sslCertificate completion:(void (^)(FlutterError *_Nullable))completion;
- (void)createWithIdentifier:(NSInteger)identifier protocol:(nullable NSString *)protocol host:(nullable NSString *)host port:(NSInteger)port sslErrorType:(nullable FWFSslErrorTypeDataBox *)sslErrorTypeBoxed sslCertificate:(FWFSslCertificateData *)sslCertificate completion:(void (^)(FlutterError *_Nullable))completion;
@end

/// The codec used by FWFNSUrlAuthenticationChallengeFlutterApi.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ NS_ASSUME_NONNULL_BEGIN
realm:(nullable NSString *)realm
authenticationMethod:(nullable NSString *)authenticationMethod
completion:(void (^)(FlutterError *_Nullable))completion;
/// Sends a message to Dart to create a new Dart instance and add it to the `InstanceManager`.
- (void)createWithInstance:(NSURLProtectionSpace *)instance
host:(nullable NSString *)host
protocol:(nullable NSString *)protocol
port:(NSInteger)port
sslErrorTypeBoxed:(nullable FWFSslErrorTypeDataBox *) sslErrorTypeBoxed
sslCertificate:(FWFSslCertificateData *) sslCertificate
completion:(void (^)(FlutterError *_Nullable))completion;
@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 60;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3511,7 +3511,7 @@ abstract class NSUrlProtectionSpaceFlutterApi {
void create(int identifier, String? host, String? realm, String? authenticationMethod);

/// Create a new Dart instance and add it to the `InstanceManager`.
void createWithServerTrust(int identifier, String? host, String? protocol, int port, SslErrorTypeData? sslError, SslCertificateData sslCertificate);
void createWithServerTrust(int identifier, String? protocol, String? host, int port, SslErrorTypeData? sslErrorType, SslCertificateData sslCertificate);

static void setUp(NSUrlProtectionSpaceFlutterApi? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
Expand Down Expand Up @@ -3557,17 +3557,17 @@ abstract class NSUrlProtectionSpaceFlutterApi {
final int? arg_identifier = (args[0] as int?);
assert(arg_identifier != null,
'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlProtectionSpaceFlutterApi.createWithServerTrust was null, expected non-null int.');
final String? arg_host = (args[1] as String?);
final String? arg_protocol = (args[2] as String?);
final String? arg_protocol = (args[1] as String?);
final String? arg_host = (args[2] as String?);
final int? arg_port = (args[3] as int?);
assert(arg_port != null,
'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlProtectionSpaceFlutterApi.createWithServerTrust was null, expected non-null int.');
final SslErrorTypeData? arg_sslError = args[4] == null ? null : SslErrorTypeData.values[args[4]! as int];
final SslErrorTypeData? arg_sslErrorType = args[4] == null ? null : SslErrorTypeData.values[args[4]! as int];
final SslCertificateData? arg_sslCertificate = (args[5] as SslCertificateData?);
assert(arg_sslCertificate != null,
'Argument for dev.flutter.pigeon.webview_flutter_wkwebview.NSUrlProtectionSpaceFlutterApi.createWithServerTrust was null, expected non-null SslCertificateData.');
try {
api.createWithServerTrust(arg_identifier!, arg_host, arg_protocol, arg_port!, arg_sslError, arg_sslCertificate!);
api.createWithServerTrust(arg_identifier!, arg_protocol, arg_host, arg_port!, arg_sslErrorType, arg_sslCertificate!);
return wrapResponse(empty: true);
} on PlatformException catch (e) {
return wrapResponse(error: e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';

import '../common/instance_manager.dart';
import '../common/weak_reference_utils.dart';
Expand Down Expand Up @@ -467,27 +468,49 @@ class NSUrlProtectionSpace extends NSObject {
@protected
NSUrlProtectionSpace.detached({
required this.host,
required this.realm,
required this.authenticationMethod,
this.protocol,
this.port,
this.realm,
this.sslErrorType,
this.sslCertificate,
super.binaryMessenger,
super.instanceManager,
}) : super.detached();
}) : assert((sslErrorType == null && sslCertificate == null) ||
authenticationMethod == NSUrlAuthenticationMethod.serverTrust),
super.detached();

/// The receiver’s protocol
final String? protocol;

/// The receiver’s host.
final String? host;

/// The receiver’s authentication realm.
/// The receiver’s port
final int? port;

/// The receiver’s realm
final String? realm;

/// The authentication method used by the receiver.
final String? authenticationMethod;

/// The SSL error type (only applicable if the authentication method is server trust)
final SslErrorType? sslErrorType;

/// The SSL certificate (only applicable if the authentication method is server trust)
final SslCertificate? sslCertificate;

@override
NSUrlProtectionSpace copy() {
return NSUrlProtectionSpace.detached(
protocol: protocol,
host: host,
port: port,
realm: realm,
authenticationMethod: authenticationMethod,
sslErrorType: sslErrorType,
sslCertificate: sslCertificate?.copy(),
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';

import '../common/instance_manager.dart';
import '../common/web_kit.g.dart';
Expand Down Expand Up @@ -43,6 +44,41 @@ extension _NSKeyValueChangeKeyEnumDataConverter on NSKeyValueChangeKeyEnumData {
}
}

extension _SslErrorTypeDataConverter on SslErrorTypeData {
SslErrorType toSslErrorType() {
switch (this) {
case SslErrorTypeData.unspecified:
return SslErrorType.unspecified;
case SslErrorTypeData.deny:
return SslErrorType.deny;
case SslErrorTypeData.recoverableTrustFailure:
return SslErrorType.recoverableTrustFailure;
case SslErrorTypeData.fatalTrustFailure:
return SslErrorType.fatalTrustFailure;
case SslErrorTypeData.otherError:
return SslErrorType.otherError;
case SslErrorTypeData.invalid:
return SslErrorType.invalid;
}
}
}

extension _SslCertificateDataConverter on SslCertificateData {
SslCertificate toSslCertificate() {
return SslCertificate(
issuedBy: issuedBy,
issuedTo: issuedTo,
validNotAfterDate: validNotAfterIso8601Date == null
? DateTime.parse(validNotAfterIso8601Date!)
: null,
validNotBeforeDate: validNotBeforeIso8601Date == null
? DateTime.parse(validNotBeforeIso8601Date!)
: null,
x509CertificateDer: x509CertificateDer,
);
}
}

/// Handles initialization of Flutter APIs for the Foundation library.
class FoundationFlutterApis {
/// Constructs a [FoundationFlutterApis].
Expand Down Expand Up @@ -348,6 +384,30 @@ class NSUrlProtectionSpaceFlutterApiImpl
identifier,
);
}

@override
void createWithServerTrust(
int identifier,
String? protocol,
String? host,
int port,
SslErrorTypeData? sslErrorType,
SslCertificateData sslCertificate,
) {
instanceManager.addHostCreatedInstance(
NSUrlProtectionSpace.detached(
protocol: protocol,
host: host,
port: port,
authenticationMethod: NSUrlAuthenticationMethod.serverTrust,
sslErrorType: sslErrorType?.toSslErrorType(),
sslCertificate: sslCertificate.toSslCertificate(),
binaryMessenger: binaryMessenger,
instanceManager: instanceManager,
),
identifier,
);
}
}

/// Flutter API implementation for [NSUrlAuthenticationChallenge].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1183,15 +1183,14 @@ class WebKitNavigationDelegate extends PlatformNavigationDelegate {
NSUrlAuthenticationMethod.serverTrust) {
final FutureOr<SslErrorDecision> Function(SslError)? callback =
weakThis.target?._onSslError;
final String? host = challenge.protectionSpace.host;
final String? realm = challenge.protectionSpace.realm;

if (callback != null && host != null) {
if (callback != null) {
callback(
SslError(
errorType: ,
host: host,
realm: realm,
errorType: challenge.protectionSpace.sslErrorType,
certificate: challenge.protectionSpace.sslCertificate!,
host: challenge.protectionSpace.host!,
scheme: challenge.protectionSpace.protocol!,
port: challenge.protectionSpace.port!,
),
);
return;
Expand Down
Loading