How do I add a self-signed root CA to a device?
How do I install a root CA on a device?
The certificate is only needed for my application and can be sandboxed if possible.
This works when I have dragged the certificate onto the simulator and installed it , but without using the following code:
let rootCertPath = NSBundle.mainBundle().pathForResource("server", ofType: "der")!
let rootCertData = NSData(contentsOfFile: rootCertPath)!
let rootCert = SecCertificateCreateWithData(kCFAllocatorDefault, rootCertData).takeRetainedValue()
let error = SecItemAdd(
[
NSString(format: kSecClass): NSString(format: kSecClassCertificate),
NSString(format: kSecValueRef): rootCert
], nil)
SecItemAdd
returns without error and seems to install to the device correctly, but still cannot connect to the server with the error:
NSURLConnection / CFURLConnection HTTP Load Error (kCFStreamErrorDomainSSL, -9813)
Code for connecting to the server:
let request = NSURLRequest(URL: NSURL(string: "https://" + server + ":" + port)!)
let session = NSURLSession(configuration: .defaultSessionConfiguration())
session.dataTaskWithRequest(request, completionHandler:
{(data, response, error) in
println(error)
}).resume()
error
prints the following:
Domain Error = NSURLErrorDomain Code = -1202 "The certificate for this server is not valid.
But then again, if I manually install the same certificate in the simulator profiles, it just works fine.
source to share
It is not secure and does not require a certificate
Managed to get this work done using sockets (NSStream and CFStream).
It's important to note that I need to disable kCFStreamSSLValidatesCertificateChain
for my certificate to work.
class Authentication: NSObject, NSStreamDelegate
{
private var inputStream: NSInputStream?
private var outputStream: NSOutputStream?
func connectToServer(server: String, port: Int)
{
let sslSettings =
[
NSString(format: kCFStreamSSLValidatesCertificateChain): kCFBooleanFalse
]
NSStream.getStreamsToHostWithName(server, port: port, inputStream: &inputStream, outputStream: &outputStream)
CFReadStreamSetProperty(inputStream, kCFStreamPropertySocketSecurityLevel, kCFStreamSocketSecurityLevelTLSv1)
CFReadStreamSetProperty(inputStream, kCFStreamPropertySSLSettings, sslSettings)
inputStream!.delegate = self
outputStream!.delegate = self
inputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
outputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
inputStream!.open()
outputStream!.open()
}
}
Useful links:
iOS: pre-install SSL certificate in keychain - programmatically
Correctly override TLS validation
Connecting to an iOS SSL socket
source to share