I am trying to install a simple socket (NO HTTP) from my iOS application to my server server (Node.js). The server certificate was created and signed using a custom certificate authority that I made myself. I believe that in order for iOS to trust my server, I will have to somehow add this user CA certificate to the list of trusted certificates that are used to determine the type of trust how TrustStore works in Java / Android.
I tried to connect using the code below and there are no errors, however the write () function does not seem to be successful.
Main view controller:
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let api: APIClient = APIClient() api.initialiseSSL("10.13.37.200", port: 8080) api.write("Hello") api.deinitialise() print("Done") }
Class apiclient
class APIClient: NSObject, NSStreamDelegate { var readStream: Unmanaged<CFReadStreamRef>? var writeStream: Unmanaged<CFWriteStreamRef>? var inputStream: NSInputStream? var outputStream: NSOutputStream? func initialiseSSL(host: String, port: UInt32) { CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host, port, &readStream, &writeStream) inputStream = readStream!.takeRetainedValue() outputStream = writeStream!.takeRetainedValue() inputStream?.delegate = self outputStream?.delegate = self inputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) outputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) let cert: SecCertificateRef? = CreateCertificateFromFile("ca", ext: "der") if cert != nil { print("GOT CERTIFICATE") } let certs: NSArray = NSArray(objects: cert!) let sslSettings = [ NSString(format: kCFStreamSSLLevel): kCFStreamSocketSecurityLevelNegotiatedSSL, NSString(format: kCFStreamSSLValidatesCertificateChain): kCFBooleanFalse, NSString(format: kCFStreamSSLPeerName): kCFNull, NSString(format: kCFStreamSSLCertificates): certs, NSString(format: kCFStreamSSLIsServer): kCFBooleanFalse ] CFReadStreamSetProperty(inputStream, kCFStreamPropertySSLSettings, sslSettings) CFWriteStreamSetProperty(outputStream, kCFStreamPropertySSLSettings, sslSettings) inputStream!.open() outputStream!.open() } func write(text: String) { let data = [UInt8](text.utf8) outputStream?.write(data, maxLength: data.count) } func CreateCertificateFromFile(filename: String, ext: String) -> SecCertificateRef? { var cert: SecCertificateRef! if let path = NSBundle.mainBundle().pathForResource(filename, ofType: ext) { let data = NSData(contentsOfFile: path)! cert = SecCertificateCreateWithData(kCFAllocatorDefault, data)! } else { } return cert } func deinitialise() { inputStream?.close() outputStream?.close() }
}
I understand how SSL / TLS works and thatβs all, since I did all this in the Android version of the same application. I am just confused about implementing iOS for SSL.
I am in the background of Java and have been dealing with this problem for 3 weeks. Any help would be appreciated.
Prefer the answers in Swift code rather than Objective-C, but if you have Obj C, that's fine too :)