/* * Obtain an array of the certificates in a timestamp response. Elements of the * returned array are SecCertificateRefs. The caller must CFRelease the returned * array. This timestamp is an authenticated timestamp provided by * a timestamping authority. * * Returns errSecParam if the CMS message was not signed or if signerIndex * is greater than the number of signers of the message minus one. It returns * errSecItemNotFound if no certificates were found. * * This cannot be called until after CMSDecoderFinalizeMessage() is called. */ OSStatus CMSDecoderCopySignerTimestampCertificates( CMSDecoderRef cmsDecoder, size_t signerIndex, /* usually 0 */ CFArrayRef *certificateRefs) /* RETURNED */ { OSStatus status = errSecParam; SecCmsMessageRef cmsg = NULL; SecCmsSignedDataRef signedData = NULL; int numContentInfos = 0; CFIndex tsn = 0; bool good = false; require(cmsDecoder && certificateRefs, xit); require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit); numContentInfos = SecCmsMessageContentLevelCount(cmsg); for (int dex = 0; !signedData && dex < numContentInfos; dex++) { SecCmsContentInfoRef ci = SecCmsMessageContentLevel(cmsg, dex); SECOidTag tag = SecCmsContentInfoGetContentTypeTag(ci); if (tag == SEC_OID_PKCS7_SIGNED_DATA) if ((signedData = SecCmsSignedDataRef(SecCmsContentInfoGetContent(ci)))) if (SecCmsSignerInfoRef signerInfo = SecCmsSignedDataGetSignerInfo(signedData, (int)signerIndex)) { CFArrayRef certList = SecCmsSignerInfoGetTimestampCertList(signerInfo); require_action(certList, xit, status = errSecItemNotFound); CFMutableArrayRef certs = CFArrayCreateMutableCopy(kCFAllocatorDefault, CFArrayGetCount(certList), certList); if(certs){ //reorder certificates: tsn = CFArrayGetCount(certs); good = tsn > 0 && Security::CodeSigning::isAppleCA(SecCertificateRef(CFArrayGetValueAtIndex(certs, tsn-1))); if ( good == false ) { //change TS certificate ordering. for (CFIndex n = 0; n < tsn; n++) { if (SecCertificateRef tsRoot = SecCertificateRef(CFArrayGetValueAtIndex(certs, n))) if ((good = Security::CodeSigning::isAppleCA(tsRoot))) { CFArrayExchangeValuesAtIndices(certs, n, tsn-1); break; } } } *certificateRefs = CFArrayCreateCopy(kCFAllocatorDefault, certs); CFRelease(certs); status = errSecSuccess; } break; } } xit: return status; }
// // Fill in extra information about the originator of cryptographic credentials found - if any // void PolicyEngine::setOrigin(CFArrayRef chain, CFMutableDictionaryRef result) { if (chain) if (CFArrayGetCount(chain) > 0) if (SecCertificateRef leaf = SecCertificateRef(CFArrayGetValueAtIndex(chain, 0))) if (CFStringRef summary = SecCertificateCopyLongDescription(NULL, leaf, NULL)) { CFDictionarySetValue(result, kSecAssessmentAssessmentOriginator, summary); CFRelease(summary); } }
// // Retrieve one certificate from the cert chain. // Positive and negative indices can be used: // [ leaf, intermed-1, ..., intermed-n, anchor ] // 0 1 ... -2 -1 // Returns NULL if unavailable for any reason. // SecCertificateRef Requirement::Context::cert(int ix) const { if (certs) { if (ix < 0) ix += certCount(); if (ix >= CFArrayGetCount(certs)) return NULL; if (CFTypeRef element = CFArrayGetValueAtIndex(certs, ix)) return SecCertificateRef(element); } return NULL; }