コード例 #1
0
/*
 * Dispose of a CMSDecoder. Called out from CFRelease().
 */
static void cmsDecoderFinalize(
                               CFTypeRef		dec)
{
	CMSDecoderRef cmsDecoder = (CMSDecoderRef)dec;
	if(cmsDecoder == NULL) {
		return;
	}
	if(cmsDecoder->decoder != NULL) {
		/*
		 * Normally this gets freed in SecCmsDecoderFinish - this is
		 * an error case.
		 * FIXME: SecCmsDecoderDestroy() appears to destroy the
		 * cmsMsg too! Plus there's a comment there re: a leak...
		 */
		SecCmsDecoderDestroy(cmsDecoder->decoder);
	}
	CFRELEASE(cmsDecoder->detachedContent);
	CFRELEASE(cmsDecoder->keychainOrArray);
	if(cmsDecoder->cmsMsg != NULL) {
		SecCmsMessageDestroy(cmsDecoder->cmsMsg);
	}
	if(cmsDecoder->arena != NULL) {
		SecArenaPoolFree(cmsDecoder->arena, false);
	}
}
コード例 #2
0
/*
 * Dispose of a CMSEncoder. Called out from CFRelease().
 */
static void cmsEncoderFinalize(
	CFTypeRef		enc)
{
	CMSEncoderRef cmsEncoder = (CMSEncoderRef)enc;
	if(cmsEncoder == NULL) {
		return;
	}
	if(cmsEncoder->eContentType.Data != NULL) {
		free(cmsEncoder->eContentType.Data);
	}
	CFRELEASE(cmsEncoder->signers);
	CFRELEASE(cmsEncoder->recipients);
	CFRELEASE(cmsEncoder->otherCerts);
	if(cmsEncoder->cmsMsg != NULL) {
		SecCmsMessageDestroy(cmsEncoder->cmsMsg);
		cmsEncoder->cmsMsg = NULL;
	}
	if(cmsEncoder->arena != NULL) {
		SecArenaPoolFree(cmsEncoder->arena, false);
	}
	if(cmsEncoder->encoder != NULL) {
		/* 
		 * Normally this gets freed in SecCmsEncoderFinish - this is 
		 * an error case.
		 */
		SecCmsEncoderDestroy(cmsEncoder->encoder);
	}
}
コード例 #3
0
void Download::Initialize (CFDataRef ticket,
						   SecureDownloadTrustSetupCallback setup,
						   void* setupContext,
						   SecureDownloadTrustEvaluateCallback evaluate,
						   void* evaluateContext)
{
	// decode the ticket
	SecCmsMessageRef cmsMessage = GetCmsMessageFromData (ticket);
	
	// get a policy
	SecPolicyRef policy = GetPolicy ();

	// parse the CMS message
	int contentLevelCount = SecCmsMessageContentLevelCount (cmsMessage);
	SecCmsSignedDataRef signedData;

	OSStatus result;
	
	int i = 0;
	while (i < contentLevelCount)
	{
		SecCmsContentInfoRef contentInfo = SecCmsMessageContentLevel (cmsMessage, i++);
		SECOidTag contentTypeTag = SecCmsContentInfoGetContentTypeTag (contentInfo);
		
		if (contentTypeTag != SEC_OID_PKCS7_SIGNED_DATA)
		{
			continue;
		}

		signedData = (SecCmsSignedDataRef) SecCmsContentInfoGetContent (contentInfo);
		if (signedData == NULL)
		{
			MacOSError::throwMe (errSecureDownloadInvalidTicket);
		}
		
		// import the certificates found in the cms message
		result = SecCmsSignedDataImportCerts (signedData, NULL, certUsageObjectSigner, true);
		if (result != 0)
		{
			MacOSError::throwMe (errSecureDownloadInvalidTicket);
		}
		
		int numberOfSigners = SecCmsSignedDataSignerInfoCount (signedData);
		int j;
		
		if (numberOfSigners == 0) // no signers?  This is a possible attack
		{
			MacOSError::throwMe (errSecureDownloadInvalidTicket);
		}
		
		for (j = 0; j < numberOfSigners; ++j)
		{
			SecTrustResultType resultType;
			
			// do basic verification of the message
			SecTrustRef trustRef;
			result = SecCmsSignedDataVerifySignerInfo (signedData, j, NULL, policy, &trustRef);
			
			// notify the user of the new trust ref
			if (setup != NULL)
			{
				SecureDownloadTrustCallbackResult tcResult = setup (trustRef, setupContext);
				switch (tcResult)
				{
					case kSecureDownloadDoNotEvaluateSigner:
						continue;
					
					case kSecureDownloadFailEvaluation:
						MacOSError::throwMe (errSecureDownloadInvalidTicket);
					
					case kSecureDownloadEvaluateSigner:
					break;
				}
			}
			
			if (result != 0)
			{
				MacOSError::throwMe (errSecureDownloadInvalidTicket);
			}
			
			result = SecTrustEvaluate (trustRef, &resultType);
			if (result != noErr)
			{
				MacOSError::throwMe (errSecureDownloadInvalidTicket);
			}
			
			if (evaluate != NULL)
			{
				resultType = evaluate (trustRef, resultType, evaluateContext);
			}
			
			GoOrNoGo (resultType);
		}
	}
	
	// extract the message 
	CSSM_DATA_PTR message = SecCmsMessageGetContent (cmsMessage);
	CFDataRef ticketData = CFDataCreateWithBytesNoCopy (NULL, message->Data, message->Length, kCFAllocatorNull);
	CheckCFThingForNULL (ticketData);
	
	ParseTicket (ticketData);

	// setup for hashing
	CC_SHA256_Init (&mSHA256Context);
	
	// clean up
	CFRelease (ticketData);
	SecCmsMessageDestroy (cmsMessage);
}
コード例 #4
0
/* 
 * Set up a SecCmsMessageRef for a EnvelopedData creation.
 */
