Skip to content

Instantly share code, notes, and snippets.

@theopolis
Created February 25, 2015 17:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theopolis/96d6ea5d84131119ddd9 to your computer and use it in GitHub Desktop.
Save theopolis/96d6ea5d84131119ddd9 to your computer and use it in GitHub Desktop.
Small program to demo SecCertificateCopyValues leaks
// 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