// // Generate the CMS signature for a (finished) CodeDirectory. // CFDataRef SecCodeSigner::Signer::signCodeDirectory(const CodeDirectory *cd) { assert(state.mSigner); CFRef<CFMutableDictionaryRef> defaultTSContext = NULL; // a null signer generates a null signature blob if (state.mSigner == SecIdentityRef(kCFNull)) return CFDataCreate(NULL, NULL, 0); // generate CMS signature CFRef<CMSEncoderRef> cms; MacOSError::check(CMSEncoderCreate(&cms.aref())); MacOSError::check(CMSEncoderSetCertificateChainMode(cms, kCMSCertificateChainWithRoot)); CMSEncoderAddSigners(cms, state.mSigner); MacOSError::check(CMSEncoderSetHasDetachedContent(cms, true)); if (signingTime) { MacOSError::check(CMSEncoderAddSignedAttributes(cms, kCMSAttrSigningTime)); MacOSError::check(CMSEncoderSetSigningTime(cms, signingTime)); } MacOSError::check(CMSEncoderUpdateContent(cms, cd, cd->length())); // Set up to call Timestamp server if requested if (state.mWantTimeStamp) { CFRef<CFErrorRef> error = NULL; defaultTSContext = SecCmsTSAGetDefaultContext(&error.aref()); if (error) MacOSError::throwMe(errSecDataNotAvailable); if (state.mNoTimeStampCerts || state.mTimestampService) { if (state.mTimestampService) CFDictionarySetValue(defaultTSContext, kTSAContextKeyURL, state.mTimestampService); if (state.mNoTimeStampCerts) CFDictionarySetValue(defaultTSContext, kTSAContextKeyNoCerts, kCFBooleanTrue); } CmsMessageSetTSAContext(cms, defaultTSContext); } CFDataRef signature; MacOSError::check(CMSEncoderCopyEncodedContent(cms, &signature)); return signature; }
/* * High-level, one-shot encoder function. */ OSStatus CMSEncode( CFTypeRef signers, CFTypeRef recipients, const CSSM_OID *eContentType, Boolean detachedContent, CMSSignedAttributes signedAttributes, const void *content, size_t contentLen, CFDataRef *encodedContent) /* RETURNED */ { if((signers == NULL) && (recipients == NULL)) { return errSecParam; } if(encodedContent == NULL) { return errSecParam; } CMSEncoderRef cmsEncoder; OSStatus ortn; /* set up the encoder */ ortn = CMSEncoderCreate(&cmsEncoder); if(ortn) { return ortn; } /* subsequent errors to errOut: */ if(signers) { ortn = CMSEncoderAddSigners(cmsEncoder, signers); if(ortn) { goto errOut; } } if(recipients) { ortn = CMSEncoderAddRecipients(cmsEncoder, recipients); if(ortn) { goto errOut; } } if(eContentType) { ortn = CMSEncoderSetEncapsulatedContentType(cmsEncoder, eContentType); if(ortn) { goto errOut; } } if(detachedContent) { ortn = CMSEncoderSetHasDetachedContent(cmsEncoder, detachedContent); if(ortn) { goto errOut; } } if(signedAttributes) { ortn = CMSEncoderAddSignedAttributes(cmsEncoder, signedAttributes); if(ortn) { goto errOut; } } /* GO */ ortn = CMSEncoderUpdateContent(cmsEncoder, content, contentLen); if(ortn) { goto errOut; } ortn = CMSEncoderCopyEncodedContent(cmsEncoder, encodedContent); errOut: CFRelease(cmsEncoder); return ortn; }