I have a python server in the cloud that accepts socket requests. I have a Swift (xCode) client application that uses NS(in/out)putstreams to communicate with the python server app.
I generated my own SSL cert and key files on the server.
With the SSL wrapping code commented out on my server side, I can get my client and server to talk just fine. With SSL I get handshake errors.
Both the server and client are using TLSV1 for security level protocol.
On the mac side I have my server cert file installed and allowed in my user keychain, but i'm thinking that the application does not look there for trusted certs.
Is there a way to specify a cert file, for the NSStream(s) to use, directly in the xCode application pragmatically. Or a way to install the cert on the app?
I know in python when you wrap a socket with SSL you can tell it it's a client and to use a specific cert file from a path. Is there a MacOS Swift equivalent?
Or am I going about this all wrong?
Below is my "Light Socket" Swift class. Supper simple but works when not using the SSL at both ends.
class SSLSocketLite {
// The input stream.
private var inStream: NSInputStream?
// The output stream.
private var outStream: NSOutputStream?
// The host to connect to.
private var host: String
// The port to connect on.
private var port: Int
init(inHost:String, inPort:Int) {
host = inHost
port = inPort
NSStream.getStreamsToHostWithName(host, port: port, inputStream: &inStream, outputStream: &outStream)
}
func Open() {
inStream?.open()
outStream?.open()
inStream?.setProperty(NSStreamSocketSecurityLevelTLSv1, forKey: NSStreamSocketSecurityLevelKey)
outStream?.setProperty(NSStreamSocketSecurityLevelTLSv1, forKey: NSStreamSocketSecurityLevelKey)
}
func Read() -> String! {
var buffer = Array<UInt8>(count:1024, repeatedValue: 0)
if inStream!.hasBytesAvailable {
inStream!.read(&buffer, maxLength: 1024)
let responseString = NSString(bytes: buffer, length: buffer.count, encoding: NSUTF8StringEncoding) as! String
return responseString
}
return nil
}
func Write(msg:String) {
let data:NSData = msg.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
outStream!.write(UnsafePointer(data.bytes), maxLength: data.length)
}
func Close() {
inStream?.close()
outStream?.close()
}
}
I gathered all of this from a bunch of other posts, but could not find any mention of where and when a cert file is actually used by the Swift calls to communicate out to the server.
If there is a key element to this that I am either missing or misunderstanding, please let me know! And thanks in advance!
I found my answer. I was missing these lines in my open method.
they are required to automate the handshake for SSL.
inStream?.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
outStream?.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
My other questions still could use answering though.
Thanks!