Search code examples
iosswiftxcodensurlsessionunsafe-pointers

Cannot convert value of type 'SecCertificate' to expected argument type 'UnsafeMutablePointer<UnsafeRawPointer?>!'


I am trying to perform https request but when I try to match local and remote ssl certificates Xcode shown me above error. I have attached an image of error also code below, any help will be appreciated thanks in advance.

enter image description here

Below is the complete delegate method of URLSessionDelegate.

  func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    if challenge.protectionSpace.authenticationMethod == (NSURLAuthenticationMethodServerTrust) {


        let serverTrust:SecTrust = challenge.protectionSpace.serverTrust!
        let certificate: SecCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0)!
        let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))!
        let cerPath: String = Bundle.main.path(forResource: "xxxxx", ofType: "der")!
        let localCertificateData = NSData(contentsOfFile:cerPath)!
        print(localCertificateData.length)
        let result  = remoteCertificateData.isEqual(localCertificateData as Data)
        let certDataRef = localCertificateData as! CFData
        var cert: SecCertificate = SecCertificateCreateWithData(nil, certDataRef)!
        let certArrayRef = CFArrayCreate(nil, cert, 1, nil)
        SecTrustSetAnchorCertificates(serverTrust, certArrayRef)

        SecTrustSetAnchorCertificatesOnly(serverTrust, false)
        print(result)
        var trustResult: SecTrustResultType = SecTrustResultType.invalid
        SecTrustEvaluate(serverTrust, &trustResult)
        if (trustResult == SecTrustResultType.unspecified ||
            trustResult == SecTrustResultType.proceed)
        {
            let credential:URLCredential = URLCredential(trust: serverTrust)
            challenge.sender?.use(credential, for: challenge)
            completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))

        } else {

            completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
        }
    }
    else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate
    {
        let path: String = Bundle.main.path(forResource: "client", ofType: "p12")!
        let PKCS12Data = NSData(contentsOfFile:path)!
        let identityAndTrust:IdentityAndTrust = self.extractIdentity(certData: PKCS12Data);
        let urlCredential:URLCredential = URLCredential(
            identity: identityAndTrust.identityRef,
            certificates: identityAndTrust.certArray as? [AnyObject],
            persistence: URLCredential.Persistence.forSession);
        completionHandler(URLSession.AuthChallengeDisposition.useCredential, urlCredential);
    }
    else
    {
        completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil);
    }
}

Solution

  • The line causing the error, is for creating a CFArray.

    One simple way to create a CFArray, is to use bridging the Swift Array to CFArray.

    Try changing the line:

    let certArrayRef = CFArrayCreate(nil, cert, 1, nil)
    

    To:

    let certArrayRef = [cert] as CFArray