Created
February 25, 2015 17:54
-
-
Save theopolis/96d6ea5d84131119ddd9 to your computer and use it in GitHub Desktop.
Small program to demo SecCertificateCopyValues leaks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is a leaky program! | |
// Line 40 will leak a few bytes in the SecurityFramework | |
// %I in xcode, profile. | |
#include <CoreFoundation/CoreFoundation.h> | |
#include <CoreFoundation/CFData.h> | |
#include <Security/Security.h> | |
void CreateAuthorities() { | |
CFMutableDictionaryRef query; | |
query = CFDictionaryCreateMutable(nullptr, | |
0, | |
&kCFTypeDictionaryKeyCallBacks, | |
&kCFTypeDictionaryValueCallBacks); | |
CFDictionaryAddValue(query, kSecClass, kSecClassCertificate); | |
CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue); | |
// This can be added to restrict results to x509v3 | |
CFDictionaryAddValue(query, kSecAttrCanVerify, kCFBooleanTrue); | |
CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitAll); | |
CFArrayRef keychain_certs; | |
auto status = SecItemCopyMatching(query, (CFTypeRef *)&keychain_certs); | |
CFRelease(query); | |
if (status != errSecSuccess) { | |
return; | |
} | |
// Store just the authority certificates. | |
auto authorities = CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks); | |
// For each certificate returned from the search, get the constraints prop. | |
for (CFIndex i = 0; i < CFArrayGetCount(keychain_certs); i++) { | |
auto cert = (SecCertificateRef)CFArrayGetValueAtIndex(keychain_certs, i); | |
auto keys = CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks); | |
CFArrayAppendValue(keys, kSecOIDBasicConstraints); // SecCertificateOIDs.h | |
// WARNING: This call will leak memory. | |
// Request dictionary of dictionaries (one for each attribute). | |
auto certificate_values = SecCertificateCopyValues(cert, keys, nullptr); | |
CFRelease(keys); | |
// Assume some checking to make sure constraints include CA: true. | |
CFRelease(certificate_values); | |
// Then if constraint exists, append. | |
CFArrayAppendValue(authorities, cert); | |
} | |
CFRelease(keychain_certs); | |
// Return this authorities list. | |
CFRelease(authorities); | |
return; | |
} | |
int main(int argc, const char * argv[]) { | |
while (true) { | |
CreateAuthorities(); | |
::usleep(100); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment