X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195..e3d3b979fd185d8303f28a937baa53a187fb8c7d:/libsecurity_cms/lib/CMSDecoder.cpp?ds=sidebyside diff --git a/libsecurity_cms/lib/CMSDecoder.cpp b/libsecurity_cms/lib/CMSDecoder.cpp index 93ccab3f..930c0c5e 100644 --- a/libsecurity_cms/lib/CMSDecoder.cpp +++ b/libsecurity_cms/lib/CMSDecoder.cpp @@ -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, @@ -17,18 +17,18 @@ * 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 +#include <../libsecurity_codesigning/lib/csutilities.h> #include #include @@ -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; + }