/*
* 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>
} CMSDecoderState;
/*
- * Caller's CMSDecoderRef points to one of these.
+ * Caller's CMSDecoderRef points to one of these.
*/
struct _CMSDecoder {
CFRuntimeBase base;
CFDataRef detachedContent;
CFTypeRef keychainOrArray; /* from CMSDecoderSetSearchKeychain() */
- /*
+ /*
* The following are valid (and quiescent) after CMSDecoderFinalizeMessage().
*/
SecCmsMessageRef cmsMsg;
static void cmsDecoderInit(CFTypeRef dec);
static void cmsDecoderFinalize(CFTypeRef dec);
-static CFRuntimeClass cmsDecoderRuntimeClass =
+static CFRuntimeClass cmsDecoderRuntimeClass =
{
0, /* version */
"CMSDecoder",
/* 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() */
* 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...
/*
- * 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));
}
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) {
* 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;
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);
}
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? */
}
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);
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);
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);
/*
* 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);
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 */
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;
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);
/* should never happen */
CSSM_PERROR("SecTrustEvaluate", evalRtn);
dprintf("CMSDecoderCopySignerStatus: SecTrustEvaluate error\n");
- ortn = internalComponentErr;
+ ortn = errSecInternalComponent;
goto errOut;
}
switch(secTrustResult) {
/* 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;
}
/*
* 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 */
/* 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;
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);
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;
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;
}
/*
* 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;
* 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);
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);
{
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;
+ }