skip to Main Content

My task is to create a remote control for Android TV for iOS. After unsuccessful attempts to find any SDK that provides such an opportunity, I decided to rewrite androidtv-remote. This library can do everything I need. To create a TLS connection, I decided to use the SocketIO. But my problem is that the TV has an untrusted certificate and the connection cannot happen.

let manager = SocketManager(
    socketURL: .init(string: "https://(host):(port)")!,
    config: [
        .sessionDelegate(self)
    ]
)

self.socketManager = manager
let socket = manager.defaultSocket

socket.onAny { event in
    print(event.event.uppercased())
}

socket.connect()


extension PairingManager: URLSessionDelegate {
    func urlSession(
        _ session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?
        ) -> Void) {
        guard let serverTrust = challenge.protectionSpace.serverTrust else {
            completionHandler(.performDefaultHandling, nil)

            return
        }

        completionHandler(.useCredential, .init(trust: serverTrust))
    }
}
  1. Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSErrorFailingURLStringKey=https://192.168.0.101:6467/socket.io/?transport=polling&b64=1&EIO=4, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <324E645E-2EB5-4024-A361-AAC93D7895C2>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <324E645E-2EB5-4024-A361-AAC93D7895C2>.<1>

  2. Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “192.168.0.101” which could put your confidential information at risk." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
    "<cert(0x10500e400) s: atvremote/MTCMSD6886EU/bangbae/EU 4K Android TV/1C:30:08:93:4C:CD i: atvremote/MTCMSD6886EU/bangbae/EU 4K Android TV/1C:30:08:93:4C:CD>"
    ), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://192.168.0.101:6467/socket.io/?transport=polling&b64=1&EIO=4, NSErrorFailingURLStringKey=https://192.168.0.101:6467/socket.io/?transport=polling&b64=1&EIO=4, NSUnderlyingError=0x2827bd110 {Error Domain=kCFErrorDomainCFNetwork Code=-1202 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x2818ec0a0>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9807, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9807, kCFStreamPropertySSLPeerCertificates=(
    "<cert(0x10500e400) s: atvremote/MTCMSD6886EU/bangbae/EU 4K Android TV/1C:30:08:93:4C:CD i: atvremote/MTCMSD6886EU/bangbae/EU 4K Android TV/1C:30:08:93:4C:CD>"
    )}}, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <5CC821A4-3477-4201-8CBE-0E2BA018DF02>.<1>"
    ), _kCFStreamErrorCodeKey=-9807, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <5CC821A4-3477-4201-8CBE-0E2BA018DF02>.<1>, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x2818ec0a0>, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “192.168.0.101” which could put your confidential information at risk.}

  3. Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorCodeKey=-4, NSUnderlyingError=0x2803512c0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x282e15f40 [0x2208eac08]>{length = 16, capacity = 16, bytes = 0x10021943c0a800650000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <49F62856-E6A2-4F2A-9A0F-B4FDA7473E3F>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <49F62856-E6A2-4F2A-9A0F-B4FDA7473E3F>.<1>"
    ), NSLocalizedDescription=The network connection was lost., NSErrorFailingURLStringKey=http://192.168.0.101:6467/socket.io/?transport=polling&b64=1&EIO=4, NSErrorFailingURLKey=http://192.168.0.101:6467/socket.io/?transport=polling&b64=1&EIO=4, _kCFStreamErrorDomainKey=4}

But as a result, I get different errors, depending on the configuration.

  1. The first error I get is with the above code
  2. The second error I get is if I don’t do the processing in the URLSessionDelegate
  3. The third error occurs if I establish a connection using the HTTP protocol and not HTTPS

2

Answers


  1. Instead of using URLSessionDelegate to bypass the SSL validation, you can manually trust the certificate on the iOS device. Here’s an example code:

    func trustCertificateManually() {
    let host = "host"
    let port = "port"
    
    guard let serverURL = URL(string: "https://(host):(port)") else {
        return
    }
    
    let serverTrust = serverURL.securityTrust()
    
    if serverTrust != nil {
        // Save the serverTrust object for the duration of your app's session
        URLCredentialStorage.shared.setCredential(
            URLCredential(trust: serverTrust!),
            for: serverURL
        )
    }
    
    // Proceed with establishing the connection
    let manager = SocketManager(socketURL: serverURL)
    // your code...
       }
    
        extension URL {
        func securityTrust() -> SecTrust? {
         var trust: SecTrust?
         let policy = SecPolicyCreateSSL(true, self.host as CFString)
         let status = SecTrustCreateWithCertificates(self as CFURL, policy, &trust)
        
        guard status == errSecSuccess else {
            return nil
        }
        
        return trust
    }
    }
    
    Login or Signup to reply.
  2. You should use the Network framework is have wrote Samir.
    NWConnection + NWParameters with NWProtocolTLS.Options

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search