blob: 21892943aa98d67fcd8be68b467d32ec589e1573 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/cert/x509_util_mac.h"
#include "base/check_op.h"
namespace net {
// CSSM functions are deprecated as of OSX 10.7, but have no replacement.
// https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
namespace x509_util {
CSSMFieldValue::CSSMFieldValue()
: cl_handle_(CSSM_INVALID_HANDLE), oid_(nullptr), field_(nullptr) {}
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, nullptr, nullptr);
}
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 = nullptr;
CSSM_HANDLE results_handle = CSSM_INVALID_HANDLE;
uint32_t 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;
// Note: |field_value_count| may be > 1, indicating that more than one
// value is present. This may happen with extensions, but for current
// usages, only the first value is returned.
CSSM_CL_CertAbortQuery(cl_handle_, results_handle);
field->Reset(cl_handle_, oid, field_ptr);
return CSSM_OK;
}
} // namespace x509_util
#pragma clang diagnostic pop // "-Wdeprecated-declarations"
} // namespace net