0

My iOS app communicates with my backend server which has a valid certificate. During development my iOS app is configured to communicate with my internal test server which has a certificate signed by my self signed root certificate.

Prior to iOS 11 I could configure my app to trust connections signed by my self signed root using instructions laid out here: https://developer.apple.com/library/content/technotes/tn2232/_index.html#//apple_ref/doc/uid/DTS40012884-CH1-SECCUSTOMCERT

However in iOS 11 it is no longer possible for an app to bypass ATS without creating an ATS exception int the info.plist. This thread includes some explanation from Apple: https://forums.developer.apple.com/thread/89694

So now in iOS how can I install my custom CA root on all my iOS simulators in some kind of automated way?

4

1 回答 1

3

由于 iOS 11 支持多应用 UI 测试,我创建了一个 UI 测试,它使 iOS 系统使用 Safari 和设置应用程序安装我的自定义 CA 的根。UI测试的源码如下:

import XCTest

class InstallRootCerts: XCTestCase {

    override func setUp() {
        super.setUp()
        continueAfterFailure = false
        XCUIApplication().launch()
    }

    override func tearDown() {
        super.tearDown()
    }

    func testInstallTestingRootCertOnDevice() {

        // Set test time env var ROOT_CA to point to your custom CA's .cer file.
        let cert = ProcessInfo.processInfo.environment["ROOT_CA"]
        // Set test time env var ROOT_CA_NAME to contain the name of your CA.
        let caName = ProcessInfo.processInfo.environment["ROOT_CA_NAME"]

        let safari = XCUIApplication(bundleIdentifier: "com.apple.mobilesafari")

        let settings = XCUIApplication(bundleIdentifier: "com.apple.Preferences")

        safari.activate()

        XCTAssertNotNil(cert)

        let certUrl = "file://\(cert!)"

        if safari.otherElements["URL"].exists {
            safari.otherElements["URL"].tap()
        }

        let addressBar = safari.textFields["URL"]

        addressBar.typeText(certUrl)

        safari.buttons["Go"].tap()

        safari.buttons["Allow"].tap()

        XCTAssertTrue( settings.wait(for: .runningForeground, timeout: 30) )

        if !settings.staticTexts["Verified"].exists {
            settings.buttons["Install"].tap()
            settings.buttons["Install"].tap()
            settings.sheets.buttons["Install"].tap()
        }

        // Now trust the root certificate
        settings.buttons["Cancel"].tap()
        XCTAssertTrue( safari.wait(for: .runningForeground, timeout: 120) )
        settings.activate()
        XCTAssertTrue( settings.wait(for: .runningForeground, timeout: 120) )

        settings.buttons["General"].tap()
        settings.cells["About"].tap()
        settings.cells["Certificate Trust Settings"].tap()
        let cell = settings.cells.containing(.staticText, identifier: caName)
        let toggle = cell.switches.firstMatch
        if toggle.value as? String != "1" {
            toggle.tap()
            settings.buttons["Continue"].tap()
        }

    }

}

此测试用例仅适用于运行 iOS 11.0 的模拟器。我认为如果您将 .cer 文件放在 Web 服务器上并通过 http 打开它,它可以与实际设备一起使用。

然后,这个测试用例可以在 Xcode 服务器上作为 Bot 运行,或者您可以在本地的任何模拟器上运行它来进行设置。这是我知道的一个黑客。

于 2017-10-25T19:45:00.197 回答