This source file includes following definitions.
- CreatePolicy
- CreateSSLClientPolicy
- CreateSSLServerPolicy
- CreateBasicX509Policy
- CreateRevocationPolicies
- field_
- field_
- Reset
- cached_cert_handle_
- Init
- GetField
#include "net/cert/x509_util_mac.h"
#include "base/logging.h"
#include "third_party/apple_apsl/cssmapplePriv.h"
namespace net {
namespace x509_util {
namespace {
OSStatus CreatePolicy(const CSSM_OID* policy_oid,
void* option_data,
size_t option_length,
SecPolicyRef* policy) {
SecPolicySearchRef search;
OSStatus err = SecPolicySearchCreate(CSSM_CERT_X_509v3, policy_oid, NULL,
&search);
if (err)
return err;
err = SecPolicySearchCopyNext(search, policy);
CFRelease(search);
if (err)
return err;
if (option_data) {
CSSM_DATA options_data = {
option_length,
reinterpret_cast<uint8_t*>(option_data)
};
err = SecPolicySetValue(*policy, &options_data);
if (err) {
CFRelease(*policy);
return err;
}
}
return noErr;
}
}
OSStatus CreateSSLClientPolicy(SecPolicyRef* policy) {
CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options;
memset(&tp_ssl_options, 0, sizeof(tp_ssl_options));
tp_ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION;
tp_ssl_options.Flags |= CSSM_APPLE_TP_SSL_CLIENT;
return CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options,
sizeof(tp_ssl_options), policy);
}
OSStatus CreateSSLServerPolicy(const std::string& hostname,
SecPolicyRef* policy) {
CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options;
memset(&tp_ssl_options, 0, sizeof(tp_ssl_options));
tp_ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION;
if (!hostname.empty()) {
tp_ssl_options.ServerName = hostname.data();
tp_ssl_options.ServerNameLen = hostname.size();
}
return CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options,
sizeof(tp_ssl_options), policy);
}
OSStatus CreateBasicX509Policy(SecPolicyRef* policy) {
return CreatePolicy(&CSSMOID_APPLE_X509_BASIC, NULL, 0, policy);
}
OSStatus CreateRevocationPolicies(bool enable_revocation_checking,
bool enable_ev_checking,
CFMutableArrayRef policies) {
OSStatus status = noErr;
if (enable_ev_checking || enable_revocation_checking) {
CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options;
memset(&tp_crl_options, 0, sizeof(tp_crl_options));
tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION;
if (enable_revocation_checking)
tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET;
SecPolicyRef crl_policy;
status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options,
sizeof(tp_crl_options), &crl_policy);
if (status)
return status;
CFArrayAppendValue(policies, crl_policy);
CFRelease(crl_policy);
}
if (enable_revocation_checking || !enable_ev_checking) {
CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options;
memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options));
tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
if (enable_revocation_checking) {
tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT;
} else {
tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET |
CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE;
}
SecPolicyRef ocsp_policy;
status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, &tp_ocsp_options,
sizeof(tp_ocsp_options), &ocsp_policy);
if (status)
return status;
CFArrayAppendValue(policies, ocsp_policy);
CFRelease(ocsp_policy);
}
return status;
}
CSSMFieldValue::CSSMFieldValue()
: cl_handle_(CSSM_INVALID_HANDLE),
oid_(NULL),
field_(NULL) {
}
CSSMFieldValue::CSSMFieldValue(CSSM_CL_HANDLE cl_handle,
const CSSM_OID* oid,
CSSM_DATA_PTR field)
: cl_handle_(cl_handle),
oid_(const_cast<CSSM_OID_PTR>(oid)),
field_(field) {
}
CSSMFieldValue::~CSSMFieldValue() {
Reset(CSSM_INVALID_HANDLE, NULL, NULL);
}
void CSSMFieldValue::Reset(CSSM_CL_HANDLE cl_handle,
CSSM_OID_PTR oid,
CSSM_DATA_PTR field) {
if (cl_handle_ && oid_ && field_)
CSSM_CL_FreeFieldValue(cl_handle_, oid_, field_);
cl_handle_ = cl_handle;
oid_ = oid;
field_ = field;
}
CSSMCachedCertificate::CSSMCachedCertificate()
: cl_handle_(CSSM_INVALID_HANDLE),
cached_cert_handle_(CSSM_INVALID_HANDLE) {
}
CSSMCachedCertificate::~CSSMCachedCertificate() {
if (cl_handle_ && cached_cert_handle_)
CSSM_CL_CertAbortCache(cl_handle_, cached_cert_handle_);
}
OSStatus CSSMCachedCertificate::Init(SecCertificateRef os_cert_handle) {
DCHECK(!cl_handle_ && !cached_cert_handle_);
DCHECK(os_cert_handle);
CSSM_DATA cert_data;
OSStatus status = SecCertificateGetData(os_cert_handle, &cert_data);
if (status)
return status;
status = SecCertificateGetCLHandle(os_cert_handle, &cl_handle_);
if (status) {
DCHECK(!cl_handle_);
return status;
}
status = CSSM_CL_CertCache(cl_handle_, &cert_data, &cached_cert_handle_);
if (status)
DCHECK(!cached_cert_handle_);
return status;
}
OSStatus CSSMCachedCertificate::GetField(const CSSM_OID* field_oid,
CSSMFieldValue* field) const {
DCHECK(cl_handle_);
DCHECK(cached_cert_handle_);
CSSM_OID_PTR oid = const_cast<CSSM_OID_PTR>(field_oid);
CSSM_DATA_PTR field_ptr = NULL;
CSSM_HANDLE results_handle = CSSM_INVALID_HANDLE;
uint32 field_value_count = 0;
CSSM_RETURN status = CSSM_CL_CertGetFirstCachedFieldValue(
cl_handle_, cached_cert_handle_, oid, &results_handle,
&field_value_count, &field_ptr);
if (status)
return status;
CSSM_CL_CertAbortQuery(cl_handle_, results_handle);
field->Reset(cl_handle_, oid, field_ptr);
return CSSM_OK;
}
}
}