]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_cms/lib/CMSEncoder.cpp
Security-59306.61.1.tar.gz
[apple/security.git] / OSX / libsecurity_cms / lib / CMSEncoder.cpp
index c60110c7af64109f9e9207f5d549912050481e44..27d6810dacc5626d29b60c7363f84c8b2ba46665 100644 (file)
@@ -25,8 +25,8 @@
  * CMSEncoder.cpp - encode, sign, and/or encrypt CMS messages. 
  */
  
  * 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>
 #include "CMSUtils.h"
 #include <Security/SecBase.h>
 #include <Security/SecCmsEncoder.h>
@@ -47,6 +47,7 @@
 #include <Security/SecAsn1Templates.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <pthread.h>
 #include <Security/SecAsn1Templates.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <pthread.h>
+#include <utilities/SecCFRelease.h>
 
 #include <security_smime/tsaSupport.h>
 #include <security_smime/cmspriv.h>
 
 #include <security_smime/tsaSupport.h>
 #include <security_smime/cmspriv.h>
@@ -96,6 +97,9 @@ struct _CMSEncoder {
        SECOidTag               digestalgtag;
 
        CMSCertificateChainMode chainMode;
        SECOidTag               digestalgtag;
 
        CMSCertificateChainMode chainMode;
+    CFDataRef           hashAgilityAttrValue;
+    CFDictionaryRef     hashAgilityV2AttrValues;
+    CFAbsoluteTime      expirationTime;
 };
 
 static void cmsEncoderInit(CFTypeRef enc);
 };
 
 static void cmsEncoderInit(CFTypeRef enc);
@@ -243,12 +247,12 @@ static int encodeOid(
                for(digit=0; digit<numsToProcess; digit++) {
                        free(digits[digit]);
                }
                for(digit=0; digit<numsToProcess; digit++) {
                        free(digits[digit]);
                }
-               free(digits);
-               free(numDigits);
        }
        result = 0;
 
 cleanExit:
        }
        result = 0;
 
 cleanExit:
+    if (digits) free(digits);
+    if (numDigits) free(numDigits);
        if (oidStr) CFRelease(oidStr);
        if (argvRef) CFRelease(argvRef);
 
        if (oidStr) CFRelease(oidStr);
        if (argvRef) CFRelease(argvRef);
 
