Evaluate server cert returns error -108

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!

Accepted Reply

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"

Replies

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"