static OSStatus cmsSetupForEnvelopedData(
	CMSEncoderRef		cmsEncoder)
{
	ASSERT(cmsEncoder->op == EO_Encrypt);
	ASSERT(cmsEncoder->recipients != NULL);
	
    SecCmsContentInfoRef contentInfo = NULL;
    SecCmsEnvelopedDataRef envelopedData = NULL;
	SECOidTag algorithmTag;
    int keySize;
	OSStatus ortn;

	/*
	 * Find encryption algorithm...unfortunately we need a NULL-terminated array
	 * of SecCertificateRefs for this.
	 */
	CFIndex numCerts = CFArrayGetCount(cmsEncoder->recipients);
	CFIndex dex;
	SecCertificateRef *certArray = (SecCertificateRef *)malloc(
		(numCerts+1) * sizeof(SecCertificateRef));

	for(dex=0; dex<numCerts; dex++) {
		certArray[dex] = (SecCertificateRef)CFArrayGetValueAtIndex(
			cmsEncoder->recipients, dex);
	}
	certArray[numCerts] = NULL;
	ortn = SecSMIMEFindBulkAlgForRecipients(certArray, &algorithmTag, &keySize);
	free(certArray);
	if(ortn) {
		CSSM_PERROR("SecSMIMEFindBulkAlgForRecipients", ortn);
		return ortn;
	}
	
    /* build chain of objects: message->envelopedData->data */
	if(cmsEncoder->cmsMsg != NULL) {
		SecCmsMessageDestroy(cmsEncoder->cmsMsg);
	}
	cmsEncoder->cmsMsg = SecCmsMessageCreate(NULL);
	if(cmsEncoder->cmsMsg == NULL) {
		return errSecInternalComponent;
	}
	envelopedData = SecCmsEnvelopedDataCreate(cmsEncoder->cmsMsg, 
		algorithmTag, keySize);
	if(envelopedData == NULL) {
		return errSecInternalComponent;
	}
	contentInfo = SecCmsMessageGetContentInfo(cmsEncoder->cmsMsg);
	ortn = SecCmsContentInfoSetContentEnvelopedData(cmsEncoder->cmsMsg, 
		contentInfo, envelopedData);
	if(ortn) {
		ortn = cmsRtnToOSStatus(ortn);
		CSSM_PERROR("SecCmsContentInfoSetContentEnvelopedData", ortn);
		return ortn;
	}
    contentInfo = SecCmsEnvelopedDataGetContentInfo(envelopedData);
	if(cmsEncoder->eContentType.Data != NULL) {
		/* Override the default ContentType of id-data */
		ortn = SecCmsContentInfoSetContentOther(cmsEncoder->cmsMsg, 
			contentInfo, 
			NULL,		/* data - provided to encoder, not here */
			FALSE,		/* detachedContent */
			&cmsEncoder->eContentType);
	}
	else {
		ortn = SecCmsContentInfoSetContentData(cmsEncoder->cmsMsg, 
			contentInfo, 
			NULL /* data - provided to encoder, not here */, 
			cmsEncoder->detachedContent);
	}
	if(ortn) {
		ortn = cmsRtnToOSStatus(ortn);
		CSSM_PERROR("SecCmsContentInfoSetContentData*", ortn);
		return ortn;
	}

    /* 
     * create & attach recipient information, one for each recipient
     */
	for(dex=0; dex<numCerts; dex++) {
		SecCmsRecipientInfoRef recipientInfo = NULL;
		
		SecCertificateRef thisRecip = (SecCertificateRef)CFArrayGetValueAtIndex(
			cmsEncoder->recipients, dex);
		recipientInfo = SecCmsRecipientInfoCreate(cmsEncoder->cmsMsg, thisRecip);
		ortn = SecCmsEnvelopedDataAddRecipient(envelopedData, recipientInfo);
		if(ortn) {
			ortn = cmsRtnToOSStatus(ortn);
			CSSM_PERROR("SecCmsEnvelopedDataAddRecipient", ortn);
			return ortn;
		}
	}
	return errSecSuccess;
}
コード例 #5
0
/* 
 * Set up a SecCmsMessageRef for a SignedData creation.
 */
