IOS SSL Connector

I am trying to establish a secure connection to the SSLServerSocket java server.

I created my own root CA and signed a certificate that uses SSLServerSocket Java using this certificate.

I want to add this root certificate to my application so that any certificate signed by the root certificate works.

So far, I’m sure that a secure connection works fine by setting the read and write properties for this:

NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys: (id)kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamPropertySocketSecurityLevel, [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates, [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots, [NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,nil]; 

I add the certificate to the keychain as follows:

 -(void)addRootCert{ NSString* rootCertPath = [[NSBundle mainBundle] pathForResource:@"rootCA" ofType:@"der"]; NSData* rootCertData = [NSData dataWithContentsOfFile:rootCertPath]; OSStatus err = noErr; SecCertificateRef rootCert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)rootCertData); NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge_transfer id)kSecClassCertificate, kSecClass, rootCert, kSecValueRef, nil]; err = SecItemAdd((__bridge CFDictionaryRef) dict, NULL); if (err == noErr) { NSLog(@"Sucessfully added root certificate"); }else if (err == errSecDuplicateItem){ NSLog(@"Root certificate already exists"); }else{ NSLog(@"Root certificate add failed"); } } 

This is fine, but I want to check the certificate chain so that my application accepts only certificates signed by my CA (or standard trusted)

How can i do this?

If I set kCFStreamSSLValidatesCertificateChain to yes, I get an error: CFNetwork SSLHandshake failed (-9807) , but if it isn’t, it doesn’t matter who signed the server certificate, it will connect independently (I assume that is correct?)

Thanks!

+8
ios ssl sockets certificate-authority root-certificate
source share
2 answers

Technote 2232 , β€œHTTPS Server Trust Assessment,” should have all the answers you need. There is documentation and some examples of how to measure server trust.

+6
source share

I had the same problem, and while adding the certificate manually, the problem was fixed, it also means the need to update the application every time the certificate on the server changes (for example, when it expires, which in my case will happen in a few days).

If you use the IP address to connect to the socket, and the certificate is for the fully qualified domain name (fully qualified domain name, i.e. subdomain.example.com), then when the operating system checks the certificate, it is going to look at the IP address to to which you connect, compare it with the name in the certificate and think that they are different, which leads to a failure of the chain verification.

So, for anyone who encounters this problem, I recommend using the fully qualified domain name in the second parameter of CFStreamCreatePairWithSocketToHost instead of the IP address. After that, it should work without having to include the certificate in the package and verify it manually.

0
source share

All Articles