/* new in 10.6 */ OSStatus SecKeyDecrypt( SecKeyRef key, /* Private key */ SecPadding padding, /* kSecPaddingNone, kSecPaddingPKCS1, kSecPaddingOAEP */ const uint8_t *cipherText, size_t cipherTextLen, /* length of cipherText */ uint8_t *plainText, size_t *plainTextLen) /* IN/OUT */ { BEGIN_SECAPI SecPointer<KeyItem> keyItem(KeyItem::required(key)); CSSM_DATA inData, outData; inData.Data = (uint8*) cipherText; inData.Length = cipherTextLen; outData.Data = plainText; outData.Length = *plainTextLen; const AccessCredentials* credentials = keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_SIGN, kSecCredentialTypeDefault); keyItem->Decrypt(padding, inData, credentials, outData); *plainTextLen = outData.Length; END_SECAPI }
/* new in 10.6 */ OSStatus SecKeyRawVerify( SecKeyRef key, SecPadding padding, const uint8_t *signedData, size_t signedDataLen, const uint8_t *sig, size_t sigLen) { BEGIN_SECAPI Required(key); SecPointer<KeyItem> keyItem(KeyItem::required(key)); CSSM_DATA dataInput; dataInput.Data = (uint8_t*) signedData; dataInput.Length = signedDataLen; CSSM_DATA signature; signature.Data = (uint8_t*) sig; signature.Length = sigLen; const AccessCredentials* credentials = keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_ANY, kSecCredentialTypeDefault); keyItem->RawVerify(padding, dataInput, credentials, signature); END_SECAPI }
/* new in 10.6 */ OSStatus SecKeyEncrypt( SecKeyRef key, SecPadding padding, const uint8_t *plainText, size_t plainTextLen, uint8_t *cipherText, size_t *cipherTextLen) { BEGIN_SECAPI SecPointer<KeyItem> keyItem(KeyItem::required(key)); CSSM_DATA inData, outData; inData.Data = (uint8*) plainText; inData.Length = plainTextLen; outData.Data = cipherText; outData.Length = *cipherTextLen; const AccessCredentials* credentials = keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_SIGN, kSecCredentialTypeDefault); keyItem->Encrypt(padding, inData, credentials, outData); *cipherTextLen = outData.Length; END_SECAPI }
/* new in 10.6 */ OSStatus SecKeyRawSign( SecKeyRef key, SecPadding padding, const uint8_t *dataToSign, size_t dataToSignLen, uint8_t *sig, size_t *sigLen) { BEGIN_SECAPI Required(key); SecPointer<KeyItem> keyItem(KeyItem::required(key)); CSSM_DATA dataInput; dataInput.Data = (uint8_t*) dataToSign; dataInput.Length = dataToSignLen; CSSM_DATA output; output.Data = sig; output.Length = *sigLen; const AccessCredentials* credentials = keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_SIGN, kSecCredentialTypeDefault); keyItem->RawSign(padding, dataInput, credentials, output); *sigLen = output.Length; END_SECAPI }
OSStatus SecKeyGetStrengthInBits(SecKeyRef keyRef, const CSSM_X509_ALGORITHM_IDENTIFIER *algid, unsigned int *strength) { BEGIN_SECAPI SecPointer<KeyItem> keyItem(KeyItem::required(keyRef)); Required(strength) = keyItem->strengthInBits(algid); END_SECAPI }
OSStatus SecKeyGetAlgorithmID(SecKeyRef keyRef, const CSSM_X509_ALGORITHM_IDENTIFIER **algid) { BEGIN_SECAPI SecPointer<KeyItem> keyItem(KeyItem::required(keyRef)); Required(algid) = &keyItem->algorithmIdentifier(); END_SECAPI }
OSStatus SecKeyGetCSPHandle(SecKeyRef keyRef, CSSM_CSP_HANDLE *cspHandle) { BEGIN_SECAPI SecPointer<KeyItem> keyItem(KeyItem::required(keyRef)); Required(cspHandle) = keyItem->csp()->handle(); END_SECAPI }
OSStatus SecKeyGetCredentials( SecKeyRef keyRef, CSSM_ACL_AUTHORIZATION_TAG operation, SecCredentialType credentialType, const CSSM_ACCESS_CREDENTIALS **outCredentials) { BEGIN_SECAPI SecPointer<KeyItem> keyItem(KeyItem::required(keyRef)); Required(outCredentials) = keyItem->getCredentials(operation, credentialType); END_SECAPI }
CFDataRef decodePrivateKeyHeader(SecKeychainRef keychain, const FVPrivateKeyHeader &inHeader) { // kSecKeyLabel is defined in libsecurity_keychain/lib/SecKey.h SecKeychainAttribute attrs[] = { { 6 /* kSecKeyLabel */, inHeader.publicKeyHashSize, const_cast<uint8 *>(inHeader.publicKeyHash) } }; SecKeychainAttributeList attrList = { sizeof(attrs) / sizeof(SecKeychainAttribute), attrs }; CSSM_CSP_HANDLE cspHandle = 0; const CSSM_KEY *cssmKey = NULL; const CSSM_ACCESS_CREDENTIALS *accessCred = NULL; CSSM_CC_HANDLE cc = 0; SecKeychainSearchRef _searchRef; throwIfError(SecKeychainSearchCreateFromAttributes(keychain, (SecItemClass) CSSM_DL_DB_RECORD_PRIVATE_KEY, &attrList, &_searchRef)); CFRef<SecKeychainSearchRef> searchRef(_searchRef); SecKeychainItemRef _item; if (SecKeychainSearchCopyNext(searchRef, &_item) != 0) { return NULL; // XXX possibly should throw here? } CFRef<SecKeyRef> keyItem(reinterpret_cast<SecKeyRef>(_item)); throwIfError(SecKeyGetCSPHandle(keyItem, &cspHandle)); throwIfError(SecKeyGetCSSMKey(keyItem, &cssmKey)); throwIfError(SecKeyGetCredentials(keyItem, CSSM_ACL_AUTHORIZATION_DECRYPT, kSecCredentialTypeDefault, &accessCred)); throwIfError(CSSM_CSP_CreateAsymmetricContext(cspHandle, cssmKey->KeyHeader.AlgorithmId, accessCred, cssmKey, CSSM_PADDING_PKCS1, &cc)); CFDataRef result; try { CssmMemoryFunctions memFuncs; throwIfError(CSSM_GetAPIMemoryFunctions(cspHandle, &memFuncs)); CssmMemoryFunctionsAllocator allocator(memFuncs); const CssmData cipherBuf(const_cast<uint8 *>(inHeader.encryptedBlob), inHeader.encryptedBlobSize); CssmAutoData clearBuf(allocator); CssmAutoData remData(allocator); size_t bytesDecrypted; CSSM_RETURN crx = CSSM_DecryptData(cc, &cipherBuf, 1, &clearBuf.get(), 1, &bytesDecrypted, &remData.get()); secinfo("FDERecovery", "decodePrivateKeyHeader: CSSM_DecryptData result: %d", crx); throwIfError(crx); // throwIfError(CSSM_DecryptData(cc, &cipherBuf, 1, &clearBuf.get(), 1, &bytesDecrypted, &remData.get())); clearBuf.length(bytesDecrypted); // rawKey.copy(clearBuf.get()); result = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)clearBuf.get().data(), clearBuf.get().length()); // result = parseKeyBlob(clearBuf.get()); } catch(...) { CSSM_DeleteContext(cc); throw; } throwIfError(CSSM_DeleteContext(cc)); return result; }