1 Reply
      Latest reply: Nov 21, 2016 2:17 AM by eskimo RSS
      JuDevice Level 1 Level 1 (0 points)

        Hi,

        I have a custom CA on my device ( Server ). My iOS App gets the data from my device over https( with URLSession ). I've implememented this like in TN2232 described. My Code:

         

        //Code start

        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust{

        //TN2232: Custom certificate authority          

        //Step 1

                   let pathToCert = Bundle.main.path(forResource: "TrialRootCerSymantec", ofType: "der")

                    var localCertificate: NSData? = nil

                    do{

                        localCertificate = try NSData(contentsOfFile: pathToCert!)

                    }

         

        //Step 2 and 3

                    let serverTrust = challenge.protectionSpace.serverTrust

                    let certificateServer = SecTrustGetCertificateAtIndex(serverTrust!, 0)

                    let cfData = CFDataCreate(kCFAllocatorDefault, localCertificate?.bytes.assumingMemoryBound(to: UInt8.self), (localCertificate?.length)!)

                    let anchorCert = SecCertificateCreateWithData(kCFAllocatorDefault, cfData!)

                    let certs:[CFTypeRef] = [anchorCert as CFTypeRef]

                    let certArrayRef: CFArray = CFBridgingRetain(certs as NSArray) as! CFArray

                    if(errSecSuccess == SecTrustSetAnchorCertificates(serverTrust!, certArrayRef)){

                        print("Status: \(errSecSuccess)")

                    }else{

                        print("Status: Error")

                    }

                 

        //Step 4

                    var result: SecTrustResultType = SecTrustResultType.invalid

                    let returnState: OSStatus = SecTrustEvaluate(serverTrust!, &result)

                    let isServerTrusted: Bool = (result == SecTrustResultType.unspecified || result == SecTrustResultType.proceed)

        }

        //Code end

         

        The function SecTrustEvaluate returns -108...(returnState = -108 and result = 0).

        What does mean error -108?

        How can I fix this error?

        Thanks!

        • Re: Evaluate server cert returns error -108
          eskimo Apple Staff Apple Staff (6,310 points)

          You can get more context on security errors using the security tool.  For example:

          $ security error -108
          Error: 0xFFFFFF94 -108 Failed to allocate memory.
          

          This error has a lot of history.  It originated as memFullErr on the first ever Mac.  macOS’s Security framework inherited it from there, and iOS’s Security framework from the Mac.  When dealing with Security framework APIs, it’s best to use the Security framework alias, errSecAllocate.


          As to what’s triggering this error, that’s hard to say.  If you post a hex dump of your two certificates (the leaf certificate from the server and TrialRootCerSymantec), I’ll see if I can spot anything obvious.

          btw Your Swift code is working way too hard.  Here’s how I’d write this code:

          func evaluate(challenge: URLAuthenticationChallenge) -> Bool {
              let urlToCert = Bundle.main.url(forResource: "root", withExtension: "cer")!
              let localCertificate = try! Data(contentsOf: urlToCert)
          
              //Step 2 and 3
              let serverTrust = challenge.protectionSpace.serverTrust!
              let anchorCert = SecCertificateCreateWithData(kCFAllocatorDefault, localCertificate as NSData)!
              guard SecTrustSetAnchorCertificates(serverTrust, [anchorCert] as NSArray) == errSecSuccess else {
                  return false
              }
          
              //Step 4
              var result = SecTrustResultType.invalid
              guard SecTrustEvaluate(serverTrust, &result) == errSecSuccess else {
                  return false
              }
              return [.unspecified, .proceed].contains(result)
          }
          

          Notes:

          • The code is careful about only handling errors that might happen.  For example, root.cer is bundled with my app, so there’s no point handling the case where it’s missing or isn’t parsed as a certificate.  OTOH, SecTrustEvaluate can return an error (as you’ve noted), so we fail secure in that case.

          • Data can be converted to NSData using as NSData, and Swift then converts to CFData from there.  Likewise for [SecCertificate].

          Share and Enjoy

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