Я чувствую ваше разочарование, я не работал с Swish API как таковым, но похоже, что URLSession не может выполнить запрос сертификата клиента.На этом этапе происходит сбой рукопожатия.
Существует возможность добавить URLSessionDelegate в URLSession для обработки проблем аутентификации, таких как ServerTrust и ClientCertificate.Они обсуждают это здесь: Swift 3 UrlSession с аутентификацией клиента по сертификату
Если вы можете создать p12 / pfx с сертификатом клиента и секретным ключом, вы можете использовать SecPKCS12Import дляимпортируйте его и используйте для доверия URLCredential в NSURLAuthenticationMethodClientCertificate, полученном в URLSessionDelegate.Вот реализация, которую я написал:
func urlSession(
_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
{
let authenticationMethod = challenge.protectionSpace.authenticationMethod
if authenticationMethod == NSURLAuthenticationMethodServerTrust {
//Handle server trust if necessary
} else if authenticationMethod == NSURLAuthenticationMethodClientCertificate {
if let clientCredential = try? getClientUrlCredential() {
completionHandler(.useCredential, clientCredential)
} else {
completionHandler(.cancelAuthenticationChallenge, nil)
}
}
}
getClientUrlCredential function:
private func getClientUrlCredential() throws -> URLCredential {
let p12Data = getP12Data() //Get the data from the bundle if it's bundled in the app
let p12Key = getP12Key() //you need the key set for creating the p12/pfx
let certOptions: NSDictionary = [
kSecImportExportPassphrase as NSString : p12Key as NSString
]
// import certificate to read its entries
var items: CFArray?
let status = SecPKCS12Import(p12Data, certOptions, &items)
if status == errSecSuccess,
let items = items,
let dict = (items as Array).first as? [String: AnyObject],
let certChain = dict[kSecImportItemCertChain as String] as? [SecTrust] {
// Check if SecIdentityGetTypeID is present
guard let cfIdentity = dict[kSecImportItemIdentity as String] as CFTypeRef?,
CFGetTypeID(cfIdentity) == SecIdentityGetTypeID() else {
throw URLSessionPinningDelegateError.localClientCertificateError
}
let identity = dict[kSecImportItemIdentity as String] as! SecIdentity
return URLCredential(
identity: identity,
certificates: certChain,
persistence: .forSession
)
}
//Failed to read local certificate, throw error
throw URLSessionPinningDelegateError.localClientCertificateError
}
Имея действительный клиентский сертификат, вы должны иметь возможность выполнить привет клиента и настроить TLS на сервере, посколькуКажется, сейчас вы терпите неудачу.Предупреждение SSL по номеру 40, которое вы получаете от BoringSSL, подсказывает мне, по крайней мере.
Надеюсь, что это, по крайней мере, направит вас в правильном направлении, и будет рад поддержать вас в случае необходимости.