cs-icon.svg

Use SSL Pinning with iOS SDK

SSL (Secure Sockets Layer) Pinning is a security technique that involves incorporating the public key or a server's certificate into the client's code.

This technique ensures that the client only connects to the server that matches the pinned certificate or public key, which prevents Man-in-the-Middle (MITM) attacks. Even if an attacker can intercept the SSL traffic, they cannot modify it because they do not have access to the server's private key.

Create Class Extending the CSURLSessionDelegate Protocol

Objective-C

Perform the following steps to create a class extending the CSURLSessionDelegate protocol for Objective-C:

  1. Create a CustomSessionPinning.h file and add the following code:
  2. #import <Contentstack/Contentstack.h>
    
    @interface CustomSessionPinning:  NSObject <CSURLSessionDelegate>{
        
    }
    @end
    
    
  3. Create the CustomSessionPinning.m file and add the following code to implement the functions for the CSURLSessionDelegate protocol as below:
  4. @implementation CustomSessionPinning
    
    - (void)URLSession:(NSURLSession * _Nonnull)session didReceiveChallenge:(NSURLAuthenticationChallenge * _Nonnull)challenge completionHandler:(void (^ _Nonnull)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
        // You can use following default pinning for server trust or implement SSL pinning here and call the completion handler    
    
         NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        __block NSURLCredential *credential = nil;
    
        if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
            disposition = NSURLSessionAuthChallengeUseCredential;
            credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        } else {
            disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        }
    
        if (completionHandler) {
            completionHandler(disposition, credential);
        }
    }
    
    - (void)URLSession:(NSURLSession * _Nonnull)session task:(NSURLSessionTask * _Nonnull)task didReceiveChallenge:(NSURLAuthenticationChallenge * _Nonnull)challenge completionHandler:(void (^ _Nonnull)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
    // You can use following default pinning for server trust or implement SSL pinning here and call the completion handler
        NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        __block NSURLCredential *credential = nil;
    
        if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
            disposition = NSURLSessionAuthChallengeUseCredential;
            credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        } else {
            disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        }
    
        if (completionHandler) {
            completionHandler(disposition, credential);
        }
    }
    
    

Let’s understand the terminologies used in this section:

  • CSURLSessionDelegate: Default constructor that initializes a new instance of a class.
  • CustomSessionPinning.h: This header file enables you to customize the session pinning functionality, which can include configuring pinning policies, specifying custom certificates or public keys for server identity validation, and implementing advanced features like certificate or public key pinning.
  • CustomSessionPinning.m: This source code file accompanies the CustomSessionPinning.h header file. It contains the actual implementation code for the custom session pinning functionality provided by the SDK. It also contains any necessary configuration or initialization code that sets up the pinning functionality. You need to customize the code in this file to meet your specific needs.

Swift

Perform the following steps to create a class extending the CSURLSessionDelegate protocol for Swift:

  1. Create a CustomeSessionPinning.swift file and add the following code:
  2. class CustomSessionPinning: NSObject, CSURLSessionDelegate {
        func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping @Sendable (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    // You can use following default pinning for server trust or implement SSL pinning here and call the completion handler
            var disposition = URLSession.AuthChallengeDisposition.performDefaultHandling
            var credential: URLCredential?
            if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
                disposition = .useCredential
                credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
            } else {
                disposition = .performDefaultHandling
            }
            
            completionHandler(disposition, credential)
        }
    
        func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping @Sendable (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    // You can use following default pinning for server trust or implement SSL pinning here and call the completion handler
            var disposition = URLSession.AuthChallengeDisposition.performDefaultHandling
            var credential: URLCredential?
            if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
                disposition = .useCredential
                credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
            } else {
                disposition = .performDefaultHandling
            }
            
            completionHandler(disposition, credential)
        }
    }
    
    

Create a Config Object and Add Delegate for CSURLSessionDelegate

The Config class is useful for providing configurations related to the stack. It also contains the configuration settings related to the SSL connection and the pinning process. You can initialize the Config object and add the delegate for CSURLSessionDelegate as shown below:

let config:Config = Config()
config.delegate = CustomSessionPinning()

Config config = [[Config alloc] init];
config.delegate = [[CustomSessionPinning alloc] init];

Initialize the Stack Instance with Config Object

Initializing the Stack instance with a Config object allows you to customize the behavior of the Stack instance and fine-tune its functionality based on your specific needs. You can specify the options such as server host, region, branch, version and other settings that affect how the SDK interacts with the server and processes requests and responses.

You can add the following code to initialize the Stack instance with the Config object as shown below:

let stack:Stack = Contentstack.stackWithAPIKey("API_KEY",accessToken:"DELIVERY_TOKEN", environmentName:@"ENVIRONMENT", config:config)

Stack stack = [Contentstack stackWithAPIKey:@"API_KEY" accessToken:@"DELIVERY_TOKEN" environmentName:@"ENVIRONMENT" config:config];

Was this article helpful?
^