how do i ignore ssl when connecting to url

some self-signed certificates and just connect to the network. I don't have any sensitive information in my app. I want to disable the check per connection not for all. I am new to iOS development please help. Will Apple reject the app because of that?

Answered by DTS Engineer in 305298022

You don’t need to customise HTTPS server trust evaluation to determine if the server is using a self-signed certificate. Even with ATS enabled, you still get a

NSURLAuthenticationMethodServerTrust
authentication challenge and you can make your decision based on the certificates in that challenge. At the end of this response I’ve posted a snippet that shows how to do this. Here’s what I see when I run it:
… 09:21:32… start
… 09:21:32… is self-signed: true
…
… 09:21:32… task transport error NSURLErrorDomain / -1200

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
func test() {
    NSLog("start")
    let url = URL(string: "https://self-signed.badssl.com")!
    let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60.0)
    self.session.dataTask(with: request) { (data, response, error) in
        if let error = error as NSError? {
            NSLog("task transport error %@ / %d", error.domain, error.code)
            return
        }
        let response = response as! HTTPURLResponse
        let data = data!
        NSLog("task finished with status %d, bytes %d", response.statusCode, data.count)
    }.resume()
}

func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
        let trust = challenge.protectionSpace.serverTrust!
        NSLog("is self-signed: %@", trust.isSelfSigned.flatMap { "\($0)" } ?? "unknown" )
    }
    completionHandler(.performDefaultHandling, nil)
}
extension SecTrust {

    var isSelfSigned: Bool? {
        guard SecTrustGetCertificateCount(self) == 1 else {
            return false
        }
        guard let cert = SecTrustGetCertificateAtIndex(self, 0) else {
            return nil
        }
        return cert.isSelfSigned
    }
}

extension SecCertificate {

    var isSelfSigned: Bool? {
        guard
            let subject = SecCertificateCopyNormalizedSubjectSequence(self),
            let issuer = SecCertificateCopyNormalizedIssuerSequence(self)
        else {
            return nil
        }
        return subject == issuer
    }
}

I strongly recommend that you not try to override HTTPS server trust evaluation. You wrote:

I don't have any sensitive information in my app.

but privacy is only part of the HTTPS story. HTTPS also guarantees data integrity, which is just as important. You don’t want a malicious server returning bogus data to your app, not least because that data could be structured to exploit security vulnerabilities in your app.

Anyway, this whole topic is a bit of a FAQ here on DevForums, so I wrote up the details in a separate post. Please read Customising TLS Server Trust Evaluation Considered Harmful.

Please read this through, consider the alternatives it suggests, and then post back if you have any follow-up questions.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for your response. The reason why I try to connect to a self-signed server is to give an explicit error message to my user that the server they are trying to connect to is using a self-signed certificate. So I try to connect if it's failed then I want to override it and test and see if it does connect with SSL verification. Then I assume that the server is using a self-signed certificate. Is this at-least an acceptable way of doing it?

Accepted Answer

You don’t need to customise HTTPS server trust evaluation to determine if the server is using a self-signed certificate. Even with ATS enabled, you still get a

NSURLAuthenticationMethodServerTrust
authentication challenge and you can make your decision based on the certificates in that challenge. At the end of this response I’ve posted a snippet that shows how to do this. Here’s what I see when I run it:
… 09:21:32… start
… 09:21:32… is self-signed: true
…
… 09:21:32… task transport error NSURLErrorDomain / -1200

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
func test() {
    NSLog("start")
    let url = URL(string: "https://self-signed.badssl.com")!
    let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60.0)
    self.session.dataTask(with: request) { (data, response, error) in
        if let error = error as NSError? {
            NSLog("task transport error %@ / %d", error.domain, error.code)
            return
        }
        let response = response as! HTTPURLResponse
        let data = data!
        NSLog("task finished with status %d, bytes %d", response.statusCode, data.count)
    }.resume()
}

func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
        let trust = challenge.protectionSpace.serverTrust!
        NSLog("is self-signed: %@", trust.isSelfSigned.flatMap { "\($0)" } ?? "unknown" )
    }
    completionHandler(.performDefaultHandling, nil)
}
extension SecTrust {

    var isSelfSigned: Bool? {
        guard SecTrustGetCertificateCount(self) == 1 else {
            return false
        }
        guard let cert = SecTrustGetCertificateAtIndex(self, 0) else {
            return nil
        }
        return cert.isSelfSigned
    }
}

extension SecCertificate {

    var isSelfSigned: Bool? {
        guard
            let subject = SecCertificateCopyNormalizedSubjectSequence(self),
            let issuer = SecCertificateCopyNormalizedIssuerSequence(self)
        else {
            return nil
        }
        return subject == issuer
    }
}

There's not that many examples out there for this. This is what I had to do to make it work at my end (Swift 5.7+, based on @eskimo 's answer above):

Async

	func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) {
		if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
			guard let serverTrust = challenge.protectionSpace.serverTrust, serverTrust.isSelfSigned ?? false else {
				return (.useCredential, nil)
			}
			return (.useCredential, URLCredential(trust: serverTrust))
		}
		return (.performDefaultHandling, nil)
	}

Sync

	func urlSession(_: URLSession, task _: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
		if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
			guard let serverTrust = challenge.protectionSpace.serverTrust, serverTrust.isSelfSigned ?? false else {
				return completionHandler(.useCredential, nil)
			}
			return completionHandler(.useCredential, URLCredential(trust: serverTrust))
		}
		return completionHandler(.performDefaultHandling, nil)
	}
how do i ignore ssl when connecting to url
 
 
Q