Switching from UIWebView to WKWebView for self-signed certificates in a Cordova application

65 views Asked by At

Switching from UIWebView to WKWebView for self-signed certificates in a Cordova application

I created a cordova plugin that compares self-signed certificates against certificates stored in the bundle file and decides independently whether the device is trusted.

This plugin worked with the UIWebView framework. After updating UIWebView to WKWebView, the plugin needs to be adjusted.

Unfortunately, I can't get the callback functions that are provided via the WKWebView to be called in my code.

The plugin is created in iOS with swift

Short description of the use case

A Cordova smartphone application must send/receive data with a device via https The device is an iot-devices with a self-signed certificate.

It is not a solution to take a Let's encrypt certificate or any other certificate from a trusted CA. We need to work with self-signed certificates.

I created a smartphone application that needs to establish a TLS connection with an IoT-device which is using a certificate belonging to a private PKI, hence independently from the certificates installed on the device. On iOS, this plugin previously worked with the UIWebView framework. After having to update from UIWebView to WKWebView, I am facing issues regarding certificate validation. The plugin is created in iOS with swift.

Previously, I would create own classes

class STXTLSDelegate: NSObject, URLSessionDataDelegate, URLSessionTaskDelegate {

    func urlSession(_ session: URLSession,
                        didReceive challenge: URLAuthenticationChallenge,
                        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
            
            /* Check if challenge is of correct type, elso do nothing */
            if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
    }
}

Unfortunately, I seem to be unable to reproduce this functionality using WKWebView.

In my plugin file I tried to extend the WKNavigation delegate as follows.

extension WKNavigationDelegate {
    var testo: String { return "Test webviewengine" }
    
    
    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!)
        completionHandler(.useCredential, cred)
        print("Callback called")
    }
}

In addition I tried to extend the CDVWebViewEngineProtocol as follows

extension CDVWebViewEngineProtocol {
    var testo: String { return "Test" }
    
    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        print("!!!! Challenge received!!")
    }
    
    
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        print("!!!! Mutated Started loading")
    }
    
}

But I just can not get to a point where my own handler functions are called and I can do my own certificate handling routines.

Through some research I found out that when adding

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
    NSLog(@"Allow all");
    SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
    CFDataRef exceptions = SecTrustCopyExceptions (serverTrust);
    SecTrustSetExceptions (serverTrust, exceptions);
    CFRelease (exceptions);
    completionHandler (NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:serverTrust]);
    }

to the CDVWebViewEngine.m file of Cordova, the callback is executed and the self-signed certificate is trusted but that is not a solution since all the certificate handling routines are already implemented in the swift plugin file.

0

There are 0 answers