コード例 #1
0
/*
 * SecCmsSignedDataCreateCertsOnly - create a certs-only SignedData.
 *
 * cert          - base certificates that will be included
 * include_chain - if true, include the complete cert chain for cert
 *
 * More certs and chains can be added via AddCertificate and AddCertChain.
 *
 * An error results in a return value of NULL and an error set.
 *
 * XXXX CRLs
 */
SecCmsSignedDataRef
SecCmsSignedDataCreateCertsOnly(SecCmsMessageRef cmsg, SecCertificateRef cert, Boolean include_chain)
{
    SecCmsSignedDataRef sigd;
    void *mark;
    PLArenaPool *poolp;
    OSStatus rv;

    poolp = cmsg->poolp;
    mark = PORT_ArenaMark(poolp);

    sigd = SecCmsSignedDataCreate(cmsg);
    if (sigd == NULL)
	goto loser;

    /* no signerinfos, thus no digestAlgorithms */

    /* but certs */
    if (include_chain) {
	rv = SecCmsSignedDataAddCertChain(sigd, cert);
    } else {
	rv = SecCmsSignedDataAddCertificate(sigd, cert);
    }
    if (rv != SECSuccess)
	goto loser;

    /* RFC2630 5.2 sez:
     * In the degenerate case where there are no signers, the
     * EncapsulatedContentInfo value being "signed" is irrelevant.  In this
     * case, the content type within the EncapsulatedContentInfo value being
     * "signed" should be id-data (as defined in section 4), and the content
     * field of the EncapsulatedContentInfo value should be omitted.
     */
    rv = SecCmsContentInfoSetContentData(cmsg, &(sigd->contentInfo), NULL, PR_TRUE);
    if (rv != SECSuccess)
	goto loser;

    PORT_ArenaUnmark(poolp, mark);
    return sigd;

loser:
    if (sigd)
	SecCmsSignedDataDestroy(sigd);
    PORT_ArenaRelease(poolp, mark);
    return NULL;
}
コード例 #2
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;
}