* CMSEncoder.cpp - encode, sign, and/or encrypt CMS messages.
*/
-#include "CMSEncoder.h"
-#include "CMSPrivate.h"
+#include <Security/CMSEncoder.h>
+#include <Security/CMSPrivate.h>
#include "CMSUtils.h"
#include <Security/SecBase.h>
#include <Security/SecCmsEncoder.h>
CMSCertificateChainMode chainMode;
CFDataRef hashAgilityAttrValue;
+ CFDictionaryRef hashAgilityV2AttrValues;
+ CFAbsoluteTime expirationTime;
};
static void cmsEncoderInit(CFTypeRef enc);
for(digit=0; digit<numsToProcess; digit++) {
free(digits[digit]);
}
- free(digits);
- free(numDigits);
}
result = 0;
cleanExit:
+ if (digits) free(digits);
+ if (numDigits) free(numDigits);
if (oidStr) CFRelease(oidStr);
if (argvRef) CFRelease(argvRef);
// CFStringRef: OID representation is a dotted-decimal string
CFStringRef inStr = (CFStringRef)inRef;
CFIndex max = CFStringGetLength(inStr) * 3;
- char buf[max];
- if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII))
+ char *buf = (char *)malloc(max);
+ if (!buf) {
+ return errSecMemoryError;
+ }
+ if (!CFStringGetCString(inStr, buf, max-1, kCFStringEncodingASCII)) {
+ free(buf);
return errSecParam;
+ }
- if(encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0)
+ if (encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0) {
+ free(buf);
return errSecParam;
+ }
+ free(buf);
}
else if (CFGetTypeID(inRef) == CFDataGetTypeID()) {
// CFDataRef: OID representation is in binary DER format
CFRELEASE(cmsEncoder->otherCerts);
if(cmsEncoder->cmsMsg != NULL) {
SecCmsMessageDestroy(cmsEncoder->cmsMsg);
+ cmsEncoder->cmsMsg = NULL;
}
if(cmsEncoder->arena != NULL) {
SecArenaPoolFree(cmsEncoder->arena, false);
case kCMSCertificateChainWithRoot:
chainMode = SecCmsCMCertChainWithRoot;
break;
+ case kCMSCertificateChainWithRootOrFail:
+ chainMode = SecCmsCMCertChainWithRootOrFail;
+ break;
default:
break;
}
break;
}
}
+ if(cmsEncoder->signedAttributes & kCMSAttrAppleCodesigningHashAgilityV2) {
+ ortn = SecCmsSignerInfoAddAppleCodesigningHashAgilityV2(signerInfo, cmsEncoder->hashAgilityV2AttrValues);
+ /* libsecurity_smime made a copy of the attribute value. We don't need it anymore. */
+ CFReleaseNull(cmsEncoder->hashAgilityV2AttrValues);
+ if(ortn) {
+ ortn = cmsRtnToOSStatus(ortn);
+ CSSM_PERROR("SecCmsSignerInfoAddAppleCodesigningHashAgilityV2", ortn);
+ break;
+ }
+ }
+ if (cmsEncoder->signedAttributes & kCMSAttrAppleExpirationTime) {
+ ortn = SecCmsSignerInfoAddAppleExpirationTime(signerInfo, cmsEncoder->expirationTime);
+ if(ortn) {
+ ortn = cmsRtnToOSStatus(ortn);
+ CSSM_PERROR("SecCmsSignerInfoAddAppleExpirationTime", ortn);
+ break;
+ }
+ }
ortn = SecCmsSignedDataAddSignerInfo(signedData, signerInfo);
if(ortn) {
return errSecSuccess;
}
+/*
+ * Set the hash agility attribute for a CMSEncoder.
+ * This is only used if the kCMSAttrAppleCodesigningHashAgilityV2 attribute
+ * is included.
+ */
+OSStatus CMSEncoderSetAppleCodesigningHashAgilityV2(
+ CMSEncoderRef cmsEncoder,
+ CFDictionaryRef hashAgilityV2AttrValues)
+{
+ if (cmsEncoder == NULL || cmsEncoder->encState != ES_Init) {
+ return errSecParam;
+ }
+ cmsEncoder->hashAgilityV2AttrValues = CFRetainSafe(hashAgilityV2AttrValues);
+ return errSecSuccess;
+}
+
+/*
+ * Set the expiration time for a CMSEncoder.
+ * This is only used if the kCMSAttrAppleExpirationTime attribute is included.
+ */
+OSStatus CMSEncoderSetAppleExpirationTime(
+ CMSEncoderRef cmsEncoder,
+ CFAbsoluteTime time)
+{
+ if(cmsEncoder == NULL) {
+ return errSecParam;
+ }
+ if(cmsEncoder->encState != ES_Init) {
+ return errSecParam;
+ }
+ cmsEncoder->expirationTime = time;
+ return errSecSuccess;
+}
+
OSStatus CMSEncoderSetCertificateChainMode(
CMSEncoderRef cmsEncoder,
CMSCertificateChainMode chainMode)
case kCMSCertificateSignerOnly:
case kCMSCertificateChain:
case kCMSCertificateChainWithRoot:
+ case kCMSCertificateChainWithRootOrFail:
break;
default:
return errSecParam;