]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_smime/lib/CMSEncoder.c
Security-59306.41.2.tar.gz
[apple/security.git] / libsecurity_smime / lib / CMSEncoder.c
index 44d1dd0c0320d60930b200260fe912645e5bd1e3..8fc6d1d9ec546fb09ab04f3f194da6145214d1c3 100644 (file)
@@ -25,7 +25,8 @@
  * CMSEncoder.c - encode, sign, and/or encrypt CMS messages.
  */
 
-#include "CMSEncoder.h"
+#include <Security/CMSEncoder.h>
+#include <Security/CMSPrivate.h>
 #include "CMSUtils.h"
 #include <Security/SecBase.h>
 #include <Security/SecCmsEncoder.h>
@@ -98,6 +99,7 @@ struct _CMSEncoder {
     CMSCertificateChainMode chainMode;
     CFDataRef           hashAgilityAttrValue;
     CFDictionaryRef     hashAgilityV2AttrValues;
+    CFAbsoluteTime      expirationTime;
 };
 
 static void cmsEncoderInit(CFTypeRef enc);
@@ -280,12 +282,20 @@ static int convertOid(
         // 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
@@ -452,6 +462,9 @@ static OSStatus cmsSetupForSignedData(
         case kCMSCertificateChainWithRoot:
             chainMode = SecCmsCMCertChainWithRoot;
             break;
+        case kCMSCertificateChainWithRootOrFail:
+            chainMode = SecCmsCMCertChainWithRootOrFail;
+            break;
         default:
             break;
     }
@@ -537,6 +550,14 @@ static OSStatus cmsSetupForSignedData(
                 break;
             }
         }
+        if (cmsEncoder->signedAttributes & kCMSAttrAppleExpirationTime) {
+            ortn = SecCmsSignerInfoAddAppleExpirationTime(signerInfo, cmsEncoder->expirationTime);
+            if(ortn) {
+                ortn = cmsRtnToOSStatus(ortn);
+                CSSM_PERROR("SecCmsSignerInfoAddAppleExpirationTime", ortn);
+                break;
+            }
+        }
 
         CFRELEASE(ourCert);
         ourCert = NULL;
@@ -1035,6 +1056,24 @@ OSStatus CMSEncoderSetAppleCodesigningHashAgilityV2(
     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)
@@ -1050,6 +1089,7 @@ OSStatus CMSEncoderSetCertificateChainMode(
         case kCMSCertificateSignerOnly:
         case kCMSCertificateChain:
         case kCMSCertificateChainWithRoot:
+        case kCMSCertificateChainWithRootOrFail:
             break;
         default:
             return errSecParam;