diff --git a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java index 602d51d..920d975 100644 --- a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java +++ b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java @@ -38,7 +38,7 @@ import static com.RNFetchBlob.RNFetchBlobConst.GET_CONTENT_INTENT; public class RNFetchBlob extends ReactContextBaseJavaModule { - private final OkHttpClient mClient; + static private OkHttpClient mClient; static ReactApplicationContext RCTContext; private static LinkedBlockingQueue taskQueue = new LinkedBlockingQueue<>(); @@ -75,6 +75,10 @@ public class RNFetchBlob extends ReactContextBaseJavaModule { }); } + public static void applyCustomOkHttpClient(OkHttpClient client) { + mClient = client; + } + @Override public String getName() { return "RNFetchBlob"; diff --git a/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.m b/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.m index cdbe6b1..c0ce9bd 100644 --- a/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.m +++ b/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.m @@ -15,6 +15,9 @@ #import "IOS7Polyfill.h" #import +#import "SecureStorage.h" +#import + typedef NS_ENUM(NSUInteger, ResponseFormat) { UTF8, @@ -450,16 +453,108 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSen } } - -- (void) URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable credantial))completionHandler +-(NSURLCredential *)getUrlCredential:(NSURLAuthenticationChallenge *)challenge path:(NSString *)path password:(NSString *)password { - if ([[options valueForKey:CONFIG_TRUSTY] boolValue]) { - completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); - } else { - completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + NSString *authMethod = [[challenge protectionSpace] authenticationMethod]; + SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; + + if ([authMethod isEqualToString:NSURLAuthenticationMethodServerTrust] || path == nil || password == nil) { + return [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + } else if (path && password) { + NSMutableArray *policies = [NSMutableArray array]; + [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)challenge.protectionSpace.host)]; + SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies); + + SecTrustResultType result; + SecTrustEvaluate(serverTrust, &result); + + if (![[NSFileManager defaultManager] fileExistsAtPath:path]) + { + return [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + } + + NSData *p12data = [NSData dataWithContentsOfFile:path]; + NSDictionary* options = @{ (id)kSecImportExportPassphrase:password }; + CFArrayRef rawItems = NULL; + OSStatus status = SecPKCS12Import((__bridge CFDataRef)p12data, + (__bridge CFDictionaryRef)options, + &rawItems); + + if (status != noErr) { + return [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + } + + NSArray* items = (NSArray*)CFBridgingRelease(rawItems); + NSDictionary* firstItem = nil; + if ((status == errSecSuccess) && ([items count]>0)) { + firstItem = items[0]; } + + SecIdentityRef identity = (SecIdentityRef)CFBridgingRetain(firstItem[(id)kSecImportItemIdentity]); + SecCertificateRef certificate = NULL; + if (identity) { + SecIdentityCopyCertificate(identity, &certificate); + if (certificate) { CFRelease(certificate); } + } + + NSMutableArray *certificates = [[NSMutableArray alloc] init]; + [certificates addObject:CFBridgingRelease(certificate)]; + + return [NSURLCredential credentialWithIdentity:identity certificates:certificates persistence:NSURLCredentialPersistenceNone]; + } + + return [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; +} + +- (NSString *)stringToHex:(NSString *)string +{ + char *utf8 = (char *)[string UTF8String]; + NSMutableString *hex = [NSMutableString string]; + while (*utf8) [hex appendFormat:@"%02X", *utf8++ & 0x00FF]; + + return [[NSString stringWithFormat:@"%@", hex] lowercaseString]; } +-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler +{ + NSString *host = challenge.protectionSpace.host; + + // Read the clientSSL info from MMKV + __block NSString *clientSSL; + SecureStorage *secureStorage = [[SecureStorage alloc] init]; + + // https://github.com/ammarahm-ed/react-native-mmkv-storage/blob/master/src/loader.js#L31 + NSString *key = [secureStorage getSecureKey:[self stringToHex:@"com.MMKV.default"]]; + + if (key == NULL) { + return; + } + + NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + NSData *cryptKey = [key dataUsingEncoding:NSUTF8StringEncoding]; + MMKV *mmkv = [MMKV mmkvWithID:@"default" cryptKey:cryptKey mode:MMKVMultiProcess]; + clientSSL = [mmkv getStringForKey:host]; + + if ([clientSSL length] != 0) { + NSData *data = [clientSSL dataUsingEncoding:NSUTF8StringEncoding]; + id dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; + NSString *path = [dict objectForKey:@"path"]; + NSString *password = [dict objectForKey:@"password"]; + credential = [self getUrlCredential:challenge path:path password:password]; + } + + completionHandler(NSURLSessionAuthChallengeUseCredential, credential); +} + +// - (void) URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable credantial))completionHandler +// { +// if ([[options valueForKey:CONFIG_TRUSTY] boolValue]) { +// completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); +// } else { +// completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); +// } +// } + - (void) URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {