#include <Security/SecIdentity.h>
#include <CoreFoundation/CFRuntime.h>
#include <CoreFoundation/CFString.h>
#include <Security/SecCertificate.h>
#include <Security/SecKey.h>
#include <pthread.h>
#include "SecIdentityPriv.h"
#include <Security/SecInternal.h>
struct __SecIdentity {
CFRuntimeBase _base;
SecCertificateRef _certificate;
SecKeyRef _privateKey;
};
static pthread_once_t kSecIdentityRegisterClass = PTHREAD_ONCE_INIT;
static CFTypeID kSecIdentityTypeID = _kCFRuntimeNotATypeID;
static CFStringRef SecIdentityDescribe(CFTypeRef cf);
static void SecIdentityDestroy(CFTypeRef cf);
static CFStringRef SecIdentityDescribe(CFTypeRef cf) {
SecIdentityRef identity = (SecIdentityRef)cf;
return CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
CFSTR("<SecIdentityRef: %p>"), identity);
}
static void SecIdentityDestroy(CFTypeRef cf) {
SecIdentityRef identity = (SecIdentityRef)cf;
CFReleaseSafe(identity->_certificate);
CFReleaseSafe(identity->_privateKey);
}
static Boolean SecIdentityEqual(CFTypeRef cf1, CFTypeRef cf2) {
SecIdentityRef identity1 = (SecIdentityRef)cf1;
SecIdentityRef identity2 = (SecIdentityRef)cf2;
if (identity1 == identity2)
return true;
if (!identity2)
return false;
return CFEqual(identity1->_certificate, identity2->_certificate) &&
CFEqual(identity1->_privateKey, identity2->_privateKey);
}
static CFHashCode SecIdentityHash(CFTypeRef cf) {
SecIdentityRef identity = (SecIdentityRef)cf;
return CFHash(identity->_certificate) + CFHash(identity->_privateKey);
}
static void SecIdentityRegisterClass(void) {
static const CFRuntimeClass kSecIdentityClass = {
0,
"SecIdentity",
NULL,
NULL,
SecIdentityDestroy,
SecIdentityEqual,
SecIdentityHash,
NULL,
SecIdentityDescribe
};
kSecIdentityTypeID = _CFRuntimeRegisterClass(&kSecIdentityClass);
}
CFTypeID SecIdentityGetTypeID(void) {
pthread_once(&kSecIdentityRegisterClass, SecIdentityRegisterClass);
return kSecIdentityTypeID;
}
OSStatus SecIdentityCopyCertificate(SecIdentityRef identity,
SecCertificateRef *certificateRef) {
*certificateRef = identity->_certificate;
CFRetain(*certificateRef);
return 0;
}
OSStatus SecIdentityCopyPrivateKey(SecIdentityRef identity,
SecKeyRef *privateKeyRef) {
*privateKeyRef = identity->_privateKey;
CFRetain(*privateKeyRef);
return 0;
}
SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator,
SecCertificateRef certificate, SecKeyRef privateKey) {
CFIndex size = sizeof(struct __SecIdentity);
SecIdentityRef result = (SecIdentityRef)_CFRuntimeCreateInstance(
allocator, SecIdentityGetTypeID(), size - sizeof(CFRuntimeBase), 0);
if (result) {
CFRetain(certificate);
CFRetain(privateKey);
result->_certificate = certificate;
result->_privateKey = privateKey;
}
return result;
}