NSURLErrorDomain Code=-1200

I am using the URLSession library to connect to certain pages using the https protocol. To get access to certain urls I had to create a delegate to include the public part of the certificate offered by the server. The problem I find is that in some urls the application does not call the method that I created in the delegate. What could be the problem? I include the snippet of the URLSession class and the delegated class that I created. let delegate: URLSessionDelegate = SessionDelegate() as URLSessionDelegate let urlSession = URLSession(configuration: .default, delegate: delegate, delegateQueue: nil) let task = urlSession.dataTask(with: request as URLRequest){ data, response, error in if error == nil { var htmlCode: String = "" if charset == Constantes.CHARSET_UTF8 { htmlCode = String(data: data!, encoding: .utf8)! } else { htmlCode = String(data: data!, encoding: .ascii)! } callback(htmlCode, nil) return } else { callback("", error.debugDescription) } } task.resume() And my delegate class: class SessionDelegate:NSObject, URLSessionDelegate { let certificadosName: [String] = ["AC_Administracion_Publica","ac_raiz_fnmt","Camerfirma_AAPP_II_Chambers_of_Commerce_Root","Camerfirma_Corporate_Server_II_Chambers_of_Commerce_Root","Chambers_of_Commerce_Root","claveRaiz","DigiCert_High_Assurance_EV_Root_CA","Entrust_Root_Certification_Authority_G","GeoTrust_SSL_CA_G_GeoTrust_Global_CA","Izenpe_com"] let certFileType = "cer" func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { guard challenge.previousFailureCount == 0 else { challenge.sender?.cancel(challenge) // Inform the user that the user name and password are incorrect completionHandler(.cancelAuthenticationChallenge, nil) return } if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust && challenge.protectionSpace.serverTrust != nil { let trust = challenge.protectionSpace.serverTrust var certs: [SecCertificate] = [SecCertificate]() for certificadoName in certificadosName { let pem = Bundle.main.url(forResource: certificadoName, withExtension: certFileType) let data = NSData(contentsOf: pem!) let cert = SecCertificateCreateWithData(nil, data!) certs.append(cert!) } SecTrustSetAnchorCertificates(trust!, certs as CFArray) var result=SecTrustResultType.invalid if SecTrustEvaluate(trust!,&result)==errSecSuccess { if result==SecTrustResultType.proceed || result==SecTrustResultType.unspecified { let proposedCredential = URLCredential(trust: trust!) completionHandler(.useCredential,proposedCredential) return } } } completionHandler(.performDefaultHandling, nil) } }

Answered by DTS Engineer in 403968022

Thanks!

That server does not meet ATS’s forward secrecy requirement:

% TLSTool s_client -connect www.boe.es:443
*  input stream did open
* output stream did open
* output stream has space
* protocol: TLS 1.2
* cipher: RSA_WITH_AES_256_GCM_SHA384
* trust result: unspecified
* certificate info:
*   0 + rsaEncryption 2048 sha256-with-rsa-signature 'www.boe.es'
*   1 + rsaEncryption 2048 sha256-with-rsa-signature 'TERENA SSL High Assurance CA 3'
*   2 + rsaEncryption 2048 sha1-with-rsa-signature 'DigiCert High Assurance EV Root CA'
^C

Note the cypher suite is

RSA_WITH_AES_256_GCM_SHA384
, whereas ATS requires forward secrecy via an ECDHE cypher suite. See the discussion of
NSExceptionRequiresForwardSecrecy
in the
NSExceptionDomains
documentation, and the background info in Preventing Insecure Network Connections.

Consider this code snippet:

NSLog("task will start")
let url = URL(string: "https://www.boe.es")!
let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60.0)
URLSession.shared.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()

By default, it fails with a -1200 error. I can get it working by adding the following ATS configuration:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>www.boe.es</key>
        <dict>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>

Share and Enjoy

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

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

The problem I find is that in some urls the application does not call the method that I created in the delegate. What could be the problem?

I’m sorry but your code is completely scrambled. If you fix that, I should be able to take a proper look. Specifically, use the

<>
button to insert a code block into your post.

Share and Enjoy

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

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

Sorry, I couldn´t edit my post. I write my code in this coment:


The code on my connection class

let delegate: URLSessionDelegate = SessionDelegate() as URLSessionDelegate 
let urlSession = URLSession(configuration: .default, delegate: delegate, delegateQueue: nil) 
let task = urlSession.dataTask(with: request as URLRequest)
{ data, response, error  in              
     if error == nil 
     {                                 
          var htmlCode: String = ""                 
          if charset == Constantes.CHARSET_UTF8                 
          {                     
               htmlCode = String(data: data!, encoding: .utf8)!                 
          }                
          else                 
          {                     
               htmlCode = String(data: data!, encoding: .ascii)!                 
          }                                                
          callback(htmlCode, nil)                 
           return              
     }             
     else             
     {                 
          callback("", error.debugDescription)             
     }         
}      task.resume()



Delegate Class:


class SessionDelegate:NSObject, URLSessionDelegate
{
    let certificadosName: [String] = ["AC_Administracion_Publica","ac_raiz_fnmt","Camerfirma_AAPP_II_Chambers_of_Commerce_Root","Camerfirma_Corporate_Server_II_Chambers_of_Commerce_Root","Chambers_of_Commerce_Root","claveRaiz","DigiCert_High_Assurance_EV_Root_CA","Entrust_Root_Certification_Authority_G","GeoTrust_SSL_CA_G_GeoTrust_Global_CA","Izenpe_com"]

    let certFileType = "cer"

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        guard challenge.previousFailureCount == 0 else {
            challenge.sender?.cancel(challenge)
            // Inform the user that the user name and password are incorrect
            completionHandler(.cancelAuthenticationChallenge, nil)
            return
        }

        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
           && challenge.protectionSpace.serverTrust != nil
        {

            let trust = challenge.protectionSpace.serverTrust
            
            var certs: [SecCertificate] = [SecCertificate]()
            for certificadoName in certificadosName
            {
                let pem = Bundle.main.url(forResource: certificadoName, withExtension: certFileType)
                let data = NSData(contentsOf: pem!)
                let cert = SecCertificateCreateWithData(nil, data!)
                
                certs.append(cert!)
            }
            
            SecTrustSetAnchorCertificates(trust!, certs as CFArray)
            var result=SecTrustResultType.invalid
            if SecTrustEvaluate(trust!,&result)==errSecSuccess {
              if result==SecTrustResultType.proceed || result==SecTrustResultType.unspecified {
                let proposedCredential = URLCredential(trust: trust!)
                completionHandler(.useCredential,proposedCredential)
                return
              }
                
            }
        }
        completionHandler(.performDefaultHandling, nil)
    }
}

Thanks for the cleaned up code. I have two questions about the challenge handling in your

SessionDelegate
, one simple and one more in depth:
  • What are lines 8…13 about? The comment talks about “user name and password”, but you then only go on to deal with serve trust authentication challenges.

  • Stepping back, what’s the big picture here? From the code it’s clear that you’re customisation HTTPS server trust evaluation to trust a custom root certificate [1]. Are you working on an enterprise app? Or an app that you plan to distribute to a wide range of App Store customers? Also, is this customisation needed for just a small set of servers? Or a wide range?

Share and Enjoy

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

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

[1] The name

AC_Administracion_Publica
suggestions you’re specifically interested in the Brazilian state of Acre, and this isn’t the first time I’ve encountered Brazil’s fascinating PKI setup.

Thanks for your reply. I answer by parts.


Regarding the first question, indicate that I have based on a code that I have found searching on the Internet and it is true that reviewing the execution of my app, never enters that code fragment, so, I understand that this part could be expendable.


Regarding the global vision of my app, I explain it below. The app aims to serve as a single point of access to online procedures of different Spanish public administrations to facilitate daily procedures with the administration (the android version is this https://play.google.com/store/apps/details?id=com.tramite&hl=en). Therefore, I need to be able to rely on access to urls of various administrations. My problem is that the code of my delegated class is executed for the majority when making the call to the url, but for a couple of them it is not, and I do not understand the reason.

My problem is that the code of my delegated class is executed for the majority when making the call to the url, but for a couple of them it is not, and I do not understand the reason.

There’s two possibilities here:

  • The request may be blocked by App Transport Security (ATS).

  • The server’s TLS implementation may be incompatible with iOS.

As an investigation step, you can rule out the first possibility by setting

NSAllowsArbitraryLoads
. That effectively disables ATS.

IMPORTANT Don’t ship like that! Once you’ve finished your investigation, you should use those results to inform your final ATS configuration.

If you do this, do you still see connection problems?

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. I have tried to enable NSAllowsArbitraryLoads and in this case my delegated class runs correctly and I can reach the urls that did not arrive before. In this case, what is the best solution to use?

I have tried to enable

NSAllowsArbitraryLoads
and in this case my delegated class runs correctly and I can reach the urls that did not arrive before.

OK. That pretty much confirms that the problematic servers are problematic because they don’t meet ATS’s enhanced security requirements.

In this case, what is the best solution to use?

The best solution here is to yell at the folks maintaining these servers until they upgrade them (-: Seriously though, back when ATS was introduced, its enhanced security requirements were cutting edge. Nowadays, they are de rigueur.

If you can’t get these servers fixed, you need a client-side workaround, and than lands you in the world of ATS exceptions. How you handle that depends on the scope of your app:

Share and Enjoy

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

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

Thank you very much for your support. In this case, I have no way of shouting at the people who maintain those servers, so that option is not possible. Given that the user is only going to access the urls that the app offers, I will try to manage it including NSExceptionDomains entries.

I am trying to configure muy my info.plist but it´s not working.


My configuration is the next, but with this configuration my app is not calling to my delegate class.


<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>boe.es</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>


This configuration is not correct?

Can you post an example URL that loads with ATS fully disabled but fails with this exception?

Share and Enjoy

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

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

Thanks!

That server does not meet ATS’s forward secrecy requirement:

% TLSTool s_client -connect www.boe.es:443
*  input stream did open
* output stream did open
* output stream has space
* protocol: TLS 1.2
* cipher: RSA_WITH_AES_256_GCM_SHA384
* trust result: unspecified
* certificate info:
*   0 + rsaEncryption 2048 sha256-with-rsa-signature 'www.boe.es'
*   1 + rsaEncryption 2048 sha256-with-rsa-signature 'TERENA SSL High Assurance CA 3'
*   2 + rsaEncryption 2048 sha1-with-rsa-signature 'DigiCert High Assurance EV Root CA'
^C

Note the cypher suite is

RSA_WITH_AES_256_GCM_SHA384
, whereas ATS requires forward secrecy via an ECDHE cypher suite. See the discussion of
NSExceptionRequiresForwardSecrecy
in the
NSExceptionDomains
documentation, and the background info in Preventing Insecure Network Connections.

Consider this code snippet:

NSLog("task will start")
let url = URL(string: "https://www.boe.es")!
let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60.0)
URLSession.shared.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()

By default, it fails with a -1200 error. I can get it working by adding the following ATS configuration:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>www.boe.es</key>
        <dict>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>

Share and Enjoy

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

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

Thanks eskimo. I will check it.

Thanks for your help. I try to configurate another url that I received error and it´s not working. I launch the comand: openssl s_client -connect sedeaplicaciones.minetur.***.es:443 And the result is:


CONNECTED(00000005)
depth=1 C = ES, O = Firmaprofesional S.A., OU = Security Services, serialNumber = A62634068, CN = AC Firmaprofesional - INFRAESTRUCTURA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=ES/ST=MADRID/L=MADRID/O=MINISTERIO DE INDUSTRIA, COMERCIO Y TURISMO/2.5.4.97=VATES-S2800214E/serialNumber=S2800214E/CN=sedeaplicaciones.minetur.***.es
   i:/C=ES/O=Firmaprofesional S.A./OU=Security Services/serialNumber=A62634068/CN=AC Firmaprofesional - INFRAESTRUCTURA
 1 s:/C=ES/O=Firmaprofesional S.A./OU=Security Services/serialNumber=A62634068/CN=AC Firmaprofesional - INFRAESTRUCTURA
   i:/C=ES/CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIHjDCCBnSgAwIBAgIQdXENNAz41BIO5EtfbMLR/DANBgkqhkiG9w0BAQsFADCB
jTELMAkGA1UEBhMCRVMxHjAcBgNVBAoMFUZpcm1hcHJvZmVzaW9uYWwgUy5BLjEa
MBgGA1UECwwRU2VjdXJpdHkgU2VydmljZXMxEjAQBgNVBAUTCUE2MjYzNDA2ODEu
MCwGA1UEAwwlQUMgRmlybWFwcm9mZXNpb25hbCAtIElORlJBRVNUUlVDVFVSQTAe
Fw0yMDAxMTYxMjUzMjlaFw0yMjAxMTUxMjUzMjlaMIG9MQswCQYDVQQGEwJFUzEP
MA0GA1UECBMGTUFEUklEMQ8wDQYDVQQHEwZNQURSSUQxNDAyBgNVBAoTK01JTklT
VEVSSU8gREUgSU5EVVNUUklBLCBDT01FUkNJTyBZIFRVUklTTU8xGDAWBgNVBGET
D1ZBVEVTLVMyODAwMjE0RTESMBAGA1UEBRMJUzI4MDAyMTRFMSgwJgYDVQQDEx9z
ZWRlYXBsaWNhY2lvbmVzLm1pbmV0dXIuZ29iLmVzMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAnxTcJVOEOsPuEEx8Dkp/UtH6BfwpXc6mFp6p/tyLqo4x
TtgVFlQhVKQ6ofdFaShJIpnCG08b67LV+PhbxgxW9JU8MdT5SgDaYnvZZoXJJ63o
RWpbX+tJxIs3WWt+aqChC/1yfH1/i7nF1kO2vbTLsqCEb6+GQcFscjaKqmFH0D6I
6elBCan+K3RHmfe/46+JFIDe3uz+GvWJswnO8v6akgHqKey4sk8DRKCtSx+SrYTL
+m2mQgVFirGWRxD+OF3la/PM+QJRqEUPtteqwuL2cnltpLQNx4/8u0wjrUhjhcnV
HLFd93frnzf9PJXuv8ZofbHlx4Q52zRMRgNZeHsS2QIDAQABo4IDtDCCA7AwDAYD
VR0TAQH/BAIwADAfBgNVHSMEGDAWgBRiFau1swh5pYf+gNki8I78jxH9eTB9Bggr
BgEFBQcBAQRxMG8wPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcmwuZmlybWFwcm9mZXNp
b25hbC5jb20vaW5mcmFlc3RydWN0dXJhLmNydDAsBggrBgEFBQcwAYYgaHR0cDov
L29jc3AuZmlybWFwcm9mZXNpb25hbC5jb20wKgYDVR0RBCMwIYIfc2VkZWFwbGlj
YWNpb25lcy5taW5ldHVyLmdvYi5lczCBgQYDVR0gBHoweDB2BgsrBgEEAeZ5CgED
ATBnMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZpcm1hcHJvZmVzaW9uYWwuY29t
L2NwczA0BggrBgEFBQcCAjAoDCZFc3RlIGVzIHVuIENlcnRpZmljYWRvIGRlIFNl
cnZpZG9yIFdlYjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwgYAGA1Ud
HwR5MHcwOaA3oDWGM2h0dHA6Ly9jcmwuZmlybWFwcm9mZXNpb25hbC5jb20vaW5m
cmFlc3RydWN0dXJhLmNybDA6oDigNoY0aHR0cDovL2NybDIuZmlybWFwcm9mZXNp
b25hbC5jb20vaW5mcmFlc3RydWN0dXJhLmNybDAdBgNVHQ4EFgQU/LW6Qyk5AxRE
Z02zTK6PK+Y+TcgwDgYDVR0PAQH/BAQDAgSwMIIBfQYKKwYBBAHWeQIEAgSCAW0E
ggFpAWcAdQBvU3asMfAxGdiZAKRRFf93FRwR2QLBACkGjbIImjfZEwAAAW+uankn
AAAEAwBGMEQCIEvExrNEaaNVcT0X2cJq5Q9TxqqiVOzKrx3a0NVItAfzAiAh6iSh
+5wzuMFblPwigb/S3hkhhPJL9f05UdSTuLFuYQB2AFWB1MIWkDYBSuoLm1c8U/DA
5Dh4cCUIFy+jqh0HE9MMAAABb65qekoAAAQDAEcwRQIgFv+U2oJ6MfgNJLGN9CSp
SohhCk9hoIHs8bFaVHC6KcwCIQDAPZwWewlFTD5KmKHM2908XwA197WpmLXM2/0D
Ldh+5AB2AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAABb65qe94A
AAQDAEcwRQIhAIARZp6spL+mrQyFWAT1plY6GuMlXmjt0PkBV/uk374VAiBZjfFa
vYtxJ8JlxMKO6YZ0cbTFZlrv/fdJBZ1MQAYQJzANBgkqhkiG9w0BAQsFAAOCAQEA
jzYle73OJmYIs/KhgaAsmqfxrnmxWDOiA4zdwfMmon8X9nWA/6bmGNLYhUYt9zFe
jSXNNwP1VOBljZaQn7kNfi7+JbnYib4Ao01ejuadCG17BIG/QkVoGXizMBjrAet3
tHag7G3fHQ/uYzUNADnNh3E/BbQt/4HGoDcUXqsgze+rYUG9WcIEIjz6fOr+rXW1
1lq0DwwI248LCGGeL6rMFD1kXrZJktgCfB8iUQ8VQXoERPiL83lPAO8HNPg0qg3h
vX/+llh00RTijLyzkUmpKupgbjNaTmYReKa9EsgWmje2ZZCCwm4Uj07RMJLrKLSJ
sBSPAnx9RMVe4mU6I9nNSg==
-----END CERTIFICATE-----
subject=/C=ES/ST=MADRID/L=MADRID/O=MINISTERIO DE INDUSTRIA, COMERCIO Y TURISMO/2.5.4.97=VATES-S2800214E/serialNumber=S2800214E/CN=sedeaplicaciones.minetur.***.es
issuer=/C=ES/O=Firmaprofesional S.A./OU=Security Services/serialNumber=A62634068/CN=AC Firmaprofesional - INFRAESTRUCTURA
---
No client certificate CA names sent
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3858 bytes and written 334 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : ECDHE-RSA-AES256-SHA
    Session-ID: 843100002732FA3A6A6512B3A716B16ABDDA72355069FC1D549F83B29D3B8A02
    Session-ID-ctx: 
    Master-Key: E7379A467496E2FD38D62BE51313C09CDBD923EBE9E52BBF1223AE7AA75212E68A687FAB453AB64280B36A5DDC8B90AB
    Start Time: 1580318913
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---


I think that is not the same error because this certificate suports ECDHE, but I still receiving the 1200 error. More specficly:


Optional(Error Domain=NSURLErrorDomain Code=-1200 "Se ha producido un error de SSL y no puede establecerse una conexión segura con el servidor."


UserInfo={NSLocalizedDescription=Se ha producido un error de SSL y no puede establecerse una conexión segura con el servidor., 


NSLocalizedRecoverySuggestion=¿Quieres conectarte al servidor de todos modos?, _kCFStreamErrorCodeKey=-9801, NSErrorFailingURLStringKey=


https://sedeaplicaciones.minetur.***.es/ReclamacionesTELCO_Nueva/FrmSolicitud.aspx, _kCFStreamErrorDomainKey=3, NSUnderlyingError=0x17d22b00 


{Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFNetworkCFStreamSSLErrorOriginalValue=-9801, _kCFStreamErrorCodeKey=-9801,


 _kCFStreamErrorDomainKey=3, _kCFStreamPropertySSLClientCertificateState=0}}, 


NSErrorFailingURLKey=https://sedeaplicaciones.minetur.***.es/ReclamacionesTELCO_Nueva/FrmSolicitud.aspx})

This server’s problem is that it doesn’t support TLS 1.2:

% TLSTool s_client -connect sedeaplicaciones.minetur.***.es:443
*  input stream did open
* output stream did open
* output stream has space
* protocol: TLS 1.0                         <<< NOTE THIS
* cipher: ECDHE_RSA_WITH_AES_256_CBC_SHA
* trust result: unspecified
* certificate info:
*   0 + rsaEncryption 2048 sha256-with-rsa-signature 'sedeaplicaciones.minetur.***.es'
*   1 + rsaEncryption 2048 sha256-with-rsa-signature 'AC Firmaprofesional - INFRAESTRUCTURA'
*   2 + rsaEncryption 4096 sha1-with-rsa-signature 'Autoridad de Certificacion Firmaprofesional CIF A62634068'
^C

Again, ATS has an exception to allow for this, namely

NSExceptionMinimumTLSVersion
.

btw If you want a copy of

TLSTool
, it’s sample code that you can download from here.

Share and Enjoy

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

let myEmail = "eskimo" + "1" + "@apple.com"
NSURLErrorDomain Code=-1200
 
 
Q