]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_cms/lib/CMSDecoder.cpp
Security-55471.14.8.tar.gz
[apple/security.git] / libsecurity_cms / lib / CMSDecoder.cpp
index 93ccab3f3800bec97f4f47acc8d57708e81ee211..930c0c5ecb13c13582271dc053b15ca2f10ae9e4 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
- * 
+ *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
 /*
  * CMSDecoder.cpp - Interface for decoding CMS messages.
  */
+
 #include "CMSDecoder.h"
 #include "CMSPrivate.h"
 #include "CMSUtils.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <../libsecurity_codesigning/lib/csutilities.h>
 
 #include <Security/SecCmsDecoder.h>
 #include <Security/SecCmsEnvelopedData.h>
@@ -57,7 +57,7 @@ typedef enum {
 } CMSDecoderState;
 
 /*
- * Caller's CMSDecoderRef points to one of these. 
+ * Caller's CMSDecoderRef points to one of these.
  */
 struct _CMSDecoder {
        CFRuntimeBase           base;
@@ -67,7 +67,7 @@ struct _CMSDecoder {
        CFDataRef                       detachedContent;
        CFTypeRef                       keychainOrArray;        /* from CMSDecoderSetSearchKeychain() */
        
-       /* 
+       /*
         * The following are valid (and quiescent) after CMSDecoderFinalizeMessage().
         */
        SecCmsMessageRef        cmsMsg;
@@ -82,7 +82,7 @@ struct _CMSDecoder {
 static void cmsDecoderInit(CFTypeRef dec);
 static void cmsDecoderFinalize(CFTypeRef dec);
 
-static CFRuntimeClass cmsDecoderRuntimeClass = 
+static CFRuntimeClass cmsDecoderRuntimeClass =
 {
        0,                      /* version */
        "CMSDecoder",
@@ -102,8 +102,8 @@ static CFTypeID cmsDecoderTypeID = _kCFRuntimeNotATypeID;
 /* one time only class init, called via pthread_once() in CMSDecoderGetTypeID() */
 static void cmsDecoderClassInitialize(void)
 {
-       cmsDecoderTypeID = 
-               _CFRuntimeRegisterClass((const CFRuntimeClass * const)&cmsDecoderRuntimeClass);
+       cmsDecoderTypeID =
+    _CFRuntimeRegisterClass((const CFRuntimeClass * const)&cmsDecoderRuntimeClass);
 }
 
 /* init called out from _CFRuntimeCreateInstance() */
@@ -117,15 +117,15 @@ static void cmsDecoderInit(CFTypeRef dec)
  * Dispose of a CMSDecoder. Called out from CFRelease().
  */
 static void cmsDecoderFinalize(
-       CFTypeRef               dec)
+                               CFTypeRef               dec)
 {
        CMSDecoderRef cmsDecoder = (CMSDecoderRef)dec;
        if(cmsDecoder == NULL) {
                return;
        }
        if(cmsDecoder->decoder != NULL) {
-               /* 
-                * Normally this gets freed in SecCmsDecoderFinish - this is 
+               /*
+                * Normally this gets freed in SecCmsDecoderFinish - this is
                 * an error case.
                 * FIXME: SecCmsDecoderDestroy() appears to destroy the
                 * cmsMsg too! Plus there's a comment there re: a leak...
@@ -144,13 +144,13 @@ static void cmsDecoderFinalize(
 
 
 /*
- * Given detached content and a valid (decoded) SignedData, digest the detached 
- * content. This occurs at the later of {CMSDecoderFinalizeMessage() finding a 
- * SignedData when already have detachedContent, or CMSDecoderSetDetachedContent() 
+ * Given detached content and a valid (decoded) SignedData, digest the detached
+ * content. This occurs at the later of {CMSDecoderFinalizeMessage() finding a
+ * SignedData when already have detachedContent, or CMSDecoderSetDetachedContent()
  * when we already have a SignedData).
  */
 static OSStatus cmsDigestDetachedContent(
-       CMSDecoderRef cmsDecoder)
+                                         CMSDecoderRef cmsDecoder)
 {
        ASSERT((cmsDecoder->signedData != NULL) && (cmsDecoder->detachedContent != NULL));
        
@@ -160,12 +160,12 @@ static OSStatus cmsDigestDetachedContent(
        }
        SecCmsDigestContextRef digcx = SecCmsDigestContextStartMultiple(digestAlgorithms);
        if(digcx == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        CSSM_DATA **digests = NULL;
        
-       SecCmsDigestContextUpdate(digcx, CFDataGetBytePtr(cmsDecoder->detachedContent), 
-               CFDataGetLength(cmsDecoder->detachedContent));
+       SecCmsDigestContextUpdate(digcx, CFDataGetBytePtr(cmsDecoder->detachedContent),
+                              CFDataGetLength(cmsDecoder->detachedContent));
        /* note this frees the digest content regardless */
        OSStatus ortn = SecCmsDigestContextFinishMultiple(digcx, cmsDecoder->arena, &digests);
        if(ortn) {
@@ -197,32 +197,32 @@ CFTypeID CMSDecoderGetTypeID(void)
  * Create a CMSDecoder. Result must eventually be freed via CFRelease().
  */
 OSStatus CMSDecoderCreate(
-       CMSDecoderRef           *cmsDecoderOut) /* RETURNED */
+                          CMSDecoderRef                *cmsDecoderOut) /* RETURNED */
 {
        CMSDecoderRef cmsDecoder = NULL;
-
+    
        uint32_t extra = sizeof(*cmsDecoder) - sizeof(cmsDecoder->base);
        cmsDecoder = (CMSDecoderRef)_CFRuntimeCreateInstance(NULL, CMSDecoderGetTypeID(),
-               extra, NULL);
+                                                         extra, NULL);
        if(cmsDecoder == NULL) {
-               return memFullErr;
+               return errSecAllocate;
        }
        cmsDecoder->decState = DS_Init;
        *cmsDecoderOut = cmsDecoder;
-       return noErr;
+       return errSecSuccess;
 }
 
-/* 
+/*
  * Feed raw bytes of the message to be decoded into the decoder. Can be called
- * multiple times. 
+ * multiple times.
  */
 OSStatus CMSDecoderUpdateMessage(
-       CMSDecoderRef           cmsDecoder,
-       const void                      *msgBytes,
-       size_t                          msgBytesLen)
+                                 CMSDecoderRef         cmsDecoder,
+                                 const void                    *msgBytes,
+                                 size_t                                msgBytesLen)
 {
        if(cmsDecoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        
        OSStatus ortn;
@@ -235,8 +235,8 @@ OSStatus CMSDecoderUpdateMessage(
                        if(ortn) {
                                return cmsRtnToOSStatus(ortn);
                        }
-                       ortn = SecCmsDecoderCreate(cmsDecoder->arena, 
-                               NULL, NULL, NULL, NULL, NULL, NULL, &cmsDecoder->decoder);
+                       ortn = SecCmsDecoderCreate(cmsDecoder->arena,
+                                       NULL, NULL, NULL, NULL, NULL, NULL, &cmsDecoder->decoder);
                        if(ortn) {
                                ortn = cmsRtnToOSStatus(ortn);
                                CSSM_PERROR("SecCmsDecoderCreate", ortn);
@@ -244,18 +244,18 @@ OSStatus CMSDecoderUpdateMessage(
                        }
                        cmsDecoder->decState = DS_Updating;
                        break;
-               
+            
                case DS_Updating:
                        ASSERT(cmsDecoder->decoder != NULL);
                        break;
                        
                case DS_Final:
                        /* Too late for another update */
-                       return paramErr;
+                       return errSecParam;
                        
                default:
                        dprintf("CMSDecoderUpdateMessage: bad decState\n");
-                       return internalComponentErr;
+                       return errSecInternalComponent;
        }
        
        /* FIXME - CFIndex same size as size_t on 64bit? */
@@ -266,20 +266,20 @@ OSStatus CMSDecoderUpdateMessage(
        }
        return ortn;
 }
-       
-/* 
+
+/*
  * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming;
- * finish decoding the message. We parse the message as best we can, up to 
- * but not including verifying individual signerInfos. 
+ * finish decoding the message. We parse the message as best we can, up to
+ * but not including verifying individual signerInfos.
  */
 OSStatus CMSDecoderFinalizeMessage(
-       CMSDecoderRef           cmsDecoder)
+                                   CMSDecoderRef               cmsDecoder)
 {
        if(cmsDecoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Updating) {
-               return paramErr;
+               return errSecParam;
        }
        ASSERT(cmsDecoder->decoder != NULL);
        OSStatus ortn = SecCmsDecoderFinish(cmsDecoder->decoder, &cmsDecoder->cmsMsg);
@@ -305,8 +305,8 @@ OSStatus CMSDecoderFinalizeMessage(
                SECOidTag tag = SecCmsContentInfoGetContentTypeTag(ci);
                switch(tag) {
                        case SEC_OID_PKCS7_SIGNED_DATA:
-                               cmsDecoder->signedData = 
-                                       (SecCmsSignedDataRef)SecCmsContentInfoGetContent(ci);
+                               cmsDecoder->signedData =
+                (SecCmsSignedDataRef)SecCmsContentInfoGetContent(ci);
                                /* dig down one more layer for eContentType */
                                ci = SecCmsSignedDataGetContentInfo(cmsDecoder->signedData);
                                cmsDecoder->eContentType = SecCmsContentInfoGetContentTypeOID(ci);
@@ -317,13 +317,13 @@ OSStatus CMSDecoderFinalizeMessage(
                if(cmsDecoder->signedData != NULL) {
                        break;
                }
-                                       
+        
        }
        
        /* minimal processing of optional signedData... */
        if(cmsDecoder->signedData != NULL) {
                cmsDecoder->numSigners = (size_t)
-                       SecCmsSignedDataSignerInfoCount(cmsDecoder->signedData);
+        SecCmsSignedDataSignerInfoCount(cmsDecoder->signedData);
                if(cmsDecoder->detachedContent != NULL) {
                        /* time to calculate digests from detached content */
                        ortn = cmsDigestDetachedContent(cmsDecoder);
@@ -335,20 +335,20 @@ OSStatus CMSDecoderFinalizeMessage(
 /*
  * A signed CMS message optionally includes the data which was signed. If the
  * message does not include the signed data, caller specifies the signed data
- * (the "detached content") here. 
+ * (the "detached content") here.
  *
  * This can be called either before or after the actual decoding of the message
  * (via CMSDecoderUpdateMessage() and CMSDecoderFinalizeMessage()); the only
- * restriction is that, if detached content is required, this function must 
- * be called befoere successfully ascertaining the signature status via 
+ * restriction is that, if detached content is required, this function must
+ * be called befoere successfully ascertaining the signature status via
  * CMSDecoderCopySignerStatus().
  */
 OSStatus CMSDecoderSetDetachedContent(
-       CMSDecoderRef           cmsDecoder,
-       CFDataRef                       detachedContent)
+                                      CMSDecoderRef            cmsDecoder,
+                                      CFDataRef                        detachedContent)
 {
        if((cmsDecoder == NULL) || (detachedContent == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        cmsDecoder->detachedContent = detachedContent;
        CFRetain(detachedContent);
@@ -358,84 +358,84 @@ OSStatus CMSDecoderSetDetachedContent(
                ASSERT(cmsDecoder->decState == DS_Final);
                return cmsDigestDetachedContent(cmsDecoder);
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Obtain the detached content specified in CMSDecoderSetDetachedContent().
- * Returns a NULL detachedContent if no detached content has been specified. 
+ * Returns a NULL detachedContent if no detached content has been specified.
  * Caller must CFRelease() the result.
  */
 OSStatus CMSDecoderCopyDetachedContent(
-       CMSDecoderRef           cmsDecoder,
-       CFDataRef                       *detachedContent)               /* RETURNED */
+                                       CMSDecoderRef           cmsDecoder,
+                                       CFDataRef                       *detachedContent)               /* RETURNED */
 {
        if((cmsDecoder == NULL) || (detachedContent == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->detachedContent != NULL) {
                CFRetain(cmsDecoder->detachedContent);
        }
        *detachedContent = cmsDecoder->detachedContent;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Optionally specify a SecKeychainRef, or an array of them, containing
  * intermediate certs to be used in verifying a signed message's signer
- * certs. By default, the default keychain search list is used for this. 
+ * certs. By default, the default keychain search list is used for this.
  * Specify an empty CFArrayRef to search *no* keychains for intermediate
- * certs. 
+ * certs.
  * IF this is called, it must be called before CMSDecoderCopySignerStatus().
  */
 OSStatus CMSDecoderSetSearchKeychain(
-       CMSDecoderRef           cmsDecoder,
-       CFTypeRef                       keychainOrArray)
+                                     CMSDecoderRef             cmsDecoder,
+                                     CFTypeRef                 keychainOrArray)
 {
        if(cmsDecoder == NULL) {
-               return paramErr;
+               return errSecParam;
        }
        cmsDecoder->keychainOrArray = keychainOrArray;
        if(keychainOrArray) {
                CFRetain(keychainOrArray);
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Obtain the number of signers of a message. A result of zero indicates that
- * the message was not signed. 
+ * the message was not signed.
  */
 OSStatus CMSDecoderGetNumSigners(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          *numSigners)                    /* RETURNED */
+                                 CMSDecoderRef         cmsDecoder,
+                                 size_t                                *numSigners)                    /* RETURNED */
 {
        if((cmsDecoder == NULL) || (numSigners == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Final) {
-               return paramErr;
+               return errSecParam;
        }
        *numSigners = cmsDecoder->numSigners;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
- * Obtain the status of a CMS message's signature. A CMS message can 
+ * Obtain the status of a CMS message's signature. A CMS message can
  * be signed my multiple signers; this function returns the status
- * associated with signer 'n' as indicated by the signerIndex parameter. 
+ * associated with signer 'n' as indicated by the signerIndex parameter.
  */
 OSStatus CMSDecoderCopySignerStatus(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,
-       CFTypeRef                       policyOrArray,
-       Boolean                         evaluateSecTrust,
-       CMSSignerStatus         *signerStatus,                  /* optional; RETURNED */
-       SecTrustRef                     *secTrust,                              /* optional; RETURNED */
-       OSStatus                        *certVerifyResultCode)  /* optional; RETURNED */
+                                    CMSDecoderRef              cmsDecoder,
+                                    size_t                             signerIndex,
+                                    CFTypeRef                  policyOrArray,
+                                    Boolean                            evaluateSecTrust,
+                                    CMSSignerStatus            *signerStatus,                  /* optional; RETURNED */
+                                    SecTrustRef                        *secTrust,                              /* optional; RETURNED */
+                                    OSStatus                   *certVerifyResultCode)  /* optional; RETURNED */
 {
        if((cmsDecoder == NULL) || (cmsDecoder->decState != DS_Final)) {
-               return paramErr;
+               return errSecParam;
        }
        
        /* initialize return values */
@@ -451,45 +451,45 @@ OSStatus CMSDecoderCopySignerStatus(
        
        if(cmsDecoder->signedData == NULL) {
                *signerStatus = kCMSSignerUnsigned;     /* redundant, I know, but explicit */
-               return noErr;
+               return errSecSuccess;
        }
        ASSERT(cmsDecoder->numSigners > 0);
        if(signerIndex >= cmsDecoder->numSigners) {
                *signerStatus = kCMSSignerInvalidIndex;
-               return noErr;
+               return errSecSuccess;
        }
        if(!SecCmsSignedDataHasDigests(cmsDecoder->signedData)) {
-               *signerStatus = kCMSSignerNeedsDetachedContent; 
-               return noErr;
+               *signerStatus = kCMSSignerNeedsDetachedContent;
+               return errSecSuccess;
        }
        
        /*
         * OK, we should be able to verify this signerInfo.
-        * I think we have to do the SecCmsSignedDataVerifySignerInfo first 
-        * in order get all the cert pieces into place before returning them 
-        * to the caller. 
+        * I think we have to do the SecCmsSignedDataVerifySignerInfo first
+        * in order get all the cert pieces into place before returning them
+        * to the caller.
         */
        SecTrustRef theTrust = NULL;
-       OSStatus vfyRtn = SecCmsSignedDataVerifySignerInfo(cmsDecoder->signedData, 
-               signerIndex, 
-               /* 
-                * FIXME this cast should not be necessary, but libsecurity_smime 
-                * declares this argument as a SecKeychainRef
-                */
-               (SecKeychainRef)cmsDecoder->keychainOrArray,
-               policyOrArray, 
-               &theTrust);
-        /* Subsequent errors to errOut: */
-        
+       OSStatus vfyRtn = SecCmsSignedDataVerifySignerInfo(cmsDecoder->signedData,
+                                                       (int)signerIndex,
+                                                       /*
+                                                        * FIXME this cast should not be necessary, but libsecurity_smime
+                                                        * declares this argument as a SecKeychainRef
+                                                        */
+                                                       (SecKeychainRef)cmsDecoder->keychainOrArray,
+                                                       policyOrArray,
+                                                       &theTrust);
+    /* Subsequent errors to errOut: */
+    
        /*
-        * NOTE the smime lib did NOT evaluate that SecTrust - it only does 
+        * NOTE the smime lib did NOT evaluate that SecTrust - it only does
         * SecTrustEvaluate() if we don't ask for a copy.
-        * 
+        *
         * FIXME deal with multitudes of status returns here...for now, proceed with
         * obtaining components the caller wants and assume that a nonzero vfyRtn
-        * means "bad signature". 
+        * means "bad signature".
         */
-       OSStatus ortn = noErr;
+       OSStatus ortn = errSecSuccess;
        SecTrustResultType secTrustResult;
        CSSM_RETURN tpVfyStatus = CSSM_OK;
        OSStatus evalRtn;
@@ -500,16 +500,16 @@ OSStatus CMSDecoderCopySignerStatus(
                if (theTrust)
                        CFRetain(theTrust);
        }
-       SecCmsSignerInfoRef signerInfo = 
-               SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, signerIndex);
+       SecCmsSignerInfoRef signerInfo =
+    SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, (int)signerIndex);
        if(signerInfo == NULL) {
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerStatus: no signerInfo\n");
-               ortn = internalComponentErr;
+               ortn = errSecInternalComponent;
                goto errOut;
        }
-
+    
        /* now do the actual cert verify */
        if(evaluateSecTrust) {
                evalRtn = SecTrustEvaluate(theTrust, &secTrustResult);
@@ -517,7 +517,7 @@ OSStatus CMSDecoderCopySignerStatus(
                        /* should never happen */
                        CSSM_PERROR("SecTrustEvaluate", evalRtn);
                        dprintf("CMSDecoderCopySignerStatus: SecTrustEvaluate error\n");
-                       ortn = internalComponentErr;
+                       ortn = errSecInternalComponent;
                        goto errOut;
                }
                switch(secTrustResult) {
@@ -555,10 +555,10 @@ OSStatus CMSDecoderCopySignerStatus(
        
        /* cook up global status based on vfyRtn and tpVfyStatus */
        if(signerStatus != NULL) {
-               if((vfyRtn == noErr) && (tpVfyStatus == CSSM_OK))  {
+               if((vfyRtn == errSecSuccess) && (tpVfyStatus == CSSM_OK))  {
                        *signerStatus = kCMSSignerValid;
                }
-               else if(vfyRtn != noErr) {
+               else if(vfyRtn != errSecSuccess) {
                        /* this could mean other things, but for now... */
                        *signerStatus = kCMSSignerInvalidSignature;
                }
@@ -573,65 +573,65 @@ errOut:
 
 /*
  * Obtain the email address of signer 'signerIndex' of a CMS message, if
- * present. 
+ * present.
  *
- * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
+ * This cannot be called until after CMSDecoderFinalizeMessage() is called.
  */
 OSStatus CMSDecoderCopySignerEmailAddress(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,
-       CFStringRef                     *signerEmailAddress)    /* RETURNED */
+                                          CMSDecoderRef                cmsDecoder,
+                                          size_t                               signerIndex,
+                                          CFStringRef                  *signerEmailAddress)    /* RETURNED */
 {
-       if((cmsDecoder == NULL) || 
+       if((cmsDecoder == NULL) ||
           (signerEmailAddress == NULL) ||
           (cmsDecoder->signedData == NULL) ||                  /* not signed */
           (signerIndex >= cmsDecoder->numSigners) ||   /* index out of range */
           (cmsDecoder->decState != DS_Final)) {
-               return paramErr;
+               return errSecParam;
        }
        
-       SecCmsSignerInfoRef signerInfo = 
-               SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, signerIndex);
+       SecCmsSignerInfoRef signerInfo =
+    SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, (int)signerIndex);
        if(signerInfo == NULL) {
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerEmailAddress: no signerInfo\n");
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        
-       /* 
-        * This is leaking memory in libsecurityKeychain per Radar 4412699. 
+       /*
+        * This is leaking memory in libsecurityKeychain per Radar 4412699.
         */
        *signerEmailAddress = SecCmsSignerInfoGetSignerEmailAddress(signerInfo);
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Obtain the certificate of signer 'signerIndex' of a CMS message, if
- * present. 
+ * present.
  *
- * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
+ * This cannot be called until after CMSDecoderFinalizeMessage() is called.
  */
 OSStatus CMSDecoderCopySignerCert(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,
-       SecCertificateRef       *signerCert)                    /* RETURNED */
+                                  CMSDecoderRef                cmsDecoder,
+                                  size_t                               signerIndex,
+                                  SecCertificateRef    *signerCert)                    /* RETURNED */
 {
-       if((cmsDecoder == NULL) || 
+       if((cmsDecoder == NULL) ||
           (signerCert == NULL) ||
           (cmsDecoder->signedData == NULL) ||                  /* not signed */
           (signerIndex >= cmsDecoder->numSigners) ||   /* index out of range */
           (cmsDecoder->decState != DS_Final)) {
-               return paramErr;
+               return errSecParam;
        }
-
-       SecCmsSignerInfoRef signerInfo = 
-               SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, signerIndex);
+    
+       SecCmsSignerInfoRef signerInfo =
+    SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, (int)signerIndex);
        if(signerInfo == NULL) {
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerCertificate: no signerInfo\n");
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        *signerCert = SecCmsSignerInfoGetSigningCertificate(signerInfo, NULL);
        /* libsecurity_smime does NOT retain that */
@@ -639,43 +639,43 @@ OSStatus CMSDecoderCopySignerCert(
                /* should never happen */
                ASSERT(0);
                dprintf("CMSDecoderCopySignerCertificate: no signerCert\n");
-               return internalComponentErr;
+               return errSecInternalComponent;
        }
        CFRetain(*signerCert);
-       return noErr;
+       return errSecSuccess;
 }
 
-/* 
+/*
  * Determine whether a CMS message was encrypted, and if so, whether we were
- * able to decrypt it. 
+ * able to decrypt it.
  */
 OSStatus CMSDecoderIsContentEncrypted(
-       CMSDecoderRef   cmsDecoder,
-       Boolean                 *wasEncrypted)
+                                      CMSDecoderRef    cmsDecoder,
+                                      Boolean                  *wasEncrypted)
 {
        if((cmsDecoder == NULL) || (wasEncrypted == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Final) {
-               return paramErr;
+               return errSecParam;
        }
        *wasEncrypted = cmsDecoder->wasEncrypted;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
- * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if 
+ * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if
  * present.
  */
 OSStatus CMSDecoderCopyEncapsulatedContentType(
-       CMSDecoderRef           cmsDecoder,
-       CFDataRef                       *eContentType)          /* RETURNED */
+                                               CMSDecoderRef           cmsDecoder,
+                                               CFDataRef                       *eContentType)          /* RETURNED */
 {
        if((cmsDecoder == NULL) || (eContentType == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Final) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->signedData == NULL) {
                *eContentType = NULL;
@@ -684,36 +684,36 @@ OSStatus CMSDecoderCopyEncapsulatedContentType(
                CSSM_OID *ecOid = cmsDecoder->eContentType;
                *eContentType = CFDataCreate(NULL, ecOid->Data, ecOid->Length);
        }
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
- * Obtain an array of all of the certificates in a message. Elements of the 
- * returned array are SecCertificateRefs. The caller must CFRelease the returned 
+ * Obtain an array of all of the certificates in a message. Elements of the
+ * returned array are SecCertificateRefs. The caller must CFRelease the returned
  * array.
- * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
+ * This cannot be called until after CMSDecoderFinalizeMessage() is called.
  */
 OSStatus CMSDecoderCopyAllCerts(
-       CMSDecoderRef           cmsDecoder,
-       CFArrayRef                      *certs)                                 /* RETURNED */
+                                CMSDecoderRef          cmsDecoder,
+                                CFArrayRef                     *certs)                                 /* RETURNED */
 {
        if((cmsDecoder == NULL) || (certs == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Final) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->signedData == NULL) {
                /* message wasn't signed */
                *certs = NULL;
-               return noErr;
+               return errSecSuccess;
        }
        
        /* NULL_terminated array of CSSM_DATA ptrs */
        CSSM_DATA_PTR *cssmCerts = SecCmsSignedDataGetCertificateList(cmsDecoder->signedData);
        if((cssmCerts == NULL) || (*cssmCerts == NULL)) {
                *certs = NULL;
-               return noErr;
+               return errSecSuccess;
        }
        
        CFMutableArrayRef allCerts = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -721,9 +721,9 @@ OSStatus CMSDecoderCopyAllCerts(
        for(cssmCert=cssmCerts; *cssmCert!=NULL; cssmCert++) {
                OSStatus ortn;
                SecCertificateRef cfCert;
-               ortn = SecCertificateCreateFromData(*cssmCert, 
-                       CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER,
-                       &cfCert);
+               ortn = SecCertificateCreateFromData(*cssmCert,
+                                            CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER,
+                                            &cfCert);
                if(ortn) {
                        CFRelease(allCerts);
                        return ortn;
@@ -733,104 +733,104 @@ OSStatus CMSDecoderCopyAllCerts(
                CFRelease(cfCert);
        }
        *certs = allCerts;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
  * Obtain the actual message content (payload), if any. If the message was
  * signed with detached content this will return NULL.
- * Caller must CFRelease the result. 
+ * Caller must CFRelease the result.
  */
 OSStatus CMSDecoderCopyContent(
-       CMSDecoderRef           cmsDecoder,
-       CFDataRef                       *content)                               /* RETURNED */
+                               CMSDecoderRef           cmsDecoder,
+                               CFDataRef                       *content)                               /* RETURNED */
 {
        if((cmsDecoder == NULL) || (content == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->decState != DS_Final) {
-               return paramErr;
+               return errSecParam;
        }
        if(cmsDecoder->cmsMsg == NULL) {
                /* Hmmm....looks like the finalize call failed */
-               return paramErr;
+               return errSecParam;
        }
        CSSM_DATA_PTR odata = SecCmsMessageGetContent(cmsDecoder->cmsMsg);
        if((odata == NULL) || (odata->Length == 0)) {
                /* i.e., detached content */
                *content = NULL;
-               return noErr;
+               return errSecSuccess;
        }
        *content = CFDataCreate(NULL, (const UInt8 *)odata->Data, odata->Length);
-       return noErr;
+       return errSecSuccess;
 }
 
 #pragma mark --- SPI declared in CMSPrivate.h ---
 
 /*
- * Obtain the SecCmsMessageRef associated with a CMSDecoderRef. Intended 
- * to be called after decoding the message (i.e., after 
+ * Obtain the SecCmsMessageRef associated with a CMSDecoderRef. Intended
+ * to be called after decoding the message (i.e., after
  * CMSDecoderFinalizeMessage() to gain finer access to the contents of the
- * SecCmsMessageRef than is otherwise available via the CMSDecoder interface. 
+ * SecCmsMessageRef than is otherwise available via the CMSDecoder interface.
  * Returns a NULL SecCmsMessageRef if CMSDecoderFinalizeMessage() has not been
- * called. 
+ * called.
  *
  * The CMSDecoder retains ownership of the returned SecCmsMessageRef.
  */
 OSStatus CMSDecoderGetCmsMessage(
-       CMSDecoderRef           cmsDecoder,
-       SecCmsMessageRef        *cmsMessage)            /* RETURNED */
+                                 CMSDecoderRef         cmsDecoder,
+                                 SecCmsMessageRef      *cmsMessage)            /* RETURNED */
 {
        if((cmsDecoder == NULL) || (cmsMessage == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        /* any state, whether we have a msg or not is OK */
        *cmsMessage = cmsDecoder->cmsMsg;
-       return noErr;
+       return errSecSuccess;
 }
 
-/* 
+/*
  * Optionally specify a SecCmsDecoderRef to use with a CMSDecoderRef.
- * If this is called, it must be called before the first call to 
+ * If this is called, it must be called before the first call to
  * CMSDecoderUpdateMessage(). The CMSDecoderRef takes ownership of the
  * incoming SecCmsDecoderRef.
  */
 OSStatus CMSDecoderSetDecoder(
-       CMSDecoderRef           cmsDecoder,
-       SecCmsDecoderRef        decoder)
+                              CMSDecoderRef            cmsDecoder,
+                              SecCmsDecoderRef decoder)
 {
        if((cmsDecoder == NULL) || (decoder == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        switch(cmsDecoder->decState) {
                case DS_Init:
                        ASSERT(cmsDecoder->decoder == NULL);
                        cmsDecoder->decoder = decoder;
                        cmsDecoder->decState = DS_Updating;
-                       return noErr;
+                       return errSecSuccess;
                case DS_Updating:
                case DS_Final:
-                       return paramErr;
+                       return errSecParam;
        }
-       return noErr;
-}              
-       
-/* 
- * Obtain the SecCmsDecoderRef associated with a CMSDecoderRef. 
+       return errSecSuccess;
+}
+
+/*
+ * Obtain the SecCmsDecoderRef associated with a CMSDecoderRef.
  * Returns a NULL SecCmsDecoderRef if neither CMSDecoderSetDecoder() nor
- * CMSDecoderUpdateMessage() has been called. 
+ * CMSDecoderUpdateMessage() has been called.
  * The CMSDecoderRef retains ownership of the SecCmsDecoderRef.
  */
 OSStatus CMSDecoderGetDecoder(
-       CMSDecoderRef           cmsDecoder,
-       SecCmsDecoderRef        *decoder)                       /* RETURNED */
+                              CMSDecoderRef            cmsDecoder,
+                              SecCmsDecoderRef *decoder)                       /* RETURNED */
 {
        if((cmsDecoder == NULL) || (decoder == NULL)) {
-               return paramErr;
+               return errSecParam;
        }
        /* any state, whether we have a decoder or not is OK */
        *decoder = cmsDecoder->decoder;
-       return noErr;
+       return errSecSuccess;
 }
 
 /*
@@ -838,17 +838,17 @@ OSStatus CMSDecoderGetDecoder(
  * present. This is an unauthenticate time, although it is part of the
  * signed attributes of the message.
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
- * is greater than the number of signers of the message minus one. 
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
+ * is greater than the number of signers of the message minus one.
  *
- * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
+ * This cannot be called until after CMSDecoderFinalizeMessage() is called.
  */
 OSStatus CMSDecoderCopySignerSigningTime(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,            /* usually 0 */
-       CFAbsoluteTime      *signingTime)                       /* RETURNED */
+                                         CMSDecoderRef         cmsDecoder,
+                                         size_t                                signerIndex,            /* usually 0 */
+                                         CFAbsoluteTime      *signingTime)                     /* RETURNED */
 {
-    OSStatus status = paramErr;
+    OSStatus status = errSecParam;
        SecCmsMessageRef cmsg;
        SecCmsSignedDataRef signedData = NULL;
     int numContentInfos = 0;
@@ -877,21 +877,21 @@ xit:
  * present. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
- * is greater than the number of signers of the message minus one. 
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
+ * is greater than the number of signers of the message minus one.
  *
- * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
+ * This cannot be called until after CMSDecoderFinalizeMessage() is called.
  */
 OSStatus CMSDecoderCopySignerTimestamp(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,        /* usually 0 */
-       CFAbsoluteTime      *timestamp)                 /* RETURNED */
+                                       CMSDecoderRef           cmsDecoder,
+                                       size_t                          signerIndex,        /* usually 0 */
+                                       CFAbsoluteTime      *timestamp)                 /* RETURNED */
 {
-    OSStatus status = paramErr;
+    OSStatus status = errSecParam;
        SecCmsMessageRef cmsg;
        SecCmsSignedDataRef signedData = NULL;
     int numContentInfos = 0;
-
+    
     require(cmsDecoder && timestamp, xit);
        require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit);
     numContentInfos = SecCmsMessageContentLevelCount(cmsg);
@@ -907,33 +907,35 @@ OSStatus CMSDecoderCopySignerTimestamp(
                     break;
                 }
     }
-
+    
 xit:
     return status;
 }
 
 /*
- * Obtain an array of the certificates in a timestamp response. Elements of the 
+ * Obtain an array of the certificates in a timestamp response. Elements of the
  * returned array are SecCertificateRefs. The caller must CFRelease the returned
  * array. This timestamp is an authenticated timestamp provided by
  * a timestamping authority.
  *
- * Returns paramErr if the CMS message was not signed or if signerIndex
+ * Returns errSecParam if the CMS message was not signed or if signerIndex
  * is greater than the number of signers of the message minus one. It returns
  * errSecItemNotFound if no certificates were found.
  *
  * This cannot be called until after CMSDecoderFinalizeMessage() is called. 
  */
 OSStatus CMSDecoderCopySignerTimestampCertificates(
-       CMSDecoderRef           cmsDecoder,
-       size_t                          signerIndex,            /* usually 0 */
-       CFArrayRef          *certificateRefs)       /* RETURNED */
+                                                   CMSDecoderRef               cmsDecoder,
+                                                   size_t                              signerIndex,            /* usually 0 */
+                                                   CFArrayRef          *certificateRefs)       /* RETURNED */
 {
-    OSStatus status = paramErr;
-       SecCmsMessageRef cmsg;
+    OSStatus status = errSecParam;
+       SecCmsMessageRef cmsg = NULL;
        SecCmsSignedDataRef signedData = NULL;
     int numContentInfos = 0;
-
+    CFIndex tsn = 0;
+    bool good = false;
+    
     require(cmsDecoder && certificateRefs, xit);
        require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit);
     numContentInfos = SecCmsMessageContentLevelCount(cmsg);
@@ -947,12 +949,35 @@ OSStatus CMSDecoderCopySignerTimestampCertificates(
                 {
                     CFArrayRef certList = SecCmsSignerInfoGetTimestampCertList(signerInfo);
                     require_action(certList, xit, status = errSecItemNotFound);
-                    *certificateRefs = CFArrayCreateCopy(kCFAllocatorDefault, certList);
-                    status = noErr;
+                    CFMutableArrayRef certs = CFArrayCreateMutableCopy(kCFAllocatorDefault, CFArrayGetCount(certList), certList);
+                    
+                    if(certs){
+                        //reorder certificates:
+                        tsn = CFArrayGetCount(certs);
+                        good = tsn > 0 && Security::CodeSigning::isAppleCA(SecCertificateRef(CFArrayGetValueAtIndex(certs, tsn-1)));
+                        
+                        if ( good == false )
+                        {
+                            //change TS certificate ordering.
+                            for (CFIndex n = 0; n < tsn; n++)
+                            {
+                                if (SecCertificateRef tsRoot = SecCertificateRef(CFArrayGetValueAtIndex(certs, n)))
+                                    if ((good = Security::CodeSigning::isAppleCA(tsRoot))) {
+                                        CFArrayExchangeValuesAtIndices(certs, n, tsn-1);
+                                        break;
+                                    }
+                            }
+                        }
+                        
+                        *certificateRefs = CFArrayCreateCopy(kCFAllocatorDefault, certs);
+                        CFRelease(certs);
+                        status = errSecSuccess;
+                    }
                     break;
                 }
     }
-
-xit:
-    return status;
-}
+    
+    
+    xit:
+        return status;
+    }