zwopple / PocketSocket

Objective-C websocket library for building things that work in realtime on iOS and OS X.
Other
414 stars 129 forks source link

WS Secure server: CFNetwork SSLHandshake failed (-9806) #60

Open micamo2k17 opened 7 years ago

micamo2k17 commented 7 years ago

Hi,

I'm having problems configuring a secure websocket server with PocketSocket. The situation is the following: my app creates a websocket server listening on localhost, using a self-signed certificate I made with localhost as CN. The server is created without problems. Another part of my app tries to connect to this websocket server from a webview. Unfortunately, when this happens, the error "CFNetwork SSLHandshake failed (-9806)" gets printed on the console, and the websocket isn't opened. If the websocket is created without a certificate, an un-secure connection can be correctly created, but this isn't enough for my use case. I tried adding the following parameter: opts[(__bridge id)kCFStreamSSLLevel] = (__bridge id _Nullable)(kCFStreamSocketSecurityLevelSSLv2); inside the - (void)accept:(CFSocketNativeHandle)handle method of PSWebSocketServer class, but this seems ineffective. Also tried to disable App Transport Security in my app, and to allow exceptions such as NSTemporaryExceptionMinimumTLSVersion to it for the domains interested in this process (localhost, and the one the page in the webview is loaded from), with no success. Do you have and idea about why the SSL handshake with the websocket server may fail?

Thanks!

kisileno commented 7 years ago

@micamo2k17 how did you manage to add your self-signed certificate authority to the system's keychain?

micamo2k17 commented 7 years ago

Hi @kisileno ,

I didn't add my certificate to the keychain, i did the following (sorry for the poor-to-inexistent error-handling):

let certData = NSData(contentsOfFile: certificatePath!) //certificatePath is the path of my P12 self-signed cert
let passDictionary:NSMutableDictionary = NSMutableDictionary()
passDictionary.setValue("password", forKey: kSecImportExportPassphrase as String)
var items: CFArray?
let error = SecPKCS12Import(certData!, passDictionary, &items)
let unwrappedItems = items! as [AnyObject]
let certDict = unwrappedItems[0] as! [String:AnyObject]
var certs = [certDict["identity"]!]
for c in certDict["chain"]! as! [AnyObject]
{
    certs.append(c as! SecCertificate)
}
self.server = PSWebSocketServer(host: nil, port: 8091, sslCertificates: certs)

Probably something wrong with it...?

Thanks

passuf commented 7 years ago

I did something very similar and received the same error when trying to connect from Chrome to the WebSocket server on my iPhone. It turned out that Chrome was aborting the TLS handshake, since it was a self-signed certificate (the CN matched the IP of my iPhone though).

To test this, I tried to access the WebSocket via https://... and then accepted the certificate warning, after that the WebSocket connection worked like a charm. On Firefox this did not work.

I do not know if there is a solution to this, it looks like current browsers do not allow to handle untrusted WebSocket connections.

micamo2k17 commented 7 years ago

So from what I understand, this seems an issue related to the invalid certificate. However, could someone confirm my approach for loading the certificate?

Toon34 commented 6 years ago

Hello !

I have same issue only with the client ! My server working very fine with android ssl web socket client and PC browser. But with PSWebSocket, only web socket without ssl works for me... Any ideas ? Thanks

EDIT : I find the solution for my problem, I add evaluateServerTrust delegate and return true if it's my CA !