I am trying to import RSA private keys into the keychain using my application. The first time I import a key using SecKeychainImport() the operation is successful, a subsequent import gives me an EINVAL (100022) error.
This does not happen if I quit and relaunch the app between two imports. I am including the source code below.
CFArrayRef array = (CFArrayRef)[NSMutableArray array]; SecExternalFormat format = kSecFormatUnknown; //We are always storing a private key… SecExternalItemType type = kSecItemTypePrivateKey; SecKeyImportExportParameters params; SecKeychainRef keychain; SecKeychainCopyDefault(&keychain); memset(¶ms, 0, sizeof(params)); params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; params.flags = kSecKeyNoAccessControl; params.keyUsage = CSSM_KEYUSE_ANY; params.keyAttributes = CSSM_KEYATTR_EXTRACTABLE; err = SecKeychainItemImport((CFDataRef)data, (CFStringRef)@"pem", &format, &type, 0, NULL, keychain, &array); if(err == noErr) { //Change the kSecKeyPrintName attribute of the keychain item. } else { //Handle the error by displaying appropriate alert. }
Am I missing anything obvious?
Try setting the
CSSM_KEYATTR_PERMANENTbit in params.keyAttribute. On Lion, I can import multiple PEM-armoured RSA private keys (generated withopenssl genrsa) into a keychain if I explicitly set this attribute. If I don’t, I geterrSecItemNotFound(-25300) when importing the very first key.(Don’t forget to remove
kSecKeyNoAccessControlbefore deploying this code in production. Also, if you generate the key yourself, consider usingSecKeyGenerate/SecKeyGenerateSymmetricinstead.)