I'm developing a React Native app where my client has provided me with a Cloudflare elliptic curve (EC) type client certificate (certificate.pem) and a private key (privateKey.pem). These certificate are necessary to access APIs, as the server has rules in place to only accept requests with valid certificates.
However, I'm unfamiliar with iOS development and need guidance on how to embed these certificates into my React Native iOS app. My existing iOS code is in Objective C++ e.g (AppDelegate.mm) Can someone provide detailed step-by-step instructions on how to accomplish this? Any insights or code examples would be greatly appreciated.
Thank you!
I tried following things
MyURLSessionDelegate.h
#import <Foundation/Foundation.h>
@interface MyURLSessionDelegate : NSObject <NSURLSessionDelegate>
+ (instancetype)sharedInstance;
- (NSURLSession *)configuredSession;
@end
MyURLSessionDelegate.mm
#import "MyURLSessionDelegate.h"
#import <Security/Security.h>
@implementation MyURLSessionDelegate
+ (instancetype)sharedInstance {
static MyURLSessionDelegate *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyURLSessionDelegate alloc] init];
});
return sharedInstance;
}
- (NSURLSession *)configuredSession {
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
// Load the client certificate
NSString *pathToCertificate = [[NSBundle mainBundle] pathForResource:@"xyz_certificateName" ofType:@"pem"];
NSData *certificateData = [NSData dataWithContentsOfFile:pathToCertificate];
if (!certificateData) {
NSLog(@"Client certificate not found");
return nil;
}
// Create a custom SSL configuration with the client certificate
NSDictionary *sslSettings = @{
(NSString *)kCFStreamSSLCertificates: @[certificateData],
(NSString *)kCFStreamSSLValidatesCertificateChain: @NO // Disable certificate chain validation if needed
};
sessionConfig.TLSMinimumSupportedProtocol = kTLSProtocol1;
sessionConfig.TLSMaximumSupportedProtocol = kTLSProtocol12;
sessionConfig.TLSMinimumSupportedProtocol = kTLSProtocol12;
sessionConfig.TLSMaximumSupportedProtocol = kTLSProtocol13;
sessionConfig.connectionProxyDictionary = sslSettings;
// Create and return NSURLSession with custom configuration and delegate
return [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
}
#pragma mark - NSURLSessionDelegate Methods
// Implement NSURLSessionDelegate methods as needed
@end
AppDelegate.mm
#import "AppDelegate.h"
#import <Firebase.h>
#import <React/RCTBundleURLProvider.h>
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>
#import <TrustKit/TrustKit.h>
#import "MyURLSessionDelegate.h"
#import "SSLPinning.h"
#import "ClientSecurity.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
self.moduleName = @“xyz_app";
self.initialProps = @{};
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
NSURLSession *session = [[MyURLSessionDelegate sharedInstance] configuredSession];
NSLog(@"session configuration: %@", session.configuration);
// Create the URL
NSURL *url = [NSURL URLWithString:@"https://xyz.example.com/rest/login"];
// Create the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
// Set the parameters
NSDictionary *parameters = @{@"username": @“example”, @"password": @“Example@123};
NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
// Set the request body
[request setHTTPBody:postData];
// Set the content type
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
// Create a data task with the session
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// Check for errors
if (error) {
NSLog(@"SS Error: %@", error);
return;
}
// Log the raw response data
NSLog(@"SS Raw Response Data: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
// Parse the response data (assuming it's JSON for example)
NSError *jsonError = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
// Check for JSON parsing errors
if (jsonError) {
NSLog(@"SS JSON Error: %@", jsonError);
return;
}
NSLog(@"SS Response: %@", json);
}];
[dataTask resume];
@end
After implementing above i am getting following result My request is getting blocked by cloudflare.
On api call i'm getting => [AxiosError: Request failed with status code 403]