#include <CoreFoundation/CFString.h>
#include <Security/SecPolicy.h>
#include <Security/SecPolicyPriv.h>
#include <security_keychain/Policies.h>
#include <security_keychain/PolicyCursor.h>
#include "SecBridge.h"
CFTypeID
SecPolicyGetTypeID(void)
{
BEGIN_SECAPI
return gTypes().Policy.typeID;
END_SECAPI1(_kCFRuntimeNotATypeID)
}
OSStatus
SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID* oid)
{
BEGIN_SECAPI
Required(oid) = Policy::required(policyRef)->oid();
END_SECAPI
}
OSStatus
SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA* value)
{
BEGIN_SECAPI
Required(value) = Policy::required(policyRef)->value();
END_SECAPI
}
OSStatus
SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value)
{
BEGIN_SECAPI
Required(value);
const CssmData newValue(value->Data, value->Length);
Policy::required(policyRef)->setValue(newValue);
END_SECAPI
}
OSStatus
SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE* tpHandle)
{
BEGIN_SECAPI
Required(tpHandle) = Policy::required(policyRef)->tp()->handle();
END_SECAPI
}
OSStatus
SecPolicyCopyAll(CSSM_CERT_TYPE certificateType, CFArrayRef* policies)
{
BEGIN_SECAPI
Required(policies);
CFMutableArrayRef currPolicies = NULL;
currPolicies = CFArrayCreateMutable(NULL, 0, NULL);
if ( currPolicies )
{
SecPointer<PolicyCursor> cursor(new PolicyCursor(NULL, NULL));
SecPointer<Policy> policy;
while ( cursor->next(policy) )
{
CFArrayAppendValue(currPolicies, policy->handle());
CFRelease(policy->handle());
}
*policies = CFArrayCreateCopy(NULL, currPolicies);
CFRelease(currPolicies);
CFRelease(cursor->handle());
}
END_SECAPI
}
OSStatus
SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPolicyRef* policy)
{
Required(policy);
Required(policyOID);
SecPolicySearchRef srchRef = NULL;
OSStatus ortn;
ortn = SecPolicySearchCreate(certificateType, policyOID, NULL, &srchRef);
if(ortn) {
return ortn;
}
ortn = SecPolicySearchCopyNext(srchRef, policy);
CFRelease(srchRef);
return ortn;
}
SecPolicyRef
SecPolicyCreateBasicX509(void)
{
SecPolicyRef policy = nil;
SecPolicySearchRef policySearch = nil;
OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &policySearch);
if (!status) {
status = SecPolicySearchCopyNext(policySearch, &policy);
}
if (policySearch) {
CFRelease(policySearch);
}
return policy;
}
SecPolicyRef
SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
{
SecPolicyRef policy = nil;
SecPolicySearchRef policySearch = nil;
OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, NULL, &policySearch);
if (!status) {
status = SecPolicySearchCopyNext(policySearch, &policy);
}
if (!status && policy) {
char *strbuf = NULL;
const char *hostnamestr = NULL;
if (hostname) {
CFIndex strbuflen = 0;
hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8);
if (hostnamestr == NULL) {
strbuflen = CFStringGetLength(hostname)*6;
strbuf = (char *)malloc(strbuflen+1);
if (CFStringGetCString(hostname, strbuf, strbuflen, kCFStringEncodingUTF8)) {
hostnamestr = strbuf;
}
}
}
uint32 hostnamelen = (hostnamestr) ? strlen(hostnamestr) : 0;
uint32 flags = (!server) ? CSSM_APPLE_TP_SSL_CLIENT : 0;
CSSM_APPLE_TP_SSL_OPTIONS opts = {CSSM_APPLE_TP_SSL_OPTS_VERSION, hostnamelen, hostnamestr, flags};
CSSM_DATA data = {sizeof(opts), (uint8*)&opts};
SecPolicySetValue(policy, &data);
if (strbuf) {
free(strbuf);
}
}
if (policySearch) {
CFRelease(policySearch);
}
return policy;
}