static OSStatus cmsSetupForSignedData(
	CMSEncoderRef		cmsEncoder)
{
	ASSERT((cmsEncoder->signers != NULL) || (cmsEncoder->otherCerts != NULL));
	
    SecCmsContentInfoRef contentInfo = NULL;
    SecCmsSignedDataRef signedData = NULL;
	OSStatus ortn;

    /* build chain of objects: message->signedData->data */
	if(cmsEncoder->cmsMsg != NULL) {
		SecCmsMessageDestroy(cmsEncoder->cmsMsg);
	}
	cmsEncoder->cmsMsg = SecCmsMessageCreate(NULL);
	if(cmsEncoder->cmsMsg == NULL) {
		return errSecInternalComponent;
	}

	signedData = SecCmsSignedDataCreate(cmsEncoder->cmsMsg);
	if(signedData == NULL) {
		return errSecInternalComponent;
	}
	contentInfo = SecCmsMessageGetContentInfo(cmsEncoder->cmsMsg);
	ortn = SecCmsContentInfoSetContentSignedData(cmsEncoder->cmsMsg, contentInfo, 
			signedData);
	if(ortn) {
		return cmsRtnToOSStatus(ortn);
	}
    contentInfo = SecCmsSignedDataGetContentInfo(signedData);
	if(cmsEncoder->eContentType.Data != NULL) {
		/* Override the default eContentType of id-data */
		ortn = SecCmsContentInfoSetContentOther(cmsEncoder->cmsMsg, 
			contentInfo, 
			NULL,		/* data - provided to encoder, not here */
			cmsEncoder->detachedContent,
			&cmsEncoder->eContentType);
	}
	else {
		ortn = SecCmsContentInfoSetContentData(cmsEncoder->cmsMsg, 
			contentInfo, 
			NULL, /* data - provided to encoder, not here */
			cmsEncoder->detachedContent);
	}
	if(ortn) {
		ortn = cmsRtnToOSStatus(ortn);
		CSSM_PERROR("SecCmsContentInfoSetContent*", ortn);
		return ortn;
	}

	/* optional 'global' (per-SignedData) certs */
	if(cmsEncoder->otherCerts != NULL) {
		ortn = SecCmsSignedDataAddCertList(signedData, cmsEncoder->otherCerts);
		if(ortn) {
			ortn = cmsRtnToOSStatus(ortn);
			CSSM_PERROR("SecCmsSignedDataAddCertList", ortn);
			return ortn;
		}
	}
	
	/* SignerInfos, one per signer */
	CFIndex numSigners = 0;
	if(cmsEncoder->signers != NULL) {
		/* this is optional...in case we're just creating a cert bundle */
		numSigners = CFArrayGetCount(cmsEncoder->signers);
	}
	CFIndex dex;
	SecCertificateRef ourCert = NULL;
	SecCmsCertChainMode chainMode = SecCmsCMCertChain;

	switch(cmsEncoder->chainMode) {
		case kCMSCertificateNone:
			chainMode = SecCmsCMNone;
			break;
		case kCMSCertificateSignerOnly:
			chainMode = SecCmsCMCertOnly;
			break;
		case kCMSCertificateChainWithRoot:
			chainMode = SecCmsCMCertChainWithRoot;
			break;
		default:
			break;
	}
	for(dex=0; dex<numSigners; dex++) {
		SecCmsSignerInfoRef signerInfo;
		
		SecIdentityRef ourId = 
			(SecIdentityRef)CFArrayGetValueAtIndex(cmsEncoder->signers, dex);
		ortn = SecIdentityCopyCertificate(ourId, &ourCert);
		if(ortn) {
			CSSM_PERROR("SecIdentityCopyCertificate", ortn);
			break;
		}
		signerInfo = SecCmsSignerInfoCreate(cmsEncoder->cmsMsg, ourId, cmsEncoder->digestalgtag);
		if (signerInfo == NULL) {
			ortn = errSecInternalComponent;
			break;
		}

		/* we want the cert chain included for this one */
		/* NOTE the usage parameter is currently unused by the SMIME lib */
		ortn = SecCmsSignerInfoIncludeCerts(signerInfo, chainMode, 
			certUsageEmailSigner);
		if(ortn) {
			ortn = cmsRtnToOSStatus(ortn);
			CSSM_PERROR("SecCmsSignerInfoIncludeCerts", ortn);
			break;
		}
		
		/* other options */
		if(cmsEncoder->signedAttributes & kCMSAttrSmimeCapabilities) {
			ortn = SecCmsSignerInfoAddSMIMECaps(signerInfo);
			if(ortn) {
				ortn = cmsRtnToOSStatus(ortn);
				CSSM_PERROR("SecCmsSignerInfoAddSMIMEEncKeyPrefs", ortn);
				break;
			}
		}
		if(cmsEncoder->signedAttributes & kCMSAttrSmimeEncryptionKeyPrefs) {
			ortn = SecCmsSignerInfoAddSMIMEEncKeyPrefs(signerInfo, ourCert, NULL);
			if(ortn) {
				ortn = cmsRtnToOSStatus(ortn);
				CSSM_PERROR("SecCmsSignerInfoAddSMIMEEncKeyPrefs", ortn);
				break;
			}
		}
		if(cmsEncoder->signedAttributes & kCMSAttrSmimeMSEncryptionKeyPrefs) {
			ortn = SecCmsSignerInfoAddMSSMIMEEncKeyPrefs(signerInfo, ourCert, NULL);
			if(ortn) {
				ortn = cmsRtnToOSStatus(ortn);
				CSSM_PERROR("SecCmsSignerInfoAddMSSMIMEEncKeyPrefs", ortn);
				break;
			}
		}
		if(cmsEncoder->signedAttributes & kCMSAttrSigningTime) {
			if (cmsEncoder->signingTime == 0)
				cmsEncoder->signingTime = CFAbsoluteTimeGetCurrent();
			ortn = SecCmsSignerInfoAddSigningTime(signerInfo, cmsEncoder->signingTime);
			if(ortn) {
				ortn = cmsRtnToOSStatus(ortn);
				CSSM_PERROR("SecCmsSignerInfoAddSigningTime", ortn);
				break;
			}
		}
        if(cmsEncoder->signedAttributes & kCMSAttrAppleCodesigningHashAgility) {
            ortn = SecCmsSignerInfoAddAppleCodesigningHashAgility(signerInfo, cmsEncoder->hashAgilityAttrValue);
            /* libsecurity_smime made a copy of the attribute value. We don't need it anymore. */
            CFReleaseNull(cmsEncoder->hashAgilityAttrValue);
            if(ortn) {
                ortn = cmsRtnToOSStatus(ortn);
                CSSM_PERROR("SecCmsSignerInfoAddAppleCodesigningHashAgility", ortn);
                break;
            }
        }
		
		ortn = SecCmsSignedDataAddSignerInfo(signedData, signerInfo);
		if(ortn) {
			ortn = cmsRtnToOSStatus(ortn);
			CSSM_PERROR("SecCmsSignedDataAddSignerInfo", ortn);
			break;
		}

		CFRELEASE(ourCert);
		ourCert = NULL;
	}
	if(ortn) {
		CFRELEASE(ourCert);
	}
	return ortn;
}