void DRMaker::nonAppleAnchor() { // get the Organization DN element for the leaf CFRef<CFStringRef> leafOrganization; MacOSError::check(SecCertificateCopySubjectComponent(ctx.cert(Requirement::leafCert), &CSSMOID_OrganizationName, &leafOrganization.aref())); // now step up the cert chain looking for the first cert with a different one int slot = Requirement::leafCert; // start at leaf if (leafOrganization) { while (SecCertificateRef ca = ctx.cert(slot+1)) { // NULL if you over-run the anchor slot CFRef<CFStringRef> caOrganization; MacOSError::check(SecCertificateCopySubjectComponent(ca, &CSSMOID_OrganizationName, &caOrganization.aref())); if (!caOrganization || CFStringCompare(leafOrganization, caOrganization, 0) != kCFCompareEqualTo) break; slot++; } if (slot == ctx.certCount() - 1) // went all the way to the anchor... slot = Requirement::anchorCert; // ... so say that } // nail the last cert with the leaf's Organization value SHA1::Digest authorityHash; hashOfCertificate(ctx.cert(slot), authorityHash); this->anchor(slot, authorityHash); }
// // Ditto, given a SecCertificateRef // void hashOfCertificate(SecCertificateRef cert, SHA1::Digest digest) { assert(cert); CSSM_DATA certData; MacOSError::check(SecCertificateGetData(cert, &certData)); hashOfCertificate(certData.Data, certData.Length, digest); }
// // Generate the default (implicit) Designated Requirement for this StaticCode. // This is a heuristic of sorts, and may change over time (for the better, we hope). // Requirement *DRMaker::make() { // we can't make an explicit DR for a (proposed) ad-hoc signing because that requires the CodeDirectory (which we ain't got yet) if (ctx.certCount() == 0) return NULL; // always require the identifier this->put(opAnd); this->ident(ctx.identifier); SHA1::Digest anchorHash; hashOfCertificate(ctx.cert(Requirement::anchorCert), anchorHash); if (!memcmp(anchorHash, Requirement::appleAnchorHash(), SHA1::digestLength) #if defined(TEST_APPLE_ANCHOR) || !memcmp(anchorHash, Requirement::testAppleAnchorHash(), SHA1::digestLength) #endif ) appleAnchor(); else nonAppleAnchor(); return Maker::make(); }
// // One-stop hash-certificate-and-compare // bool verifyHash(SecCertificateRef cert, const Hashing::Byte *digest) { SHA1::Digest dig; hashOfCertificate(cert, dig); return !memcmp(dig, digest, SHA1::digestLength); }