【问题标题】:How to get an identity for NEPacketTunnelProvider Networkextension from keychain?如何从钥匙串中获取 NEPacketTunnelProvider Networkextension 的身份?
【发布时间】:2019-01-04 09:05:15
【问题描述】:

我正在使用 NEPacketTunnelProvider 进行网络扩展。我正在使用带有 com.apple.vpn.managed 有效负载的配置文件。此外,我使用带有 com.apple.security.pkcs12 有效负载的 ClientCertificate 身份验证。根据NETunnelProviderManager 文档,我的扩展程序应该可以使用 com.apple.managed.vpn.shared 钥匙串访问组检索此身份。

如果我查询钥匙串的身份,我总是得到错误代码-25300。根据www.osstatus.com,这意味着:“找不到该项目。”

代码 1: 我尝试使用 protocolConfiguration 提供的持久引用来检索身份。

class PacketTunnelProvider: NEPacketTunnelProvider {

    override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {

        NSLog("vpn-service startTunnel")

        let pc = self.protocolConfiguration
        NSLog("vpn-service protocolConfiguration " + pc.debugDescription)
        if let identity = pc.identityReference {
            let persistentRef = identity as NSData
            NSLog("vpn-service persistentRef "  + persistentRef.description)
            var copyResult: AnyObject?
            let copyErr = SecItemCopyMatching([
                kSecValuePersistentRef as String: persistentRef,
                kSecReturnData as String: true
                ] as CFDictionary, &copyResult)
            NSLog("vpn-service getCert copyErr "  + copyErr.description)
        }
    }
}

输出是:

Jul 27 10:07:53 Tims-iPhone vpn(libswiftFoundation.dylib)[4994] <Notice>: vpn-service startTunnel
Jul 27 10:07:53 Tims-iPhone vpn(libswiftFoundation.dylib)[4994] <Notice>: vpn-service protocolConfiguration
    type = plugin
    identifier = 3B39941E-AF39-45CE-B869-68AF392FBCA0
    serverAddress = DEFAULT
    password = {
        domain = user
        accessGroup = com.apple.managed.vpn.shared
    }
    identity = {
        identifier = <Subject Name Common Name of the identity installed by the com.apple.security.pkcs12 payload>
        persistentReference = <69646e74 00000000 00000011>
        domain = user
    }
    identityDataImported = NO
    identityReference = <69646e74 00000000 00000011>
    proxySettings = {
        autoProxyDiscovery = NO
        autoProxyConfigurationEnabled = NO
        HTTPEnabled = NO
        HTTPSEnabled = NO
        FTPEnabled = NO
        SOCKSEnabled = NO
        RTSPEnabled = NO
        gopherEnabled = NO
        excludeSimpleHostnames = NO
                usePassiveFTP = YES
    }
    disconnectOnSleep = NO
    disconnectOnIdle = NO
    disconnectOnIdleTimeout = 0
    disconnectOnWake = NO
    disconnectOnWakeTimeout = 0
    pluginType = <my-bundle-id>
    authenticationMethod = 1
Jul 27 10:07:53 Tims-iPhone vpn(libswiftFoundation.dylib)[4994] <Notice>: vpn-service persistentRef <69646e74 00000000 00000011>
Jul 27 10:07:53 Tims-iPhone vpn(libswiftFoundation.dylib)[4994] <Notice>: vpn-service getCert copyErr -25300

代码 2: 如果我尝试在没有引用的情况下检索所有身份,我也会得到 -25300

let getQuery: [String: Any] = [
    kSecClass as String: kSecClassIdentity,
    kSecMatchLimit as String: kSecMatchLimitAll,
    kSecReturnAttributes as String: true,
]

var item: CFTypeRef?
let status = SecItemCopyMatching(getQuery as CFDictionary, &item)
NSLog("vpn-service status: " + status.description)

我重新检查了构建结果得到了钥匙串访问组:

codesign -d --ent :- build/Debug-iphoneos/agent.app/PlugIns/vpn.appex/

Executable=/Users/timb/projects/xcode/ios-client/build/Debug-iphoneos/agent.app/PlugIns/vpn.appex/vpn
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>application-identifier</key>
    <string><my-application-identifier-of-the-network-extension></string>
    <key>com.apple.developer.networking.networkextension</key>
    <array/>
    <key>com.apple.developer.team-identifier</key>
    <string><my-team-identifier></string>
    <key>get-task-allow</key>
    <true/>
    <key>keychain-access-groups</key>
    <array>
        <string><my-team-identifier>.com.apple.managed.vpn.shared</string>
    </array>
</dict>
</plist>

如何从钥匙串中获取 NEPacketTunnelProvider Networkextension 的身份?

【问题讨论】:

  • 嗨...找到原因了吗?
  • 很遗憾,还没有
  • 这适用于passwordNEProxyServer 的情况吗?您是否尝试为代理服务器(NEProxyServer)设置密码?
  • 嘿,不,我没试过。如果您需要访问 com.apple.managed.vpn.shared 钥匙串组,这是必要的。您是如何将密码添加到配置文件中的?

标签: ios swift keychain networkextension


【解决方案1】:

我会回答自己,因为我解决了问题:

1:您需要特殊权限才能访问 com.apple.managed.vpn.shared 组。创建一个 TSI 来获取它。这将需要大约一个月的时间。 https://forums.developer.apple.com/thread/67613#9

2:确保您的容器应用和网络扩展已设置权利。您可以通过codesign -d --entitlements :- &lt;filename&gt;查看

应该是这样的:

<key>keychain-access-groups</key>
<array>
    <string>com.apple.managed.vpn.shared</string>
</array>

我正在使用 XCode 10 Beta,当您使用 GUI 时出现问题。它将值设置为&lt;string&gt;$(AppIdentifierPrefix)com.apple.managed.vpn.shared&lt;/string&gt; 你必须用文本编辑器修复它。

3:从钥匙串访问数据。我将发布一些示例代码以将数据用作 base64 编码字符串。

guard let identityReference = protocolConfiguration.identityReference else {
    throw ConfigError.errorIdentityNotFound
}
let query: [String : Any] = [
    kSecValuePersistentRef as String: identityReference as CFData,
    kSecReturnRef as String: true,
]

var copyResult: AnyObject?
SecItemCopyMatching(query as CFDictionary, &copyResult)

guard let existingCopyResult = copyResult else {
    throw ConfigError.errorIdentityNotFound
}
let identity = existingCopyResult as! SecIdentity

var certificate: SecCertificate!
SecIdentityCopyCertificate(identity, &certificate)

let DERCertificate = SecCertificateCopyData(certificate) as NSData
let DERCertificateStringBase64Encoded = DERCertificate.base64EncodedString(options: NSData.Base64EncodingOptions.lineLength64Characters)

let PEMCertificateString = "-----BEGIN CERTIFICATE-----\n\(DERCertificateStringBase64Encoded)\n-----END CERTIFICATE-----" 

var privateKey: SecKey!
SecIdentityCopyPrivateKey(identity, &privateKey)
let privateKeyData = SecKeyCopyExternalRepresentation(privateKey, nil) as! NSData
let privateKeyDataBase64Encoded = privateKeyData.base64EncodedString(options: NSData.Base64EncodingOptions.lineLength64Characters)
let privateKeyPKCS1String = "-----BEGIN RSA PRIVATE KEY-----\n\(privateKeyDataBase64Encoded)\n-----END RSA PRIVATE KEY-----"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-04
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多