1 Reply
      Latest reply: Dec 16, 2016 3:01 AM by eskimo RSS
      roben Level 1 Level 1 (0 points)

        I'm using a self-signed certificate. But my host domain maybe different from the certificate or may be IP adresses.

        But I find that the code is not working when ATS is turned on.

        The weird thing is the domain verification will fail but the pure IP address will be ok.

          // Get remote certificate
          SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
          SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
          
          // Set SSL policies for domain name check
          NSMutableArray *policies = [NSMutableArray array];
          NSString *trustDomain = [NSString stringWithFormat:@"%@:%d",
                                   challenge.protectionSpace.host,
                                   challenge.protectionSpace.port];
          [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)trustDomain)];
          SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies);
        

        The error info is

        {

            NSErrorClientCertificateStateKey = 0;

           ....

            NSLocalizedDescription = "An SSL error has occurred and a secure connection to the server cannot be made.";

            NSLocalizedRecoverySuggestion = "Would you like to connect to the server anyway?";

            NSURLErrorFailingURLPeerTrustErrorKey = "<SecTrustRef: 0x14fd8a90>";

            NSUnderlyingError = "Error Domain=kCFErrorDomainCFNetwork Code=-1200 \"(null)\" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorCodeKey=-9802, _kCFStreamErrorDomainKey=3, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x14fd8a90>, kCFStreamPropertySSLPeerCertificates=(....)}";

            "_kCFStreamErrorCodeKey" = "-9802";

            "_kCFStreamErrorDomainKey" = 3;

        }

        • Re: SecTrustSetPolicies not work when ATS enabled
          eskimo Apple Staff Apple Staff (6,470 points)

          I'm using a self-signed certificate … But I find that the code is not working when ATS is turned on.

          The general rule for ATS is that apps are not able to lower security beyond that specified in their ATS dictionary (the NSAppTransportSecurity dictionary in the Info.plist).  So if “ATS is turned on” means what I think it means (you are building with a modern SDK, which enables ATS, and you don’t have an ATS dictionary that specifically disables ATS for your domain), this is working as expected:  ATS is preventing you from lowering security beyond what’s specified in your ATS dictionary, which is exactly what it’s supposed to be doing.

          To make this work you’ll need to add an ATS exception that covers your server.  If there are no constraints on the DNS name of your server, you’ll need to use NSAllowsArbitraryLoads.

          The weird thing is the domain verification will fail but the pure IP address will be ok.

          Right.  ATS is always disabled for IP address URLs.

          IMPORTANT  This is new in iOS 10.  In iOS 9 ATS is always enabled for IP address URLs and there’s no way (other than the heavy hammer than is NSAllowsArbitraryLoads) to disable it.


          Coming back to the big picture, why are you using a self-signed certificate?  Folks do this for lots of different reasons, but in most cases there’s a better approach.  If you can explain more about your high-level problem, I should be able to suggest an alternative.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"