@@ -277,12 +281,20 @@ static int convertOid(
                // CFStringRef: OID representation is a dotted-decimal string
                CFStringRef inStr = (CFStringRef)inRef;
                CFIndex max = CFStringGetLength(inStr) * 3;
                // 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;
                        return errSecParam;
+               }
 
 
-               if(encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0)
+               if (encodeOid((unsigned char *)buf, &oidData, &oidLen) != 0) {
+                       free(buf);
                        return errSecParam;
                        return errSecParam;
+               }
+               free(buf);
        }
        else if (CFGetTypeID(inRef) == CFDataGetTypeID()) {
                // CFDataRef: OID representation is in binary DER format
        }
        else if (CFGetTypeID(inRef) == CFDataGetTypeID()) {
                // CFDataRef: OID representation is in binary DER format
@@ -334,6 +346,7 @@ static void cmsEncoderFinalize(
        CFRELEASE(cmsEncoder->otherCerts);
        if(cmsEncoder->cmsMsg != NULL) {
                SecCmsMessageDestroy(cmsEncoder->cmsMsg);
        CFRELEASE(cmsEncoder->otherCerts);
        if(cmsEncoder->cmsMsg != NULL) {
                SecCmsMessageDestroy(cmsEncoder->cmsMsg);
+               cmsEncoder->cmsMsg = NULL;
        }
        if(cmsEncoder->arena != NULL) {
                SecArenaPoolFree(cmsEncoder->arena, false);
        }
        if(cmsEncoder->arena != NULL) {
                SecArenaPoolFree(cmsEncoder->arena, false);
@@ -442,7 +455,6 @@ static OSStatus cmsSetupForSignedData(
                numSigners = CFArrayGetCount(cmsEncoder->signers);
        }
        CFIndex dex;
                numSigners = CFArrayGetCount(cmsEncoder->signers);
        }
        CFIndex dex;
-       SecKeychainRef ourKc = NULL;
        SecCertificateRef ourCert = NULL;
        SecCmsCertChainMode chainMode = SecCmsCMCertChain;
 
        SecCertificateRef ourCert = NULL;
        SecCmsCertChainMode chainMode = SecCmsCMCertChain;
 
@@ -456,6 +468,9 @@ static OSStatus cmsSetupForSignedData(
                case kCMSCertificateChainWithRoot:
                        chainMode = SecCmsCMCertChainWithRoot;
                        break;
                case kCMSCertificateChainWithRoot:
                        chainMode = SecCmsCMCertChainWithRoot;
                        break;
+               case kCMSCertificateChainWithRootOrFail:
+                       chainMode = SecCmsCMCertChainWithRootOrFail;
+                       break;
                default:
                        break;
        }
                default:
                        break;
        }
@@ -469,11 +484,6 @@ static OSStatus cmsSetupForSignedData(
                        CSSM_PERROR("SecIdentityCopyCertificate", ortn);
                        break;
                }
                        CSSM_PERROR("SecIdentityCopyCertificate", ortn);
                        break;
                }
-               ortn = SecKeychainItemCopyKeychain((SecKeychainItemRef)ourCert, &ourKc);
-               if(ortn) {
-                       CSSM_PERROR("SecKeychainItemCopyKeychain", ortn);
-                       break;
-               }
                signerInfo = SecCmsSignerInfoCreate(cmsEncoder->cmsMsg, ourId, cmsEncoder->digestalgtag);
                if (signerInfo == NULL) {
                        ortn = errSecInternalComponent;
                signerInfo = SecCmsSignerInfoCreate(cmsEncoder->cmsMsg, ourId, cmsEncoder->digestalgtag);
                if (signerInfo == NULL) {
                        ortn = errSecInternalComponent;
@@ -500,7 +510,7 @@ static OSStatus cmsSetupForSignedData(
                        }
                }
                if(cmsEncoder->signedAttributes & kCMSAttrSmimeEncryptionKeyPrefs) {
                        }
                }
                if(cmsEncoder->signedAttributes & kCMSAttrSmimeEncryptionKeyPrefs) {
-                       ortn = SecCmsSignerInfoAddSMIMEEncKeyPrefs(signerInfo, ourCert, ourKc);
+                       ortn = SecCmsSignerInfoAddSMIMEEncKeyPrefs(signerInfo, ourCert, NULL);
                        if(ortn) {
                                ortn = cmsRtnToOSStatus(ortn);
                                CSSM_PERROR("SecCmsSignerInfoAddSMIMEEncKeyPrefs", ortn);
                        if(ortn) {
                                ortn = cmsRtnToOSStatus(ortn);
                                CSSM_PERROR("SecCmsSignerInfoAddSMIMEEncKeyPrefs", ortn);
@@ -508,7 +518,7 @@ static OSStatus cmsSetupForSignedData(
                        }
                }
                if(cmsEncoder->signedAttributes & kCMSAttrSmimeMSEncryptionKeyPrefs) {
                        }
                }
                if(cmsEncoder->signedAttributes & kCMSAttrSmimeMSEncryptionKeyPrefs) {
-                       ortn = SecCmsSignerInfoAddMSSMIMEEncKeyPrefs(signerInfo, ourCert, ourKc);
+                       ortn = SecCmsSignerInfoAddMSSMIMEEncKeyPrefs(signerInfo, ourCert, NULL);
                        if(ortn) {
                                ortn = cmsRtnToOSStatus(ortn);
                                CSSM_PERROR("SecCmsSignerInfoAddMSSMIMEEncKeyPrefs", ortn);
                        if(ortn) {
                                ortn = cmsRtnToOSStatus(ortn);
                                CSSM_PERROR("SecCmsSignerInfoAddMSSMIMEEncKeyPrefs", ortn);
@@ -525,6 +535,34 @@ static OSStatus cmsSetupForSignedData(
                                break;
                        }
                }
                                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;
+            }
+        }
+        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) {
                
                ortn = SecCmsSignedDataAddSignerInfo(signedData, signerInfo);
                if(ortn) {
@@ -533,13 +571,10 @@ static OSStatus cmsSetupForSignedData(
                        break;
                }
 
                        break;
                }
 
-               CFRELEASE(ourKc);
                CFRELEASE(ourCert);
                CFRELEASE(ourCert);
-               ourKc = NULL;
                ourCert = NULL;
        }
        if(ortn) {
                ourCert = NULL;
        }
        if(ortn) {
-               CFRELEASE(ourKc);
                CFRELEASE(ourCert);
        }
        return ortn;
                CFRELEASE(ourCert);
        }
        return ortn;
@@ -982,7 +1017,7 @@ OSStatus CMSEncoderAddSignedAttributes(
        if(cmsEncoder->encState != ES_Init) {
                return errSecParam;
        }
        if(cmsEncoder->encState != ES_Init) {
                return errSecParam;
        }
-       cmsEncoder->signedAttributes = signedAttributes;
+       cmsEncoder->signedAttributes |= signedAttributes;
        return errSecSuccess;
 }
 
        return errSecSuccess;
 }
 
@@ -1004,6 +1039,55 @@ OSStatus CMSEncoderSetSigningTime(
        return errSecSuccess;
 }
 
        return errSecSuccess;
 }
 
+/*
+ * Set the hash agility attribute for a CMSEncoder.
+ * This is only used if the kCMSAttrAppleCodesigningHashAgility attribute
+ * is included.
+ */
+OSStatus CMSEncoderSetAppleCodesigningHashAgility(
+    CMSEncoderRef   cmsEncoder,
+    CFDataRef       hashAgilityAttrValue)
+{
+    if (cmsEncoder == NULL || cmsEncoder->encState != ES_Init) {
+        return errSecParam;
+    }
+    cmsEncoder->hashAgilityAttrValue = CFRetainSafe(hashAgilityAttrValue);
+    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,
 
 OSStatus CMSEncoderSetCertificateChainMode(
        CMSEncoderRef                   cmsEncoder,
@@ -1020,6 +1104,7 @@ OSStatus CMSEncoderSetCertificateChainMode(
                case kCMSCertificateSignerOnly:
                case kCMSCertificateChain:
                case kCMSCertificateChainWithRoot:
                case kCMSCertificateSignerOnly:
                case kCMSCertificateChain:
                case kCMSCertificateChainWithRoot:
+               case kCMSCertificateChainWithRootOrFail:
                        break;
                default:
                        return errSecParam;
                        break;
                default:
                        return errSecParam;