Я устанавливаю VPN-соединение, для аутентификации которого требуется сертификат.
В приведенном ниже коде показано, как я устанавливаю конфигурацию, которая требуется для VPN. Параметр identityData - это то место, где я помещаю свой сертификат как Data.
func setupVPN(){
guard let vpnManager = NEVPNManager.shared() else { return }
vpnManager.loadFromPreferences { error in
var hasProtocolConfig = false;
if #available(iOS 9, *) {
hasProtocolConfig = self.vpnManager.protocolConfiguration != nil
} else {
hasProtocolConfig = self.vpnManager.`protocol` != nil
}
if hasProtocolConfig == true {
let p = NEVPNProtocolIKEv2()
// All preferences here
if let vpnData = self.vpnData {
p.serverAddress = vpnData.getePDGAddress() // "X.X.X.X"
p.localIdentifier = vpnData.getlocalIdentifier() // "[email protected]"
p.remoteIdentifier = vpnData.getAPN() // "gggggg.uuuuuuuuuuu"
p.identityData = vpnData.getUserCertificateData() // User Certificate as Data
}
p.ikeSecurityAssociationParameters.integrityAlgorithm = NEVPNIKEv2IntegrityAlgorithm.SHA256
p.ikeSecurityAssociationParameters.encryptionAlgorithm = NEVPNIKEv2EncryptionAlgorithm.algorithmAES128
p.ikeSecurityAssociationParameters.diffieHellmanGroup = NEVPNIKEv2DiffieHellmanGroup.group14
p.serverCertificateIssuerCommonName = "TEST SubCA"
p.serverCertificateCommonName = "TEST SubCA"
p.authenticationMethod = NEVPNIKEAuthenticationMethod.certificate
if #available(iOS 9, *) {
self.vpnManager.protocolConfiguration = p
} else {
self.vpnManager.`protocol` = p
}
self.vpnManager.isEnabled = true
self.vpnManager.saveToPreferences { error in
if let e = error{
print("[VPN] error saving: " + e.localizedDescription)
} else {
print("[VPN] vpn saved")
Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.connectVPN), userInfo: nil, repeats: false)
}
return
}
}
}
}
Один из примеров этого сертификата, закодированного в базе 64:
MIIFqTCCA5GgAwIBAgIQKLf5dlFRabt3cAe9ax2kXjANBgkqhkiG9w0BAQsFADBgMRwwGgYDVQQDDBNURVNUIFZGQ1ogRVBDIFN1Yk ... wdWJsaWMgYS5zLjELMAkGA1UEBhMCQ1owggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNgTmc6uQ9Md
И затем синтаксический анализ данных выполняется следующим образом:
CaCertificateData = Data(base64Encoded: "Base64StringEncoded_Here")
Когда все настроено, я запускаю VPN-туннель следующим образом:
do {
try vpnManager.connection.startVPNTunnel()
} catch let error {
print("Error starting VPN Connection \(error.localizedDescription)");
}
Я вижу статус VPN, и VPN начинает подключение, а затем становится отключенным. 3 алгоритма, которые мы видим выше, верны.
Кто-то может заметить, что я делаю не так? У меня есть файлы .pcap из нескольких проведенных мною тестов. Во всех файлах .pcap я не отправляю обязательное сообщение «Client Hello». Думаю, проблема в сертификате.