iOS - Install SSL certificate programmatically
It's no enough to import the certificate into the keychain. The new root certificate has also be trusted by the user or system.
Assuming you still have the SecCertificateRef
in the variable certificate
, use the following code to raise the trust level:
NSDictionary *newTrustSettings = @{(id)kSecTrustSettingsResult: [NSNumber numberWithInt:kSecTrustSettingsResultTrustRoot]};status = SecTrustSettingsSetTrustSettings(certificate, kSecTrustSettingsDomainUser, (__bridge CFTypeRef)(newTrustSettings));if (status != errSecSuccess) { NSLog(@"Could not change the trust setting for a certificate. Error: %d", status); exit(0);}
Changing the trust level will ask the user in a popup window if he accepts the change.
Swift 4.0
let rootCertPath = Bundle.main.path(forResource: "XXXXX", ofType: "der") let rootCertData = NSData(contentsOfFile: rootCertPath!) var err: OSStatus = noErr let rootCert = SecCertificateCreateWithData(kCFAllocatorDefault, rootCertData!) //var result: CFTypeRef1 let dict = NSDictionary.init(objects: [kSecClassCertificate, rootCert!], forKeys: [kSecClass as! NSCopying, kSecValueRef as! NSCopying]) err = SecItemAdd(dict, nil) if(err == noErr) { NSLog("Install root certificate success"); } else if( err == errSecDuplicateItem ) { NSLog("duplicate root certificate entry"); } else { NSLog("install root certificate failure"); }
Which I was looking for, setting "Always Trust" for System keychain certificate,
// Trust always, as root certificated. NSDictionary *newTrustSettings = @{(id)kSecTrustSettingsResult: [NSNumber numberWithInt:kSecTrustSettingsResultTrustRoot]}; status = SecTrustSettingsSetTrustSettings(myCertificate, kSecTrustSettingsDomainAdmin, (__bridge CFTypeRef)(newTrustSettings));