security: Fixing memory leaks and properly handling non-existing keys
Change-Id: I9145b009d9d9d5e7862a26d0be8c3b7085a42c4b
Refs: #1562, #1563
diff --git a/src/security/sec-tpm-osx.cpp b/src/security/sec-tpm-osx.cpp
index 5132c3d..a7e1cd9 100644
--- a/src/security/sec-tpm-osx.cpp
+++ b/src/security/sec-tpm-osx.cpp
@@ -34,6 +34,111 @@
namespace ndn {
+/**
+ * @brief Helper class to wrap CoreFoundation object pointers
+ *
+ * The class is similar in spirit to shared_ptr, but uses CoreFoundation
+ * mechanisms to retain/release object.
+ *
+ * Original implementation by Christopher Hunt and it was borrowed from
+ * http://www.cocoabuilder.com/archive/cocoa/130776-auto-cfrelease-and.html
+ */
+template<class T>
+class CFReleaser
+{
+public:
+ //////////////////////////////
+ // Construction/destruction //
+
+ CFReleaser()
+ : m_typeRef(0)
+ {
+ }
+
+ CFReleaser(const T& typeRef)
+ : m_typeRef(typeRef)
+ {
+ }
+
+ CFReleaser(const CFReleaser& inReleaser)
+ : m_typeRef(0)
+ {
+ retain(inReleaser.m_typeRef);
+ }
+
+ CFReleaser&
+ operator=(const T& typeRef)
+ {
+ if (typeRef != m_typeRef) {
+ release();
+ m_typeRef = typeRef;
+ }
+ return *this;
+ }
+
+ CFReleaser&
+ operator=(const CFReleaser& inReleaser)
+ {
+ retain(inReleaser.m_typeRef);
+ return *this;
+ }
+
+ ~CFReleaser()
+ {
+ release();
+ }
+
+ ////////////
+ // Access //
+
+ // operator const T&() const
+ // {
+ // return m_typeRef;
+ // }
+
+ // operator T&()
+ // {
+ // return m_typeRef;
+ // }
+
+ const T&
+ get() const
+ {
+ return m_typeRef;
+ }
+
+ T&
+ get()
+ {
+ return m_typeRef;
+ }
+
+ ///////////////////
+ // Miscellaneous //
+
+ void
+ retain(const T& typeRef)
+ {
+ if (typeRef != 0) {
+ CFRetain(typeRef);
+ }
+ release();
+ m_typeRef = typeRef;
+ }
+
+ void release()
+ {
+ if (m_typeRef != 0) {
+ CFRelease(m_typeRef);
+ m_typeRef = 0;
+ }
+ };
+
+private:
+ T m_typeRef;
+};
+
+
class SecTpmOsx::Impl
{
public:
@@ -60,7 +165,7 @@
* @param keyClass
* @returns pointer to the key
*/
- SecKeychainItemRef
+ CFReleaser<SecKeychainItemRef>
getKey(const Name& keyName, KeyClass keyClass);
/**
@@ -118,7 +223,6 @@
bool m_inTerminal;
};
-
SecTpmOsx::SecTpmOsx()
: m_impl(new Impl)
{
@@ -259,29 +363,29 @@
string keyNameUri = m_impl->toInternalKeyName(keyName, KEY_CLASS_PUBLIC);
- SecKeyRef publicKey, privateKey;
+ CFReleaser<CFStringRef> keyLabel =
+ CFStringCreateWithCString(0,
+ keyNameUri.c_str(),
+ kCFStringEncodingUTF8);
- CFStringRef keyLabel = CFStringCreateWithCString(0,
- keyNameUri.c_str(),
- kCFStringEncodingUTF8);
+ CFReleaser<CFMutableDictionaryRef> attrDict =
+ CFDictionaryCreateMutable(0,
+ 3,
+ &kCFTypeDictionaryKeyCallBacks,
+ 0);
- CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(0,
- 3,
- &kCFTypeDictionaryKeyCallBacks,
- 0);
+ CFReleaser<CFNumberRef> cfKeySize = CFNumberCreate(0, kCFNumberIntType, &keySize);
- CFDictionaryAddValue(attrDict, kSecAttrKeyType, m_impl->getAsymKeyType(keyType));
- CFDictionaryAddValue(attrDict, kSecAttrKeySizeInBits, CFNumberCreate(0,
- kCFNumberIntType,
- &keySize));
- CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
+ CFDictionaryAddValue(attrDict.get(), kSecAttrKeyType, m_impl->getAsymKeyType(keyType));
+ CFDictionaryAddValue(attrDict.get(), kSecAttrKeySizeInBits, cfKeySize.get());
+ CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
- OSStatus res = SecKeyGeneratePair((CFDictionaryRef)attrDict, &publicKey, &privateKey);
+ CFReleaser<SecKeyRef> publicKey, privateKey;
+ OSStatus res = SecKeyGeneratePair((CFDictionaryRef)attrDict.get(),
+ &publicKey.get(), &privateKey.get());
if (res == errSecSuccess)
{
- CFRelease(publicKey);
- CFRelease(privateKey);
return;
}
@@ -301,19 +405,20 @@
void
SecTpmOsx::deleteKeyPairInTpmInternal(const Name& keyName, bool needRetry)
{
- CFStringRef keyLabel = CFStringCreateWithCString(0,
- keyName.toUri().c_str(),
- kCFStringEncodingUTF8);
+ CFReleaser<CFStringRef> keyLabel =
+ CFStringCreateWithCString(0,
+ keyName.toUri().c_str(),
+ kCFStringEncodingUTF8);
- CFMutableDictionaryRef searchDict =
+ CFReleaser<CFMutableDictionaryRef> searchDict =
CFDictionaryCreateMutable(0, 5,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- CFDictionaryAddValue(searchDict, kSecClass, kSecClassKey);
- CFDictionaryAddValue(searchDict, kSecAttrLabel, keyLabel);
- CFDictionaryAddValue(searchDict, kSecMatchLimit, kSecMatchLimitAll);
- OSStatus res = SecItemDelete(searchDict);
+ CFDictionaryAddValue(searchDict.get(), kSecClass, kSecClassKey);
+ CFDictionaryAddValue(searchDict.get(), kSecAttrLabel, keyLabel.get());
+ CFDictionaryAddValue(searchDict.get(), kSecMatchLimit, kSecMatchLimitAll);
+ OSStatus res = SecItemDelete(searchDict.get());
if (res == errSecSuccess)
return;
@@ -334,21 +439,23 @@
// string keyNameUri = m_impl->toInternalKeyName(keyName, KEY_CLASS_SYMMETRIC);
- // CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(kCFAllocatorDefault,
- // 0,
- // &kCFTypeDictionaryKeyCallBacks,
- // &kCFTypeDictionaryValueCallBacks);
+ // CFReleaser<CFMutableDictionaryRef> attrDict =
+ // CFDictionaryCreateMutable(kCFAllocatorDefault,
+ // 0,
+ // &kCFTypeDictionaryKeyCallBacks,
+ // &kCFTypeDictionaryValueCallBacks);
- // CFStringRef keyLabel = CFStringCreateWithCString(0,
- // keyNameUri.c_str(),
- // kCFStringEncodingUTF8);
+ // CFReleaser<CFStringRef> keyLabel =
+ // CFStringCreateWithCString(0,
+ // keyNameUri.c_str(),
+ // kCFStringEncodingUTF8);
- // CFDictionaryAddValue(attrDict, kSecAttrKeyType, m_impl->getSymKeyType(keyType));
- // CFDictionaryAddValue(attrDict, kSecAttrKeySizeInBits, CFNumberCreate(kCFAllocatorDefault,
- // kCFNumberSInt32Type,
- // &keySize));
- // CFDictionaryAddValue(attrDict, kSecAttrIsPermanent, kCFBooleanTrue);
- // CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
+ // CFReleaser<CFNumberRef> cfKeySize = CFNumberCreate(0, kCFNumberIntType, &keySize);
+
+ // CFDictionaryAddValue(attrDict.get(), kSecAttrKeyType, m_impl->getSymKeyType(keyType));
+ // CFDictionaryAddValue(attrDict.get(), kSecAttrKeySizeInBits, cfKeySize.get());
+ // CFDictionaryAddValue(attrDict.get(), kSecAttrIsPermanent, kCFBooleanTrue);
+ // CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
// CFErrorRef error = 0;
@@ -361,23 +468,25 @@
shared_ptr<PublicKey>
SecTpmOsx::getPublicKeyFromTpm(const Name& keyName)
{
- SecKeychainItemRef publicKey = m_impl->getKey(keyName, KEY_CLASS_PUBLIC);
+ CFReleaser<SecKeychainItemRef> publicKey = m_impl->getKey(keyName, KEY_CLASS_PUBLIC);
+ if (publicKey.get() == 0)
+ {
+ throw Error("Requested public key [" + keyName.toUri() + "] does not exist in OSX Keychain");
+ }
- CFDataRef exportedKey;
-
- OSStatus res = SecItemExport(publicKey,
+ CFReleaser<CFDataRef> exportedKey;
+ OSStatus res = SecItemExport(publicKey.get(),
kSecFormatOpenSSL,
0,
0,
- &exportedKey);
+ &exportedKey.get());
if (res != errSecSuccess)
{
throw Error("Cannot export requested public key from OSX Keychain");
}
- shared_ptr<PublicKey> key = make_shared<PublicKey>(CFDataGetBytePtr(exportedKey),
- CFDataGetLength(exportedKey));
- CFRelease(exportedKey);
+ shared_ptr<PublicKey> key = make_shared<PublicKey>(CFDataGetBytePtr(exportedKey.get()),
+ CFDataGetLength(exportedKey.get()));
return key;
}
@@ -386,13 +495,19 @@
{
using namespace CryptoPP;
- SecKeychainItemRef privateKey = m_impl->getKey(keyName, KEY_CLASS_PRIVATE);
- CFDataRef exportedKey;
- OSStatus res = SecItemExport(privateKey,
+ CFReleaser<SecKeychainItemRef> privateKey = m_impl->getKey(keyName, KEY_CLASS_PRIVATE);
+ if (privateKey.get() == 0)
+ {
+ /// @todo Can this happen because of keychain is locked?
+ throw Error("Private key [" + keyName.toUri() + "] does not exist in OSX Keychain");
+ }
+
+ CFReleaser<CFDataRef> exportedKey;
+ OSStatus res = SecItemExport(privateKey.get(),
kSecFormatOpenSSL,
0,
0,
- &exportedKey);
+ &exportedKey.get());
if (res != errSecSuccess)
{
@@ -427,12 +542,11 @@
}
privateKeyAlgorithm.MessageEnd();
DEREncodeOctetString(privateKeyInfo,
- CFDataGetBytePtr(exportedKey),
- CFDataGetLength(exportedKey));
+ CFDataGetBytePtr(exportedKey.get()),
+ CFDataGetLength(exportedKey.get()));
}
privateKeyInfo.MessageEnd();
- CFRelease(exportedKey);
return pkcs1Os.buf();
}
@@ -470,10 +584,10 @@
}
privateKeyInfo.MessageEnd();
- CFDataRef importedKey = CFDataCreateWithBytesNoCopy(0,
- rawKeyBits.BytePtr(),
- rawKeyBits.size(),
- kCFAllocatorNull);
+ CFReleaser<CFDataRef> importedKey = CFDataCreateWithBytesNoCopy(0,
+ rawKeyBits.BytePtr(),
+ rawKeyBits.size(),
+ kCFAllocatorNull);
SecExternalFormat externalFormat = kSecFormatOpenSSL;
SecExternalItemType externalType = kSecItemTypePrivateKey;
@@ -481,27 +595,27 @@
memset(&keyParams, 0, sizeof(keyParams));
keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
keyParams.keyAttributes = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT;
- SecAccessRef access;
- CFStringRef keyLabel = CFStringCreateWithCString(0,
- keyName.toUri().c_str(),
- kCFStringEncodingUTF8);
- SecAccessCreate(keyLabel, 0, &access);
- keyParams.accessRef = access;
- CFArrayRef outItems;
+ CFReleaser<SecAccessRef> access;
+ CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(0,
+ keyName.toUri().c_str(),
+ kCFStringEncodingUTF8);
+ SecAccessCreate(keyLabel.get(), 0, &access.get());
+ keyParams.accessRef = access.get();
+ CFReleaser<CFArrayRef> outItems;
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif // __clang__
- OSStatus res = SecKeychainItemImport (importedKey,
- 0,
- &externalFormat,
- &externalType,
- 0,
- &keyParams,
- m_impl->m_keyChainRef,
- &outItems);
+ OSStatus res = SecKeychainItemImport(importedKey.get(),
+ 0,
+ &externalFormat,
+ &externalType,
+ 0,
+ &keyParams,
+ m_impl->m_keyChainRef,
+ &outItems.get());
#ifdef __clang__
#pragma clang diagnostic pop
@@ -520,7 +634,7 @@
return false;
}
- SecKeychainItemRef privateKey = (SecKeychainItemRef)CFArrayGetValueAtIndex(outItems, 0);
+ SecKeychainItemRef privateKey = (SecKeychainItemRef)CFArrayGetValueAtIndex(outItems.get(), 0);
SecKeychainAttribute attrs[1]; // maximum number of attributes
SecKeychainAttributeList attrList = { 0, attrs };
string keyUri = keyName.toUri();
@@ -541,7 +655,6 @@
return false;
}
- CFRelease(importedKey);
return true;
}
@@ -552,28 +665,28 @@
bool
SecTpmOsx::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
{
- CFDataRef importedKey = CFDataCreateWithBytesNoCopy(0,
- buf,
- size,
- kCFAllocatorNull);
+ CFReleaser<CFDataRef> importedKey = CFDataCreateWithBytesNoCopy(0,
+ buf,
+ size,
+ kCFAllocatorNull);
SecExternalFormat externalFormat = kSecFormatOpenSSL;
SecExternalItemType externalType = kSecItemTypePublicKey;
- CFArrayRef outItems;
+ CFReleaser<CFArrayRef> outItems;
- OSStatus res = SecItemImport (importedKey,
- 0,
- &externalFormat,
- &externalType,
- 0,
- 0,
- m_impl->m_keyChainRef,
- &outItems);
+ OSStatus res = SecItemImport(importedKey.get(),
+ 0,
+ &externalFormat,
+ &externalType,
+ 0,
+ 0,
+ m_impl->m_keyChainRef,
+ &outItems.get());
if (res != errSecSuccess)
return false;
- SecKeychainItemRef publicKey = (SecKeychainItemRef)CFArrayGetValueAtIndex(outItems, 0);
+ SecKeychainItemRef publicKey = (SecKeychainItemRef)CFArrayGetValueAtIndex(outItems.get(), 0);
SecKeychainAttribute attrs[1]; // maximum number of attributes
SecKeychainAttributeList attrList = { 0, attrs };
string keyUri = keyName.toUri();
@@ -592,7 +705,6 @@
if (res != errSecSuccess)
return false;
- CFRelease(importedKey);
return true;
}
@@ -600,54 +712,60 @@
SecTpmOsx::signInTpmInternal(const uint8_t* data, size_t dataLength,
const Name& keyName, DigestAlgorithm digestAlgorithm, bool needRetry)
{
- CFDataRef dataRef = CFDataCreateWithBytesNoCopy(0,
- data,
- dataLength,
- kCFAllocatorNull);
+ CFReleaser<CFDataRef> dataRef = CFDataCreateWithBytesNoCopy(0,
+ data,
+ dataLength,
+ kCFAllocatorNull);
- SecKeyRef privateKey = (SecKeyRef)m_impl->getKey(keyName, KEY_CLASS_PRIVATE);
+ CFReleaser<SecKeychainItemRef> privateKey = m_impl->getKey(keyName, KEY_CLASS_PRIVATE);
+ if (privateKey.get() == 0)
+ {
+ throw Error("Private key [" + keyName.toUri() + "] does not exist in OSX Keychain");
+ }
- CFErrorRef error;
- SecTransformRef signer = SecSignTransformCreate((SecKeyRef)privateKey, &error);
- if (error)
+ CFReleaser<CFErrorRef> error;
+ CFReleaser<SecTransformRef> signer = SecSignTransformCreate((SecKeyRef)privateKey.get(),
+ &error.get());
+ if (error.get() != 0)
throw Error("Fail to create signer");
// Set input
- Boolean set_res = SecTransformSetAttribute(signer,
+ Boolean set_res = SecTransformSetAttribute(signer.get(),
kSecTransformInputAttributeName,
- dataRef,
- &error);
- if (error)
+ dataRef.get(),
+ &error.get());
+ if (error.get() != 0)
throw Error("Fail to configure input of signer");
// Enable use of padding
- SecTransformSetAttribute(signer,
+ SecTransformSetAttribute(signer.get(),
kSecPaddingKey,
kSecPaddingPKCS1Key,
- &error);
- if (error)
+ &error.get());
+ if (error.get() != 0)
throw Error("Fail to configure digest algorithm of signer");
// Set padding type
- set_res = SecTransformSetAttribute(signer,
+ set_res = SecTransformSetAttribute(signer.get(),
kSecDigestTypeAttribute,
m_impl->getDigestAlgorithm(digestAlgorithm),
- &error);
- if (error)
+ &error.get());
+ if (error.get() != 0)
throw Error("Fail to configure digest algorithm of signer");
// Set padding attribute
long digestSize = m_impl->getDigestSize(digestAlgorithm);
- set_res = SecTransformSetAttribute(signer,
+ CFReleaser<CFNumberRef> cfDigestSize = CFNumberCreate(0, kCFNumberLongType, &digestSize);
+ set_res = SecTransformSetAttribute(signer.get(),
kSecDigestLengthAttribute,
- CFNumberCreate(0, kCFNumberLongType, &digestSize),
- &error);
- if (error)
+ cfDigestSize.get(),
+ &error.get());
+ if (error.get() != 0)
throw Error("Fail to configure digest size of signer");
// Actually sign
- CFDataRef signature = (CFDataRef) SecTransformExecute(signer, &error);
- if (error)
+ CFReleaser<CFDataRef> signature = (CFDataRef)SecTransformExecute(signer.get(), &error.get());
+ if (error.get() != 0)
{
if (!needRetry)
{
@@ -658,16 +776,17 @@
}
else
{
- CFShow(error);
+ CFShow(error.get());
throw Error("Fail to sign data");
}
}
- if (!signature)
+ if (signature.get() == 0)
throw Error("Signature is NULL!\n");
return Block(Tlv::SignatureValue,
- make_shared<Buffer>(CFDataGetBytePtr(signature), CFDataGetLength(signature)));
+ make_shared<Buffer>(CFDataGetBytePtr(signature.get()),
+ CFDataGetLength(signature.get())));
}
ConstBufferPtr
@@ -686,7 +805,12 @@
// dataLength
// );
- // SecKeyRef decryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
+ // CFReleaser<SecKeyRef> decryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
+ // if (decryptKey.get() == 0)
+ // {
+ // /// @todo Can this happen because of keychain is locked?
+ // throw Error("Decruption key [" + ??? + "] does not exist in OSX Keychain");
+ // }
// CFErrorRef error;
// SecTransformRef decrypt = SecDecryptTransformCreate(decryptKey, &error);
@@ -714,40 +838,44 @@
{
if (keyClass == KEY_CLASS_PRIVATE && acl == ACL_TYPE_PRIVATE)
{
- SecKeychainItemRef privateKey = m_impl->getKey(keyName, keyClass);
+ CFReleaser<SecKeychainItemRef> privateKey = m_impl->getKey(keyName, keyClass);
+ if (privateKey.get() == 0)
+ {
+ throw Error("Private key [" + keyName.toUri() + "] does not exist in OSX Keychain");
+ }
- SecAccessRef accRef;
- OSStatus acc_res = SecKeychainItemCopyAccess(privateKey, &accRef);
+ CFReleaser<SecAccessRef> accRef;
+ OSStatus acc_res = SecKeychainItemCopyAccess(privateKey.get(), &accRef.get());
- CFArrayRef signACL = SecAccessCopyMatchingACLList(accRef,
- kSecACLAuthorizationSign);
+ CFReleaser<CFArrayRef> signACL = SecAccessCopyMatchingACLList(accRef.get(),
+ kSecACLAuthorizationSign);
- SecACLRef aclRef = (SecACLRef) CFArrayGetValueAtIndex(signACL, 0);
+ SecACLRef aclRef = (SecACLRef)CFArrayGetValueAtIndex(signACL.get(), 0);
- CFArrayRef appList;
- CFStringRef description;
+ CFReleaser<CFArrayRef> appList;
+ CFReleaser<CFStringRef> description;
SecKeychainPromptSelector promptSelector;
OSStatus acl_res = SecACLCopyContents(aclRef,
- &appList,
- &description,
+ &appList.get(),
+ &description.get(),
&promptSelector);
- CFMutableArrayRef newAppList = CFArrayCreateMutableCopy(0,
- 0,
- appList);
+ CFReleaser<CFMutableArrayRef> newAppList = CFArrayCreateMutableCopy(0,
+ 0,
+ appList.get());
- SecTrustedApplicationRef trustedApp;
+ CFReleaser<SecTrustedApplicationRef> trustedApp;
acl_res = SecTrustedApplicationCreateFromPath(appPath.c_str(),
- &trustedApp);
+ &trustedApp.get());
- CFArrayAppendValue(newAppList, trustedApp);
+ CFArrayAppendValue(newAppList.get(), trustedApp.get());
acl_res = SecACLSetContents(aclRef,
- newAppList,
- description,
+ newAppList.get(),
+ description.get(),
promptSelector);
- acc_res = SecKeychainItemSetAccess(privateKey, accRef);
+ acc_res = SecKeychainItemSetAccess(privateKey.get(), accRef.get());
}
}
@@ -767,7 +895,11 @@
// dataLength
// );
- // SecKeyRef encryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
+ // CFReleaser<SecKeyRef> encryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
+ // if (encryptKey.get() == 0)
+ // {
+ // throw Error("Encryption key [" + ???? + "] does not exist in OSX Keychain");
+ // }
// CFErrorRef error;
// SecTransformRef encrypt = SecEncryptTransformCreate(encryptKey, &error);
@@ -792,22 +924,23 @@
{
string keyNameUri = m_impl->toInternalKeyName(keyName, keyClass);
- CFStringRef keyLabel = CFStringCreateWithCString(0,
- keyNameUri.c_str(),
- kCFStringEncodingUTF8);
+ CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(0,
+ keyNameUri.c_str(),
+ kCFStringEncodingUTF8);
- CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(0,
- 4,
- &kCFTypeDictionaryKeyCallBacks,
- 0);
+ CFReleaser<CFMutableDictionaryRef> attrDict =
+ CFDictionaryCreateMutable(0,
+ 4,
+ &kCFTypeDictionaryKeyCallBacks,
+ 0);
- CFDictionaryAddValue(attrDict, kSecClass, kSecClassKey);
- // CFDictionaryAddValue(attrDict, kSecAttrKeyClass, m_impl->getKeyClass(keyClass));
- CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
- CFDictionaryAddValue(attrDict, kSecReturnRef, kCFBooleanTrue);
+ CFDictionaryAddValue(attrDict.get(), kSecClass, kSecClassKey);
+ // CFDictionaryAddValue(attrDict.get(), kSecAttrKeyClass, m_impl->getKeyClass(keyClass));
+ CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
+ CFDictionaryAddValue(attrDict.get(), kSecReturnRef, kCFBooleanTrue);
- SecKeychainItemRef itemRef;
- OSStatus res = SecItemCopyMatching((CFDictionaryRef)attrDict, (CFTypeRef*)&itemRef);
+ CFReleaser<SecKeychainItemRef> itemRef;
+ OSStatus res = SecItemCopyMatching((CFDictionaryRef)attrDict.get(), (CFTypeRef*)&itemRef.get());
if (res == errSecSuccess)
return true;
@@ -826,28 +959,28 @@
// OSXPrivateKeyStorage::Impl //
////////////////////////////////
-SecKeychainItemRef
+CFReleaser<SecKeychainItemRef>
SecTpmOsx::Impl::getKey(const Name& keyName, KeyClass keyClass)
{
string keyNameUri = toInternalKeyName(keyName, keyClass);
- CFStringRef keyLabel = CFStringCreateWithCString(0,
- keyNameUri.c_str(),
- kCFStringEncodingUTF8);
+ CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(0,
+ keyNameUri.c_str(),
+ kCFStringEncodingUTF8);
- CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(0,
- 5,
- &kCFTypeDictionaryKeyCallBacks,
- 0);
+ CFReleaser<CFMutableDictionaryRef> attrDict =
+ CFDictionaryCreateMutable(0,
+ 5,
+ &kCFTypeDictionaryKeyCallBacks,
+ 0);
- CFDictionaryAddValue(attrDict, kSecClass, kSecClassKey);
- CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
- CFDictionaryAddValue(attrDict, kSecAttrKeyClass, getKeyClass(keyClass));
- CFDictionaryAddValue(attrDict, kSecReturnRef, kCFBooleanTrue);
+ CFDictionaryAddValue(attrDict.get(), kSecClass, kSecClassKey);
+ CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
+ CFDictionaryAddValue(attrDict.get(), kSecAttrKeyClass, getKeyClass(keyClass));
+ CFDictionaryAddValue(attrDict.get(), kSecReturnRef, kCFBooleanTrue);
- SecKeychainItemRef keyItem;
-
- OSStatus res = SecItemCopyMatching((CFDictionaryRef) attrDict, (CFTypeRef*)&keyItem);
+ CFReleaser<SecKeychainItemRef> keyItem;
+ OSStatus res = SecItemCopyMatching((CFDictionaryRef)attrDict.get(), (CFTypeRef*)&keyItem.get());
if (res != errSecSuccess)
return 0;
diff --git a/tests/security/test-sec-tpm-osx.cpp b/tests/security/test-sec-tpm-osx.cpp
index 0da4233..f8df5e8 100644
--- a/tests/security/test-sec-tpm-osx.cpp
+++ b/tests/security/test-sec-tpm-osx.cpp
@@ -22,7 +22,7 @@
BOOST_AUTO_TEST_SUITE(SecurityTestSecTpmOsx)
-BOOST_AUTO_TEST_CASE (Delete)
+BOOST_AUTO_TEST_CASE(Delete)
{
SecTpmOsx tpm;
@@ -40,7 +40,7 @@
BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), false);
}
-BOOST_AUTO_TEST_CASE (SignVerify)
+BOOST_AUTO_TEST_CASE(SignVerify)
{
SecTpmOsx tpm;
@@ -81,7 +81,7 @@
tpm.deleteKeyPairInTpm(keyName);
}
-BOOST_AUTO_TEST_CASE (RandomGenerator)
+BOOST_AUTO_TEST_CASE(RandomGenerator)
{
SecTpmOsx tpm;
@@ -102,7 +102,7 @@
}
-BOOST_AUTO_TEST_CASE (ExportImportKey)
+BOOST_AUTO_TEST_CASE(ExportImportKey)
{
using namespace CryptoPP;
@@ -165,6 +165,25 @@
// BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC) == false);
}
+BOOST_AUTO_TEST_CASE(NonExistingKey)
+{
+ using namespace CryptoPP;
+
+ SecTpmOsx tpm;
+
+ Name keyName("/TestSecTpmOsx/NonExistingKey");
+
+ BOOST_REQUIRE_THROW(tpm.getPublicKeyFromTpm(keyName), SecTpmOsx::Error);
+
+ const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
+ BOOST_REQUIRE_THROW(tpm.signInTpm(content, sizeof(content), keyName, DIGEST_ALGORITHM_SHA256),
+ SecTpmOsx::Error);
+
+ BOOST_REQUIRE_THROW(tpm.signInTpm(0, 1, keyName, DIGEST_ALGORITHM_SHA256),
+ SecTpmOsx::Error);
+}
+
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace ndn