OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef) { BEGIN_SECKCITEMAPI Item item = ItemImpl::required(__itemImplRef); Keychain keychain = item->keychain(); // item must be persistent. KCThrowIf_( !keychain, errSecInvalidItemRef ); /* * Before deleting the item, delete any existing Extended Attributes. */ OSStatus ortn; CFArrayRef attrNames = NULL; ortn = SecKeychainItemCopyAllExtendedAttributes(__itemImplRef, &attrNames, NULL); if(ortn == errSecSuccess) { CFIndex numAttrs = CFArrayGetCount(attrNames); for(CFIndex dex=0; dex<numAttrs; dex++) { CFStringRef attrName = (CFStringRef)CFArrayGetValueAtIndex(attrNames, dex); /* setting value to NULL ==> delete */ SecKeychainItemSetExtendedAttribute(__itemImplRef, attrName, NULL); } } /* now delete the item */ keychain->deleteItem( item ); END_SECKCITEMAPI }
static int do_keychain_import( SecKeychainRef kcRef, CFDataRef inData, SecExternalFormat externFormat, SecExternalItemType itemType, SecAccessRef access, Boolean nonExtractable, const char *passphrase, const char *fileName, char **attrNames, char **attrValues, unsigned numExtendedAttributes) { SecKeyImportExportParameters keyParams; OSStatus ortn; CFStringRef fileStr; CFArrayRef outArray = NULL; int result = 0; int numCerts = 0; int numKeys = 0; int numIdentities = 0; int tryCount = 0; CFIndex dex; CFIndex numItems = 0; CFStringRef passStr = NULL; CFStringRef promptStr = NULL; CFStringRef retryStr = NULL; /* * Specify some kind of passphrase in case caller doesn't know this * is a wrapped object */ memset(&keyParams, 0, sizeof(SecKeyImportExportParameters)); keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; if(passphrase != NULL) { passStr = CFStringCreateWithCString(NULL, passphrase, kCFStringEncodingASCII); keyParams.passphrase = passStr; } else { keyParams.flags = kSecKeySecurePassphrase; } if(nonExtractable) { // explicitly set the key attributes, omitting the CSSM_KEYATTR_EXTRACTABLE bit keyParams.keyAttributes = CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_SENSITIVE; } keyParams.accessRef = access; fileStr = CFStringCreateWithCString(NULL, fileName, kCFStringEncodingUTF8); if (fileStr) { CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, fileStr, kCFURLPOSIXPathStyle, FALSE); if (fileURL) { CFStringRef nameStr = CFURLCopyLastPathComponent(fileURL); if (nameStr) { safe_CFRelease(&fileStr); fileStr = nameStr; } safe_CFRelease(&fileURL); } } promptStr = CFStringCreateWithFormat(NULL, NULL, KC_IMPORT_KEY_PASSWORD_MESSAGE, fileStr); retryStr = CFStringCreateWithFormat(NULL, NULL, KC_IMPORT_KEY_PASSWORD_RETRYMESSAGE, fileStr); while (TRUE) { keyParams.alertPrompt = (tryCount == 0) ? promptStr : retryStr; ortn = SecKeychainItemImport(inData, fileStr, &externFormat, &itemType, 0, /* flags not used (yet) */ &keyParams, kcRef, &outArray); if(ortn) { if (ortn == errSecPkcs12VerifyFailure && ++tryCount < 3) { continue; } sec_perror("SecKeychainItemImport", ortn); result = 1; goto cleanup; } break; } /* * Parse returned items & report to user */ if(outArray == NULL) { sec_error("No keychain items found"); result = 1; goto cleanup; } numItems = CFArrayGetCount(outArray); for(dex=0; dex<numItems; dex++) { CFTypeRef item = CFArrayGetValueAtIndex(outArray, dex); CFTypeID itemType = CFGetTypeID(item); if(itemType == SecIdentityGetTypeID()) { numIdentities++; } else if(itemType == SecCertificateGetTypeID()) { numCerts++; } else if(itemType == SecKeyGetTypeID()) { numKeys++; } else { sec_error("Unexpected item type returned from SecKeychainItemImport"); result = 1; goto cleanup; } } if(numIdentities) { char *str; if(numIdentities > 1) { str = "identities"; } else { str = "identity"; } fprintf(stdout, "%d %s imported.\n", numIdentities, str); } if(numKeys) { char *str; if(numKeys > 1) { str = "keys"; } else { str = "key"; } fprintf(stdout, "%d %s imported.\n", numKeys, str); } if(numCerts) { char *str; if(numCerts > 1) { str = "certificates"; } else { str = "certificate"; } fprintf(stdout, "%d %s imported.\n", numCerts, str); } /* optionally apply extended attributes */ if(numExtendedAttributes) { unsigned attrDex; for(attrDex=0; attrDex<numExtendedAttributes; attrDex++) { CFStringRef attrNameStr = CFStringCreateWithCString(NULL, attrNames[attrDex], kCFStringEncodingASCII); CFDataRef attrValueData = CFDataCreate(NULL, (const UInt8 *)attrValues[attrDex], strlen(attrValues[attrDex])); for(dex=0; dex<numItems; dex++) { SecKeychainItemRef itemRef = (SecKeychainItemRef)CFArrayGetValueAtIndex(outArray, dex); ortn = SecKeychainItemSetExtendedAttribute(itemRef, attrNameStr, attrValueData); if(ortn) { cssmPerror("SecKeychainItemSetExtendedAttribute", ortn); result = 1; break; } } /* for each imported item */ CFRelease(attrNameStr); CFRelease(attrValueData); if(result) { break; } } /* for each extended attribute */ } cleanup: safe_CFRelease(&fileStr); safe_CFRelease(&outArray); safe_CFRelease(&passStr); safe_CFRelease(&promptStr); safe_CFRelease(&retryStr); return result; }