#include "csutilities.h"
#include <Security/SecCertificatePriv.h>
#include <security_codesigning/requirement.h>
#include <security_utilities/debugging.h>
#include <security_utilities/errors.h>
namespace Security {
namespace CodeSigning {
void hashOfCertificate(const void *certData, size_t certLength, SHA1::Digest digest)
{
SHA1 hasher;
hasher(certData, certLength);
hasher.finish(digest);
}
void hashOfCertificate(SecCertificateRef cert, SHA1::Digest digest)
{
assert(cert);
CSSM_DATA certData;
MacOSError::check(SecCertificateGetData(cert, &certData));
hashOfCertificate(certData.Data, certData.Length, digest);
}
bool certificateHasField(SecCertificateRef cert, const CssmOid &oid)
{
assert(cert);
CSSM_DATA *value;
switch (OSStatus rc = SecCertificateCopyFirstFieldValue(cert, &oid, &value)) {
case noErr:
MacOSError::check(SecCertificateReleaseFirstFieldValue(cert, &oid, value));
return true; case errSecUnknownTag:
break; default:
MacOSError::throwMe(rc); }
CSSM_DATA **values;
bool found = false;
if (SecCertificateCopyFieldValues(cert, &CSSMOID_X509V3CertificateExtensionCStruct, &values))
return false; if (values)
for (CSSM_DATA **p = values; *p; p++) {
const CSSM_X509_EXTENSION *ext = (const CSSM_X509_EXTENSION *)(*p)->Data;
if (oid == ext->extnId) {
found = true;
break;
}
}
MacOSError::check(SecCertificateReleaseFieldValues(cert, &CSSMOID_X509V3CertificateExtensionCStruct, values));
return found;
}
bool certificateHasPolicy(SecCertificateRef cert, const CssmOid &policyOid)
{
bool matched = false;
assert(cert);
CSSM_DATA *data;
if (OSStatus rc = SecCertificateCopyFirstFieldValue(cert, &CSSMOID_CertificatePolicies, &data))
MacOSError::throwMe(rc);
if (data && data->Data && data->Length == sizeof(CSSM_X509_EXTENSION)) {
const CSSM_X509_EXTENSION *ext = (const CSSM_X509_EXTENSION *)data->Data;
assert(ext->format == CSSM_X509_DATAFORMAT_PARSED);
const CE_CertPolicies *policies = (const CE_CertPolicies *)ext->value.parsedValue;
if (policies)
for (unsigned int n = 0; n < policies->numPolicies; n++) {
const CE_PolicyInformation &cp = policies->policies[n];
if (cp.certPolicyId == policyOid) {
matched = true;
break;
}
}
}
SecCertificateReleaseFirstFieldValue(cert, &CSSMOID_PolicyConstraints, data);
return matched;
}
Copyfile::Copyfile()
{
if (!(mState = copyfile_state_alloc()))
UnixError::throwMe();
}
void Copyfile::set(uint32_t flag, const void *value)
{
check(::copyfile_state_set(mState, flag, value));
}
void Copyfile::get(uint32_t flag, void *value)
{
check(::copyfile_state_set(mState, flag, value));
}
void Copyfile::operator () (const char *src, const char *dst, copyfile_flags_t flags)
{
check(::copyfile(src, dst, mState, flags));
}
void Copyfile::check(int rc)
{
if (rc < 0)
UnixError::throwMe();
}
} }