]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_smime/lib/tsaSupport.c
Security-57031.1.35.tar.gz
[apple/security.git] / libsecurity_smime / lib / tsaSupport.c
diff --git a/libsecurity_smime/lib/tsaSupport.c b/libsecurity_smime/lib/tsaSupport.c
deleted file mode 100644 (file)
index e894fc7..0000000
+++ /dev/null
@@ -1,1393 +0,0 @@
-/*
- * Copyright (c) 2012 Apple Computer, 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,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * 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@
- *
- * tsaSupport.c -  ASN1 templates Time Stamping Authority requests and responses
- */
-
-/*
-#include <Security/SecCmsDigestContext.h>
-#include <Security/SecCmsMessage.h>
-#include <security_asn1/secasn1.h>
-#include <security_asn1/secerr.h>
-*/
-
-#include <security_utilities/debugging.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
-#include <Security/SecCmsDecoder.h>
-#include <Security/SecCmsMessage.h>
-#include <Security/SecCmsContentInfo.h>
-#include <Security/SecCmsSignedData.h>
-#include <Security/SecCmsSignerInfo.h>
-#include "tsaTemplates.h"
-#include <Security/SecAsn1Coder.h>
-#include <AssertMacros.h>
-#include <Security/SecPolicy.h>
-#include <Security/SecTrustPriv.h>
-#include <Security/SecImportExport.h>
-#include <Security/SecCertificatePriv.h>
-#include <security_keychain/SecCertificateP.h>
-#include <security_keychain/SecCertificatePrivP.h>
-
-#include "tsaSupport.h"
-#include "tsaSupportPriv.h"
-#include "tsaTemplates.h"
-#include "cmslocal.h"
-
-#include "secoid.h"
-#include "secitem.h"
-#include <fcntl.h>
-
-const CFStringRef kTSAContextKeyURL = CFSTR("ServerURL");
-const CFStringRef kTSAContextKeyNoCerts = CFSTR("NoCerts");
-const CFStringRef kTSADebugContextKeyBadReq = CFSTR("DebugBadReq");
-const CFStringRef kTSADebugContextKeyBadNonce = CFSTR("DebugBadNonce");
-
-extern const SecAsn1Template kSecAsn1TSATSTInfoTemplate[];
-
-extern OSStatus impExpImportCertCommon(
-       const CSSM_DATA         *cdata,
-       SecKeychainRef          importKeychain, // optional
-       CFMutableArrayRef       outArray);              // optional, append here
-
-#pragma mark ----- Debug Logs -----
-
-#ifndef NDEBUG
-#define TSA_USE_SYSLOG 1
-#endif
-
-#if TSA_USE_SYSLOG
-#include <syslog.h>
-    #include <time.h>
-    #include <sys/time.h>
-    #define tsaDebug(fmt, ...) \
-        do { if (true) { \
-            char buf[64];   \
-            struct timeval time_now;   \
-            gettimeofday(&time_now, NULL);  \
-            struct tm* time_info = localtime(&time_now.tv_sec);    \
-            strftime(buf, sizeof(buf), "[%Y-%m-%d %H:%M:%S]", time_info);   \
-                    fprintf(stderr, "%s " fmt, buf, ## __VA_ARGS__); \
-                    syslog(LOG_ERR, " " fmt, ## __VA_ARGS__); \
-                    } } while (0)
-    #define tsa_secdebug(scope, format...) \
-    { \
-        syslog(LOG_NOTICE, format); \
-        secdebug(scope, format); \
-        printf(format); \
-    }
-#else
-    #define tsaDebug(args...)                  tsa_secdebug("tsa", ## args)
-#define tsa_secdebug(scope, format...) \
-        secdebug(scope, format)
-#endif
-
-#ifndef NDEBUG
-#define TSTINFO_DEBUG  1   //jch
-#endif
-
-#if    TSTINFO_DEBUG
-#define dtprintf(args...)    tsaDebug(args)
-#else
-#define dtprintf(args...)
-#endif
-
-#define kHTTPResponseCodeContinue               100
-#define kHTTPResponseCodeOK                     200
-#define kHTTPResponseCodeNoContent              204
-#define kHTTPResponseCodeBadRequest             400
-#define kHTTPResponseCodeUnauthorized           401
-#define kHTTPResponseCodeForbidden              403
-#define kHTTPResponseCodeNotFound               404
-#define kHTTPResponseCodeConflict               409
-#define kHTTPResponseCodeExpectationFailed      417
-#define kHTTPResponseCodeServFail               500
-#define kHTTPResponseCodeServiceUnavailable     503
-#define kHTTPResponseCodeInsufficientStorage    507
-
-#pragma mark ----- Debug/Utilities -----
-
-static OSStatus remapHTTPErrorCodes(OSStatus status)
-{
-    switch (status)
-    {
-    case kHTTPResponseCodeOK:
-    case kHTTPResponseCodeContinue:
-        return noErr;
-    case kHTTPResponseCodeBadRequest:
-        return errSecTimestampBadRequest;
-    case kHTTPResponseCodeNoContent:
-    case kHTTPResponseCodeUnauthorized:
-    case kHTTPResponseCodeForbidden:
-    case kHTTPResponseCodeNotFound:
-    case kHTTPResponseCodeConflict:
-    case kHTTPResponseCodeExpectationFailed:
-    case kHTTPResponseCodeServFail:
-    case kHTTPResponseCodeInsufficientStorage:
-    case kHTTPResponseCodeServiceUnavailable:
-        return errSecTimestampServiceNotAvailable;
-    default:
-        return status;
-    }
-    return status;
-
-}
-
-static void printDataAsHex(const char *title, const CSSM_DATA *d, unsigned maxToPrint) // 0 means print it all
-{
-#ifndef NDEBUG
-    unsigned i;
-    bool more = false;
-    uint32 len = (uint32)d->Length;
-    uint8 *cp = d->Data;
-    char *buffer = NULL;
-    size_t bufferSize;
-    int offset, sz = 0;
-    const int wrapwid = 24;     // large enough so SHA-1 hashes fit on one line...
-
-    if ((maxToPrint != 0) && (len > maxToPrint))
-    {
-        len = maxToPrint;
-        more = true;
-    }
-
-    bufferSize = wrapwid+3*len;
-    buffer = (char *)malloc(bufferSize);
-
-    offset = sprintf(buffer, "%s [len = %u]\n", title, len);
-    dtprintf("%s", buffer);
-    offset = 0;
-
-    for (i=0; (i < len) && (offset+3 < bufferSize); i++, offset += sz)
-    {
-        sz = sprintf(buffer + offset, " %02x", (unsigned int)cp[i] & 0xff);
-        if ((i % wrapwid) == (wrapwid-1))
-        {
-            dtprintf("%s", buffer);
-            offset = 0;
-            sz = 0;
-        }
-    }
-
-    sz=sprintf(buffer + offset, more?" ...\n":"\n");
-        offset += sz;
-    buffer[offset+1]=0;
-
-//    fprintf(stderr, "%s", buffer);
-    dtprintf("%s", buffer);
-#endif
-}
-
-#ifndef NDEBUG
-int tsaWriteFileX(const char *fileName, const unsigned char *bytes, size_t numBytes)
-{
-    int rtn;
-    int fd;
-
-    fd = open(fileName, O_RDWR | O_CREAT | O_TRUNC, 0600);
-    if (fd <= 0)
-        return errno;
-
-    rtn = (int)write(fd, bytes, numBytes);
-    if(rtn != (int)numBytes)
-    {
-        if (rtn >= 0)
-            fprintf(stderr, "writeFile: short write\n");
-        rtn = EIO;
-    }
-    else
-        rtn = 0;
-
-    close(fd);
-    return rtn;
-}
-#endif
-
-char *cfStringToChar(CFStringRef inStr)
-{
-    // Caller must free
-    char *result = NULL;
-    const char *str = NULL;
-
-       if (!inStr)
-        return strdup("");     // return a null string
-
-       // quick path first
-       if ((str = CFStringGetCStringPtr(inStr, kCFStringEncodingUTF8))) {
-        result = strdup(str);
-       } else {
-        // need to extract into buffer
-        CFIndex length = CFStringGetLength(inStr);  // in 16-bit character units
-        CFIndex bytesToAllocate = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
-        result = malloc(bytesToAllocate);
-        if (!CFStringGetCString(inStr, result, bytesToAllocate, kCFStringEncodingUTF8))
-            result[0] = 0;
-    }
-    
-       return result;
-}
-
-/* Oids longer than this are considered invalid. */
-#define MAX_OID_SIZE                           32
-
-#ifndef NDEBUG
-/* FIXME: There are other versions of this in SecCertifcate.c and SecCertificateP.c */
-static CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator, const CSSM_OID *oid)
-{
-       if (oid->Length == 0)
-        return CFSTR("<NULL>");
-
-       if (oid->Length > MAX_OID_SIZE)
-        return CFSTR("Oid too long");
-
-    CFMutableStringRef result = CFStringCreateMutable(allocator, 0);
-
-       // The first two levels are encoded into one byte, since the root levelq
-       // has only 3 nodes (40*x + y).  However if x = joint-iso-itu-t(2) then
-       // y may be > 39, so we have to add special-case handling for this.
-       uint32_t x = oid->Data[0] / 40;
-       uint32_t y = oid->Data[0] % 40;
-       if (x > 2)
-       {
-               // Handle special case for large y if x = 2
-               y += (x - 2) * 40;
-               x = 2;
-       }
-    CFStringAppendFormat(result, NULL, CFSTR("%u.%u"), x, y);
-
-       uint32_t value = 0;
-       for (x = 1; x < oid->Length; ++x)
-       {
-               value = (value << 7) | (oid->Data[x] & 0x7F);
-        /* @@@ value may not span more than 4 bytes. */
-        /* A max number of 20 values is allowed. */
-               if (!(oid->Data[x] & 0x80))
-               {
-            CFStringAppendFormat(result, NULL, CFSTR(".%lu"), (unsigned long)value);
-                       value = 0;
-               }
-       }
-       return result;
-}
-#endif
-
-static void debugSaveCertificates(CSSM_DATA **outCerts)
-{
-#ifndef NDEBUG
-    if (outCerts)
-    {
-        CSSM_DATA_PTR *certp;
-        unsigned jx = 0;
-        const char *certNameBase = "/tmp/tsa-resp-cert-";
-        char fname[PATH_MAX];
-        unsigned certCount = SecCmsArrayCount((void **)outCerts);
-        dtprintf("Found %d certs\n",certCount);
-
-        for (certp=outCerts;*certp;certp++, ++jx)
-        {
-            char numstr[32];
-            strncpy(fname, certNameBase, strlen(certNameBase)+1);
-            sprintf(numstr,"%u", jx);
-            strcat(fname,numstr);
-            tsaWriteFileX(fname, (*certp)->Data, (*certp)->Length);
-            if (jx > 5)
-                break;  //something wrong
-        }
-    }
-#endif
-}
-
-static void debugShowSignerInfo(SecCmsSignedDataRef signedData)
-{
-#ifndef NDEBUG
-    int numberOfSigners = SecCmsSignedDataSignerInfoCount (signedData);
-    dtprintf("numberOfSigners : %d\n", numberOfSigners);
-    int ix;
-    for (ix=0;ix < numberOfSigners;ix++)
-    {
-        SecCmsSignerInfoRef sigi = SecCmsSignedDataGetSignerInfo(signedData,ix);
-        if (sigi)
-        {
-            CFStringRef commonName = SecCmsSignerInfoGetSignerCommonName(sigi);
-            const char *signerhdr = "      signer    : ";
-            if (commonName)
-            {
-                char *cn = cfStringToChar(commonName);
-                dtprintf("%s%s\n", signerhdr, cn);
-                if (cn)
-                    free(cn);
-            }
-            else
-                dtprintf("%s<NULL>\n", signerhdr);
-         }
-    }
-#endif
-}
-
-static void debugShowContentTypeOID(SecCmsContentInfoRef contentInfo)
-{
-#ifndef NDEBUG
-
-    CSSM_OID *typeOID = SecCmsContentInfoGetContentTypeOID(contentInfo);
-    if (typeOID)
-    {
-        CFStringRef oidCFStr = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, typeOID);
-        char *oidstr = cfStringToChar(oidCFStr);
-        printDataAsHex("oid:", typeOID, (unsigned int)typeOID->Length);
-        dtprintf("\toid: %s\n", oidstr);
-        if (oidCFStr)
-            CFRelease(oidCFStr);
-        if (oidstr)
-            free(oidstr);
-    }
-#endif
-}
-
-uint64_t tsaDER_ToInt(const CSSM_DATA *DER_Data)
-{
-       uint64_t    rtn = 0;
-       unsigned        i = 0;
-
-       while(i < DER_Data->Length) {
-               rtn |= DER_Data->Data[i];
-               if(++i == DER_Data->Length) {
-                       break;
-               }
-               rtn <<= 8;
-       }
-       return rtn;
-}
-
-void displayTSTInfo(SecAsn1TSATSTInfo *tstInfo)
-{
-#ifndef NDEBUG
-    dtprintf("--- TSTInfo ---\n");
-    if (!tstInfo)
-        return;
-
-    if (tstInfo->version.Data)
-    {
-        uint64_t vers = tsaDER_ToInt(&tstInfo->version);
-        dtprintf("Version:\t\t%u\n", (int)vers);
-    }
-
-    if (tstInfo->serialNumber.Data)
-    {
-        uint64_t sn = tsaDER_ToInt(&tstInfo->serialNumber);
-        dtprintf("SerialNumber:\t%llu\n", sn);
-    }
-
-    if (tstInfo->ordering.Data)
-    {
-        uint64_t ord = tsaDER_ToInt(&tstInfo->ordering);
-        dtprintf("Ordering:\t\t%s\n", ord?"yes":"no");
-    }
-
-    if (tstInfo->nonce.Data)
-    {
-        uint64_t nonce = tsaDER_ToInt(&tstInfo->nonce);
-        dtprintf("Nonce:\t\t%llu\n", nonce);
-    }
-    else
-        dtprintf("Nonce:\t\tnot specified\n");
-
-    if (tstInfo->genTime.Data)
-    {
-        char buf[tstInfo->genTime.Length+1];
-        memcpy(buf, (const char *)tstInfo->genTime.Data, tstInfo->genTime.Length);
-        buf[tstInfo->genTime.Length]=0;
-        dtprintf("GenTime:\t\t%s\n", buf);
-    }
-
-    dtprintf("-- MessageImprint --\n");
-    if (true)   // SecAsn1TSAMessageImprint
-    {
-        printDataAsHex(" Algorithm:",&tstInfo->messageImprint.hashAlgorithm.algorithm, 0);
-        printDataAsHex(" Message  :", &tstInfo->messageImprint.hashedMessage, 0);//tstInfo->messageImprint.hashedMessage.Length);
-    }
-#endif
-}
-
-#pragma mark ----- TimeStamp Response using XPC -----
-
-#include <xpc/private.h>
-
-static OSStatus checkForNonDERResponse(const unsigned char *resp, size_t respLen)
-{
-    /*
-        Good start is something like 30 82 0c 03 30 15 02 01  00 30 10 0c 0e 4f 70 65
-
-        URL:    http://timestamp-int.corp.apple.com/signserver/process?TimeStampSigner
-        Resp:   Http/1.1 Service Unavailable
-
-        URL:    http://timestamp-int.corp.apple.com/ts01
-        Resp:   blank
-
-        URL:    http://cutandtaste.com/404 (or other forced 404 site)
-        Resp:   404
-    */
-
-    OSStatus status = noErr;
-    const char ader[2] = { 0x30, 0x82 };
-    char *respStr = NULL;
-    size_t maxlen = 0;
-    size_t badResponseCount;
-
-    const char *badResponses[] =
-    {
-        "<!DOCTYPE html>",
-        "Http/1.1 Service Unavailable",
-        "blank"
-    };
-
-    require_action(resp && respLen, xit, status = errSecTimestampServiceNotAvailable);
-
-    // This is usual case
-    if ((respLen > 1) && (memcmp(resp, ader, 2)==0))    // might be good; pass on to DER decoder
-        return noErr;
-
-    badResponseCount = sizeof(badResponses)/sizeof(char *);
-    int ix;
-    for (ix = 0; ix < badResponseCount; ++ix)
-        if (strlen(badResponses[ix]) > maxlen)
-            maxlen = strlen(badResponses[ix]);
-
-    // Prevent a large response from allocating a ton of memory
-    if (respLen > maxlen)
-        respLen = maxlen;
-
-    respStr = (char *)malloc(respLen+1);
-    strlcpy(respStr, (const char *)resp, respLen);
-
-    for (ix = 0; ix < badResponseCount; ++ix)
-        if (strcmp(respStr, badResponses[ix])==0)
-            return errSecTimestampServiceNotAvailable;
-
-xit:
-    if (respStr)
-        free((void *)respStr);
-
-    return status;
-}
-
-static OSStatus sendTSARequestWithXPC(const unsigned char *tsaReq, size_t tsaReqLength, const unsigned char *tsaURL, unsigned char **tsaResp, size_t *tsaRespLength)
-{
-    __block OSStatus result = noErr;
-    int timeoutInSeconds = 15;
-    extern xpc_object_t xpc_create_with_format(const char * format, ...);
-
-       dispatch_queue_t xpc_queue = dispatch_queue_create("com.apple.security.XPCTimeStampingService", DISPATCH_QUEUE_SERIAL);
-    __block dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
-    dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, timeoutInSeconds * NSEC_PER_SEC);
-
-    xpc_connection_t con = xpc_connection_create("com.apple.security.XPCTimeStampingService", xpc_queue);
-
-    xpc_connection_set_event_handler(con, ^(xpc_object_t event) {
-        xpc_type_t xtype = xpc_get_type(event);
-        if (XPC_TYPE_ERROR == xtype)
-        {    tsaDebug("default: connection error: %s\n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION)); }
-        else
-         {   tsaDebug("default: unexpected connection event %p\n", event); }
-    });
-
-    xpc_connection_resume(con);
-
-    xpc_object_t tsaReqData = xpc_data_create(tsaReq, tsaReqLength);
-    const char *urlstr = (tsaURL?(const char *)tsaURL:"");
-    xpc_object_t url_as_xpc_string = xpc_string_create(urlstr);
-
-    xpc_object_t message = xpc_create_with_format("{operation: TimeStampRequest, ServerURL: %value, TimeStampRequest: %value}", url_as_xpc_string, tsaReqData);
-
-    xpc_connection_send_message_with_reply(con, message, xpc_queue, ^(xpc_object_t reply)
-    {
-        tsaDebug("xpc_connection_send_message_with_reply handler called back\n");
-        dispatch_retain(waitSemaphore);
-
-    xpc_type_t xtype = xpc_get_type(reply);
-        if (XPC_TYPE_ERROR == xtype)
-            {   tsaDebug("message error: %s\n", xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION)); }
-        else if (XPC_TYPE_CONNECTION == xtype)
-            { tsaDebug("received connection\n"); }
-        else if (XPC_TYPE_DICTIONARY == xtype)
-    {
-#ifndef NDEBUG
-        /*
-         // This is useful for debugging.
-        char *debug = xpc_copy_description(reply);
-        tsaDebug("DEBUG %s\n", debug);
-        free(debug);
-         */
-#endif
-
-        xpc_object_t xpcTimeStampReply = xpc_dictionary_get_value(reply, "TimeStampReply");
-        size_t xpcTSRLength = xpc_data_get_length(xpcTimeStampReply);
-        tsaDebug("xpcTSRLength: %ld bytes of response\n", xpcTSRLength);
-
-        xpc_object_t xpcTimeStampError = xpc_dictionary_get_value(reply, "TimeStampError");
-        xpc_object_t xpcTimeStampStatus = xpc_dictionary_get_value(reply, "TimeStampStatus");
-
-        if (xpcTimeStampError || xpcTimeStampStatus)
-        {
-#ifndef NDEBUG
-            if (xpcTimeStampError)
-            {
-                size_t len = xpc_string_get_length(xpcTimeStampError);
-                char *buf = (char *)malloc(len);
-                strlcpy(buf, xpc_string_get_string_ptr(xpcTimeStampError), len+1);
-                tsaDebug("xpcTimeStampError: %s\n", buf);
-                if (buf)
-                    free(buf);
-            }
-#endif
-            if (xpcTimeStampStatus)
-            {
-                result = (OSStatus)xpc_int64_get_value(xpcTimeStampStatus);
-                tsaDebug("xpcTimeStampStatus: %d\n", (int)result);
-            }
-        }
-
-        result = remapHTTPErrorCodes(result);
-
-        if ((result == noErr) && tsaResp && tsaRespLength)
-        {
-            *tsaRespLength = xpcTSRLength;
-            *tsaResp = (unsigned char *)malloc(xpcTSRLength);
-
-            size_t bytesCopied = xpc_data_get_bytes(xpcTimeStampReply, *tsaResp, 0, xpcTSRLength);
-            if (bytesCopied != xpcTSRLength)
-            {    tsaDebug("length mismatch: copied: %ld, xpc: %ld\n", bytesCopied, xpcTSRLength); }
-            else
-            if ((result = checkForNonDERResponse(*tsaResp,bytesCopied)))
-            {
-                tsaDebug("received non-DER response from timestamp server\n");
-            }
-            else
-            {
-                result = noErr;
-                tsaDebug("copied: %ld bytes of response\n", bytesCopied);
-            }
-        }
-        tsaDebug("releasing connection\n");
-        xpc_release(con);
-    }
-    else
-        { tsaDebug("unexpected message reply type %p\n", xtype); }
-
-        dispatch_semaphore_signal(waitSemaphore);
-        dispatch_release(waitSemaphore);
-    });
-
-    { tsaDebug("waiting up to %d seconds for response from XPC\n", timeoutInSeconds); }
-       dispatch_semaphore_wait(waitSemaphore, finishTime);
-
-       dispatch_release(waitSemaphore);
-    xpc_release(tsaReqData);
-    xpc_release(message);
-
-    { tsaDebug("sendTSARequestWithXPC exit\n"); }
-
-    return result;
-}
-
-#pragma mark ----- TimeStamp request -----
-
-#include "tsaTemplates.h"
-#include <security_asn1/SecAsn1Coder.h>
-#include <Security/oidsalg.h>
-#include <AssertMacros.h>
-#include <libkern/OSByteOrder.h>
-
-extern const SecAsn1Template kSecAsn1TSATimeStampReqTemplate;
-extern const SecAsn1Template kSecAsn1TSATimeStampRespTemplateDER;
-
-CFMutableDictionaryRef SecCmsTSAGetDefaultContext(CFErrorRef *error)
-{
-    // Caller responsible for retain/release
-    // <rdar://problem/11077440> Update SecCmsTSAGetDefaultContext with actual URL for Apple Timestamp server
-    //      URL will be in TimeStampingPrefs.plist
-
-    CFBundleRef secFWbundle = NULL;
-    CFURLRef resourceURL = NULL;
-    CFDataRef resourceData = NULL;
-    CFPropertyListRef prefs = NULL;
-    CFMutableDictionaryRef contextDict = NULL;
-    SInt32 errorCode = 0;
-    CFOptionFlags options = 0;
-    CFPropertyListFormat format = 0;
-    OSStatus status = noErr;
-
-    require_action(secFWbundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security")), xit, status = errSecInternalError);
-    require_action(resourceURL = CFBundleCopyResourceURL(secFWbundle, CFSTR("TimeStampingPrefs"), CFSTR("plist"), NULL),
-        xit, status = errSecInvalidPrefsDomain);
-
-    require(CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, resourceURL, &resourceData,
-        NULL, NULL, &errorCode), xit);
-    require_action(resourceData, xit, status = errSecDataNotAvailable);
-
-    prefs = CFPropertyListCreateWithData(kCFAllocatorDefault, resourceData, options, &format, error);
-    require_action(prefs && (CFGetTypeID(prefs)==CFDictionaryGetTypeID()), xit, status = errSecInvalidPrefsDomain);
-
-    contextDict = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, prefs);
-
-    if (error)
-        *error = NULL;
-xit:
-    if (errorCode)
-        status = errorCode;
-    if (error && status)
-        *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainOSStatus, status, NULL);
-    if (secFWbundle)
-        CFRelease(secFWbundle);
-    if (resourceURL)
-        CFRelease(resourceURL);
-    if (resourceData)
-        CFRelease(resourceData);
-    if (prefs)
-        CFRelease(prefs);
-
-    return contextDict;
-}
-
-static CFDataRef _SecTSARequestCopyDEREncoding(SecAsn1TSAMessageImprint *messageImprint, bool noCerts, uint64_t nonce)
-{
-    // Returns DER encoded TimeStampReq
-    // Modeled on _SecOCSPRequestCopyDEREncoding
-    // The Timestamp Authority supports 64 bit nonces (or more possibly)
-
-    SecAsn1CoderRef             coder = NULL;
-    uint8_t                     version = 1;
-    SecAsn1Item                 vers = {1, &version};
-    uint8_t                     creq = noCerts?0:1;
-    SecAsn1Item                 certReq = {1, &creq};   //jch - to request or not?
-    SecAsn1TSATimeStampReq      tsreq = {};
-    CFDataRef                   der = NULL;
-    uint64_t                    nonceVal = OSSwapHostToBigConstInt64(nonce);
-    SecAsn1Item                 nonceItem = {sizeof(uint64_t), (unsigned char *)&nonceVal};
-
-    uint8_t OID_FakePolicy_Data[] = { 0x2A, 0x03, 0x04, 0x05, 0x06};
-    const CSSM_OID fakePolicyOID = {sizeof(OID_FakePolicy_Data),OID_FakePolicy_Data};
-
-    tsreq.version = vers;
-
-    tsreq.messageImprint = *messageImprint;
-    tsreq.certReq = certReq;
-
-    // skip reqPolicy, extensions for now - FAKES - jch
-    tsreq.reqPolicy = fakePolicyOID;    //policyID;
-
-    tsreq.nonce = nonceItem;
-
-    // Encode the request
-    require_noerr(SecAsn1CoderCreate(&coder), errOut);
-
-    SecAsn1Item encoded;
-    require_noerr(SecAsn1EncodeItem(coder, &tsreq,
-        &kSecAsn1TSATimeStampReqTemplate, &encoded), errOut);
-    der = CFDataCreate(kCFAllocatorDefault, encoded.Data,
-        encoded.Length);
-
-errOut:
-    if (coder)
-        SecAsn1CoderRelease(coder);
-
-    return der;
-}
-
-OSStatus SecTSAResponseCopyDEREncoding(SecAsn1CoderRef coder, const CSSM_DATA *tsaResponse, SecAsn1TimeStampRespDER *respDER)
-{
-    // Partially decode the response
-    OSStatus status = paramErr;
-
-    require(tsaResponse && respDER, errOut);
-    require_noerr(SecAsn1DecodeData(coder, tsaResponse,
-        &kSecAsn1TSATimeStampRespTemplateDER, respDER), errOut);
-    status = noErr;
-
-errOut:
-
-    return status;
-}
-
-#pragma mark ----- TS Callback -----
-
-OSStatus SecCmsTSADefaultCallback(CFTypeRef context, void *messageImprintV, uint64_t nonce, CSSM_DATA *signedDERBlob)
-{
-    OSStatus result = paramErr;
-    const unsigned char *tsaReq = NULL;
-    size_t tsaReqLength = 0;
-    CFDataRef cfreq = NULL;
-    unsigned char *tsaURL = NULL;
-    bool noCerts = false;
-
-    if (!context || CFGetTypeID(context)!=CFDictionaryGetTypeID())
-        return paramErr;
-
-    SecAsn1TSAMessageImprint *messageImprint = (SecAsn1TSAMessageImprint *)messageImprintV;
-    if (!messageImprint || !signedDERBlob)
-        return paramErr;
-
-    CFBooleanRef cfnocerts = (CFBooleanRef)CFDictionaryGetValue((CFDictionaryRef)context, kTSAContextKeyNoCerts);
-    if (cfnocerts)
-    {
-        tsaDebug("[TSA] Request noCerts\n");
-        noCerts = CFBooleanGetValue(cfnocerts);
-    }
-
-    // We must spoof the nonce here, before sending the request.
-    // If we tried to alter the reply, then the signature would break instead.
-    CFBooleanRef cfBadNonce = (CFBooleanRef)CFDictionaryGetValue((CFDictionaryRef)context, kTSADebugContextKeyBadNonce);
-    if (cfBadNonce && CFBooleanGetValue(cfBadNonce))
-    {
-        tsaDebug("[TSA] Forcing bad TS Request by changing nonce\n");
-        nonce++;
-    }
-
-    printDataAsHex("[TSA] hashToTimeStamp:", &messageImprint->hashedMessage,128);
-    cfreq = _SecTSARequestCopyDEREncoding(messageImprint, noCerts, nonce);
-    if (cfreq)
-    {
-        tsaReq = CFDataGetBytePtr(cfreq);
-        tsaReqLength = CFDataGetLength(cfreq);
-
-#ifndef NDEBUG
-        CFShow(cfreq);
-        tsaWriteFileX("/tmp/tsareq.req", tsaReq, tsaReqLength);
-#endif
-    }
-
-    CFStringRef url = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)context, kTSAContextKeyURL);
-    if (!url)
-    {
-        tsaDebug("[TSA] missing URL for TSA (key: %s)\n", "kTSAContextKeyURL");
-        goto xit;
-    }
-
-    /*
-        If debugging, look at special values in the context to mess things up
-    */
-
-    CFBooleanRef cfBadReq = (CFBooleanRef)CFDictionaryGetValue((CFDictionaryRef)context, kTSADebugContextKeyBadReq);
-    if (cfBadReq && CFBooleanGetValue(cfBadReq))
-    {
-        tsaDebug("[TSA] Forcing bad TS Request by truncating length from %ld to %ld\n", tsaReqLength, (tsaReqLength-4));
-        tsaReqLength -= 4;
-    }
-
-    // need to extract into buffer
-    CFIndex length = CFStringGetLength(url);        // in 16-bit character units
-    tsaURL = malloc(6 * length + 1);                // pessimistic
-    if (!CFStringGetCString(url, (char *)tsaURL, 6 * length + 1, kCFStringEncodingUTF8))
-        goto xit;
-
-    tsaDebug("[TSA] URL for timestamp server: %s\n", tsaURL);
-
-    unsigned char *tsaResp = NULL;
-    size_t tsaRespLength = 0;
-    tsaDebug("calling sendTSARequestWithXPC with %ld bytes of request\n", tsaReqLength);
-
-    require_noerr(result = sendTSARequestWithXPC(tsaReq, tsaReqLength, tsaURL, &tsaResp, &tsaRespLength), xit);
-
-    tsaDebug("sendTSARequestWithXPC copied: %ld bytes of response\n", tsaRespLength);
-
-    signedDERBlob->Data = tsaResp;
-    signedDERBlob->Length = tsaRespLength;
-
-    result = noErr;
-
-xit:
-    if (tsaURL)
-        free((void *)tsaURL);
-    if (cfreq)
-        CFRelease(cfreq);
-
-    return result;
-}
-
-#pragma mark ----- TimeStamp Verification -----
-
-static OSStatus convertGeneralizedTimeToCFAbsoluteTime(const char *timeStr, CFAbsoluteTime *ptime)
-{
-    /*
-        See http://userguide.icu-project.org/formatparse/datetime for date/time format.
-        The "Z" signal a GMT time, but CFDateFormatterGetAbsoluteTimeFromString returns
-        values based on local time.
-    */
-
-    OSStatus result = noErr;
-    CFDateFormatterRef formatter = NULL;
-    CFStringRef time_string = NULL;
-    CFTimeZoneRef gmt = NULL;
-    CFLocaleRef locale = NULL;
-    CFRange *rangep = NULL;
-
-    require(timeStr && timeStr[0] && ptime, xit);
-    require(formatter = CFDateFormatterCreate(kCFAllocatorDefault, locale, kCFDateFormatterNoStyle, kCFDateFormatterNoStyle), xit);
-//    CFRetain(formatter);
-    CFDateFormatterSetFormat(formatter, CFSTR("yyyyMMddHHmmss'Z'"));    // GeneralizedTime
-    gmt = CFTimeZoneCreateWithTimeIntervalFromGMT(NULL, 0);
-       CFDateFormatterSetProperty(formatter, kCFDateFormatterTimeZone, gmt);
-
-    time_string = CFStringCreateWithCString(kCFAllocatorDefault, timeStr, kCFStringEncodingUTF8);
-    if (!time_string || !CFDateFormatterGetAbsoluteTimeFromString(formatter, time_string, rangep, ptime))
-    {
-        dtprintf("%s is not a valid date\n", timeStr);
-        result = 1;
-    }
-
-xit:
-    if (formatter)
-        CFRelease(formatter);
-    if (time_string)
-        CFRelease(time_string);
-    if (gmt)
-        CFRelease(gmt);
-
-    return result;
-}
-
-static OSStatus SecTSAValidateTimestamp(const SecAsn1TSATSTInfo *tstInfo, CSSM_DATA **signingCerts, CFAbsoluteTime *timestampTime)
-{
-    // See <rdar://problem/11077708> Properly handle revocation information of timestamping certificate
-    OSStatus result = paramErr;
-    CFAbsoluteTime genTime = 0;
-    char timeStr[32] = {0,};
-    SecCertificateRef signingCertificate = NULL;
-
-    require(tstInfo && signingCerts && (tstInfo->genTime.Length < 16), xit);
-
-    // Find the leaf signingCert
-    require_noerr(result = SecCertificateCreateFromData(*signingCerts,
-        CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &signingCertificate), xit);
-
-    memcpy(timeStr, tstInfo->genTime.Data, tstInfo->genTime.Length);
-    timeStr[tstInfo->genTime.Length] = 0;
-    require_noerr(convertGeneralizedTimeToCFAbsoluteTime(timeStr, &genTime), xit);
-    if (SecCertificateIsValidX(signingCertificate, genTime)) // iOS?
-        result = noErr;
-    else
-        result = errSecTimestampInvalid;
-    if (timestampTime)
-        *timestampTime = genTime;
-xit:
-    return result;
-}
-
-static OSStatus verifyTSTInfo(const CSSM_DATA_PTR content, CSSM_DATA **signingCerts, SecAsn1TSATSTInfo *tstInfo, CFAbsoluteTime *timestampTime, uint64_t expectedNonce)
-{
-    OSStatus status = paramErr;
-    SecAsn1CoderRef coder = NULL;
-
-    if (!tstInfo)
-        return SECFailure;
-
-    require_noerr(SecAsn1CoderCreate(&coder), xit);
-    require_noerr(SecAsn1Decode(coder, content->Data, content->Length,
-               kSecAsn1TSATSTInfoTemplate, tstInfo), xit);
-    displayTSTInfo(tstInfo);
-
-    // Check the nonce
-    if (tstInfo->nonce.Data && expectedNonce!=0)
-    {
-        uint64_t nonce = tsaDER_ToInt(&tstInfo->nonce);
-     //   if (expectedNonce!=nonce)
-            dtprintf("verifyTSTInfo nonce: actual: %lld, expected: %lld\n", nonce, expectedNonce);
-        require_action(expectedNonce==nonce, xit, status = errSecTimestampRejection);
-    }
-
-    status = SecTSAValidateTimestamp(tstInfo, signingCerts, timestampTime);
-    dtprintf("SecTSAValidateTimestamp result: %ld\n", (long)status);
-
-xit:
-    if (coder)
-        SecAsn1CoderRelease(coder);
-    return status;
-}
-
-static void debugShowExtendedTrustResult(int index, CFDictionaryRef extendedResult)
-{
-#ifndef NDEBUG
-    if (extendedResult)
-    {
-        CFStringRef xresStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
-        CFSTR("Extended trust result for signer #%d : %@"), index, extendedResult);
-        if (xresStr)
-        {
-            CFShow(xresStr);
-            CFRelease(xresStr);
-        }
-    }
-#endif
-}
-
-#ifndef NDEBUG
-extern const char *cssmErrorString(CSSM_RETURN error);
-
-static void statusBitTest(CSSM_TP_APPLE_CERT_STATUS certStatus, uint32 bit, const char *str)
-{
-       if (certStatus & bit)
-               dtprintf("%s  ", str);
-}
-#endif
-
-static void debugShowCertEvidenceInfo(uint16_t certCount, const CSSM_TP_APPLE_EVIDENCE_INFO *info)
-{
-#ifndef NDEBUG
-       CSSM_TP_APPLE_CERT_STATUS cs;
-//     const CSSM_TP_APPLE_EVIDENCE_INFO *pinfo = info;
-    uint16_t ix;
-       for (ix=0; info && (ix<certCount); ix++, ++info)
-    {
-               cs = info->StatusBits;
-               dtprintf("   cert %u:\n", ix);
-               dtprintf("      StatusBits     : 0x%x", (unsigned)cs);
-               if (cs)
-        {
-                       dtprintf(" ( ");
-                       statusBitTest(cs, CSSM_CERT_STATUS_EXPIRED, "EXPIRED");
-                       statusBitTest(cs, CSSM_CERT_STATUS_NOT_VALID_YET,
-                               "NOT_VALID_YET");
-                       statusBitTest(cs, CSSM_CERT_STATUS_IS_IN_INPUT_CERTS,
-                               "IS_IN_INPUT_CERTS");
-                       statusBitTest(cs, CSSM_CERT_STATUS_IS_IN_ANCHORS,
-                               "IS_IN_ANCHORS");
-                       statusBitTest(cs, CSSM_CERT_STATUS_IS_ROOT, "IS_ROOT");
-                       statusBitTest(cs, CSSM_CERT_STATUS_IS_FROM_NET, "IS_FROM_NET");
-                       dtprintf(")\n");
-               }
-               else
-            dtprintf("\n");
-
-               dtprintf("      NumStatusCodes : %u ", info->NumStatusCodes);
-        CSSM_RETURN *pstatuscode = info->StatusCodes;
-               uint16_t jx;
-        for (jx=0; pstatuscode && (jx<info->NumStatusCodes); jx++, ++pstatuscode)
-            dtprintf("%s  ", cssmErrorString(*pstatuscode));
-
-               dtprintf("\n");
-               dtprintf("      Index: %u\n", info->Index);
-       }
-
-#endif
-}
-
-#ifndef NDEBUG
-static const char *trustResultTypeString(SecTrustResultType trustResultType)
-{
-    switch (trustResultType)
-    {
-    case kSecTrustResultProceed:                    return "TrustResultProceed";
-    case kSecTrustResultUnspecified:                return "TrustResultUnspecified";
-    case kSecTrustResultDeny:                       return "TrustResultDeny";   // user reject
-    case kSecTrustResultInvalid:                    return "TrustResultInvalid";
-    case kSecTrustResultConfirm:                    return "TrustResultConfirm";
-    case kSecTrustResultRecoverableTrustFailure:    return "TrustResultRecoverableTrustFailure";
-    case kSecTrustResultFatalTrustFailure:          return "TrustResultUnspecified";
-    case kSecTrustResultOtherError:                 return "TrustResultOtherError";
-    default:                                        return "TrustResultUnknown";
-    }
-    return "";
-}
-#endif
-
-static OSStatus verifySigners(SecCmsSignedDataRef signedData, int numberOfSigners)
-{
-    // See <rdar://problem/11077588> Bubble up SecTrustEvaluate of timestamp response to high level callers
-    // Also <rdar://problem/11077708> Properly handle revocation information of timestamping certificate
-
-    SecPolicyRef policy = NULL;
-    int result=errSecInternalError;
-    int rx;
-
-    require(policy = SecPolicyCreateWithOID(kSecPolicyAppleTimeStamping), xit);
-    int jx;
-    for (jx = 0; jx < numberOfSigners; ++jx)
-    {
-        SecTrustResultType trustResultType;
-        SecTrustRef trustRef = NULL;
-        CFDictionaryRef extendedResult = NULL;
-        CFArrayRef certChain = NULL;
-        uint16_t certCount = 0;
-
-        CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
-
-        // SecCmsSignedDataVerifySignerInfo returns trustRef, which we can call SecTrustEvaluate on
-        // usually (always?) if result is noErr, the SecTrust*Result calls will return errSecTrustNotAvailable
-        result = SecCmsSignedDataVerifySignerInfo (signedData, jx, NULL, policy, &trustRef);
-        dtprintf("[%s] SecCmsSignedDataVerifySignerInfo: result: %d, signer: %d\n",
-            __FUNCTION__, result, jx);
-         require_noerr(result, xit);
-
-        result = SecTrustEvaluate (trustRef, &trustResultType);
-        dtprintf("[%s] SecTrustEvaluate: result: %d, trustResult: %s (%d)\n",
-            __FUNCTION__, result, trustResultTypeString(trustResultType), trustResultType);
-        if (result)
-            goto xit;
-        switch (trustResultType)
-        {
-               case kSecTrustResultProceed:
-               case kSecTrustResultUnspecified:
-                       break;                                  // success
-               case kSecTrustResultDeny:                   // user reject
-                       result = errSecTimestampNotTrusted;     // SecCmsVSTimestampNotTrusted ?
-            break;
-               case kSecTrustResultInvalid:
-                       assert(false);                          // should never happen
-                       result = errSecTimestampNotTrusted;     // SecCmsVSTimestampNotTrusted ?
-            break;
-        case kSecTrustResultConfirm:
-        case kSecTrustResultRecoverableTrustFailure:
-        case kSecTrustResultFatalTrustFailure:
-        case kSecTrustResultOtherError:
-               default:
-                       {
-                /*
-                    There are two "errors" that need to be resolved externally:
-                    CSSMERR_TP_CERT_EXPIRED can be OK if the timestamp was made
-                    before the TSA chain expired; CSSMERR_TP_CERT_NOT_VALID_YET
-                    can happen in the case where the user's clock was set to 0.
-                    We don't want to prevent them using apps automatically, so
-                    return noErr and let codesign or whover decide.
-                */
-                               OSStatus resultCode;
-                               require_action(SecTrustGetCssmResultCode(trustRef, &resultCode)==noErr, xit, result = errSecTimestampNotTrusted);
-                               result = (resultCode == CSSMERR_TP_CERT_EXPIRED || resultCode == CSSMERR_TP_CERT_NOT_VALID_YET)?noErr:errSecTimestampNotTrusted;
-                       }
-            break;
-               }
-
-        rx = SecTrustGetResult(trustRef, &trustResultType, &certChain, &statusChain);
-        dtprintf("[%s] SecTrustGetResult: result: %d, type: %d\n", __FUNCTION__,rx, trustResultType);
-        certCount = certChain?CFArrayGetCount(certChain):0;
-        debugShowCertEvidenceInfo(certCount, statusChain);
-
-        rx = SecTrustCopyExtendedResult(trustRef, &extendedResult);
-        dtprintf("[%s] SecTrustCopyExtendedResult: result: %d\n", __FUNCTION__, rx);
-        if (extendedResult)
-        {
-            debugShowExtendedTrustResult(jx, extendedResult);
-            CFRelease(extendedResult);
-        }
-
-        if (trustRef)
-            CFRelease (trustRef);
-     }
-
-xit:
-    if (policy)
-        CFRelease (policy);
-    return result;
-}
-
-static OSStatus impExpImportCertUnCommon(
-       const CSSM_DATA         *cdata,
-       SecKeychainRef          importKeychain, // optional
-       CFMutableArrayRef       outArray)               // optional, append here
-{
-    // The only difference between this and impExpImportCertCommon is that we append to outArray
-    // before attempting to add to the keychain
-       OSStatus status = noErr;
-       SecCertificateRef certRef = NULL;
-
-    require_action(cdata, xit, status = errSecUnsupportedFormat);
-
-       /* Pass kCFAllocatorNull as bytesDeallocator to assure the bytes aren't freed */
-       CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)cdata->Data, (CFIndex)cdata->Length, kCFAllocatorNull);
-    require_action(data, xit, status = errSecUnsupportedFormat);
-
-       certRef = SecCertificateCreateWithData(kCFAllocatorDefault, data);
-       CFRelease(data); /* certRef has its own copy of the data now */
-       if(!certRef) {
-               dtprintf("impExpHandleCert error\n");
-               return errSecUnsupportedFormat;
-       }
-
-       if (outArray)
-               CFArrayAppendValue(outArray, certRef);
-
-       if (importKeychain)
-    {
-               status = SecCertificateAddToKeychain(certRef, importKeychain);
-               if (status!=noErr && status!=errSecDuplicateItem)
-            { dtprintf("SecCertificateAddToKeychain error: %ld\n", (long)status); }
-       }
-
-xit:
-    if (certRef)
-        CFRelease(certRef);
-       return status;
-}
-
-static void saveTSACertificates(CSSM_DATA **signingCerts, CFMutableArrayRef    outArray)
-{
-    SecKeychainRef defaultKeychain = NULL;
-    // Don't save certificates in keychain to avoid securityd issues
-//  if (SecKeychainCopyDefault(&defaultKeychain))
-//     defaultKeychain = NULL;
-
-    unsigned certCount = SecCmsArrayCount((void **)signingCerts);
-    unsigned dex;
-    for (dex=0; dex<certCount; dex++)
-    {
-        OSStatus rx = impExpImportCertUnCommon(signingCerts[dex], defaultKeychain, outArray);
-        if (rx!=noErr && rx!=errSecDuplicateItem)
-            dtprintf("impExpImportCertCommon failed: %ld\n", (long)rx);
-    }
-    if (defaultKeychain)
-        CFRelease(defaultKeychain);
-}
-
-static const char *cfabsoluteTimeToString(CFAbsoluteTime abstime)
-{
-    CFGregorianDate greg = CFAbsoluteTimeGetGregorianDate(abstime, NULL);
-    char str[20];
-    if (19 != snprintf(str, 20, "%4.4d-%2.2d-%2.2d_%2.2d:%2.2d:%2.2d",
-        (int)greg.year, greg.month, greg.day, greg.hour, greg.minute, (int)greg.second))
-        str[0]=0;
-    char *data = (char *)malloc(20);
-    strncpy(data, str, 20);
-    return data;
-}
-
-static OSStatus setTSALeafValidityDates(SecCmsSignerInfoRef signerinfo)
-{
-    OSStatus status = noErr;
-
-    if (!signerinfo->timestampCertList || (CFArrayGetCount(signerinfo->timestampCertList) == 0))
-        return SecCmsVSSigningCertNotFound;
-
-    SecCertificateRef tsaLeaf = (SecCertificateRef)CFArrayGetValueAtIndex(signerinfo->timestampCertList, 0);
-    require_action(tsaLeaf, xit, status = errSecCertificateCannotOperate);
-
-    signerinfo->tsaLeafNotBefore = SecCertificateNotValidBefore(tsaLeaf); /* Start date for Timestamp Authority leaf */
-    signerinfo->tsaLeafNotAfter = SecCertificateNotValidAfter(tsaLeaf);   /* Expiration date for Timestamp Authority leaf */
-
-    const char *nbefore = cfabsoluteTimeToString(signerinfo->tsaLeafNotBefore);
-    const char *nafter = cfabsoluteTimeToString(signerinfo->tsaLeafNotAfter);
-    if (nbefore && nafter)
-    {
-        dtprintf("Timestamp Authority leaf valid from %s to %s\n", nbefore, nafter);
-        free((void *)nbefore);free((void *)nafter);
-    }
-
-/*
-               if(at < nb)
-                       status = errSecCertificateNotValidYet;
-               else if (at > na)
-                       status = errSecCertificateExpired;
-*/
-
-xit:
-    return status;
-}
-
-/*
-    From RFC 3161: Time-Stamp Protocol (TSP),August 2001, APPENDIX B:
-
-    B) The validity of the digital signature may then be verified in the
-        following way:
-
-        1)  The time-stamp token itself MUST be verified and it MUST be
-            verified that it applies to the signature of the signer.
-
-        2)  The date/time indicated by the TSA in the TimeStampToken
-            MUST be retrieved.
-
-        3)  The certificate used by the signer MUST be identified and
-            retrieved.
-
-        4)  The date/time indicated by the TSA MUST be within the
-            validity period of the signer's certificate.
-
-        5)  The revocation information about that certificate, at the
-            date/time of the Time-Stamping operation, MUST be retrieved.
-
-        6)  Should the certificate be revoked, then the date/time of
-            revocation shall be later than the date/time indicated by
-            the TSA.
-
-    If all these conditions are successful, then the digital signature
-    shall be declared as valid.
-
-*/
-
-OSStatus decodeTimeStampToken(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR inData, CSSM_DATA_PTR encDigest, uint64_t expectedNonce)
-{
-    /*
-        We update signerinfo with timestamp and tsa certificate chain.
-        encDigest is the original signed blob, which we must hash and compare.
-        inData comes from the unAuthAttr section of the CMS message
-
-        These are set in signerinfo as side effects:
-            timestampTime -
-            timestampCertList
-    */
-
-    SecCmsDecoderRef        decoderContext = NULL;
-    SecCmsMessageRef        cmsMessage = NULL;
-    SecCmsContentInfoRef    contentInfo;
-    SecCmsSignedDataRef     signedData;
-    SECOidTag               contentTypeTag;
-    int                     contentLevelCount;
-    int                     ix;
-    OSStatus                result = errSecUnknownFormat;
-    CSSM_DATA               **signingCerts = NULL;
-
-    dtprintf("decodeTimeStampToken top: PORT_GetError() %d -----\n", PORT_GetError());
-    PORT_SetError(0);
-
-    /* decode the message */
-    require_noerr(result = SecCmsDecoderCreate (NULL, NULL, NULL, NULL, NULL, NULL, NULL, &decoderContext), xit);
-    result = SecCmsDecoderUpdate(decoderContext, inData->Data, inData->Length);
-       if (result)
-    {
-        result = errSecTimestampInvalid;
-        SecCmsDecoderDestroy(decoderContext);
-        goto xit;
-       }
-
-    require_noerr(result = SecCmsDecoderFinish(decoderContext, &cmsMessage), xit);
-
-    // process the results
-    contentLevelCount = SecCmsMessageContentLevelCount(cmsMessage);
-
-    if (encDigest)
-        printDataAsHex("encDigest",encDigest, 0);
-
-    for (ix = 0; ix < contentLevelCount; ++ix)
-    {
-        dtprintf("\n----- Content Level %d -----\n", ix);
-        // get content information
-        contentInfo = SecCmsMessageContentLevel (cmsMessage, ix);
-        contentTypeTag = SecCmsContentInfoGetContentTypeTag (contentInfo);
-
-        // After 2nd round, contentInfo.content.data is the TSTInfo
-
-        debugShowContentTypeOID(contentInfo);
-
-        switch (contentTypeTag)
-        {
-        case SEC_OID_PKCS7_SIGNED_DATA:
-        {
-            require((signedData = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(contentInfo)) != NULL, xit);
-
-            debugShowSignerInfo(signedData);
-
-            SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData);
-            unsigned digestAlgCount = SecCmsArrayCount((void **)digestAlgorithms);
-            dtprintf("digestAlgCount: %d\n", digestAlgCount);
-            if (signedData->digests)
-            {
-                int jx;
-                char buffer[128];
-                for (jx=0;jx < digestAlgCount;jx++)
-                {
-                    sprintf(buffer, " digest[%u]", jx);
-                    printDataAsHex(buffer,signedData->digests[jx], 0);
-                }
-            }
-            else
-            {
-                dtprintf("No digests\n");
-                CSSM_DATA_PTR innerContent = SecCmsContentInfoGetInnerContent(contentInfo);
-                if (innerContent)
-                {
-                    dtprintf("inner content length: %ld\n", innerContent->Length);
-                    SecAsn1TSAMessageImprint fakeMessageImprint = {{{0}},};
-                    OSStatus status = createTSAMessageImprint(signedData, innerContent, &fakeMessageImprint);
-                    if (status)
-                        {    dtprintf("createTSAMessageImprint status: %d\n", (int)status); }
-                    printDataAsHex("inner content hash",&fakeMessageImprint.hashedMessage, 0);
-                    CSSM_DATA_PTR digestdata = &fakeMessageImprint.hashedMessage;
-                    CSSM_DATA_PTR digests[2] = {digestdata, NULL};
-                    SecCmsSignedDataSetDigests(signedData, digestAlgorithms, (CSSM_DATA_PTR *)&digests);
-                }
-                else
-                    dtprintf("no inner content\n");
-            }
-
-            /*
-                Import the certificates. We leave this as a warning, since
-                there are configurations where the certificates are not returned.
-            */
-            signingCerts = SecCmsSignedDataGetCertificateList(signedData);
-            if (signingCerts == NULL)
-            {    dtprintf("SecCmsSignedDataGetCertificateList returned NULL\n"); }
-            else
-            {
-                if (!signerinfo->timestampCertList)
-                    signerinfo->timestampCertList = CFArrayCreateMutable(kCFAllocatorDefault, 10, &kCFTypeArrayCallBacks);
-                saveTSACertificates(signingCerts, signerinfo->timestampCertList);
-                require_noerr(result = setTSALeafValidityDates(signerinfo), xit);
-                debugSaveCertificates(signingCerts);
-            }
-
-            int numberOfSigners = SecCmsSignedDataSignerInfoCount (signedData);
-
-            result = verifySigners(signedData, numberOfSigners);
-            if (result)
-                dtprintf("verifySigners failed: %ld\n", (long)result);   // warning
-
-
-            if (result)     // remap to SecCmsVSTimestampNotTrusted ?
-                goto xit;
-
-            break;
-        }
-        case SEC_OID_PKCS9_SIGNING_CERTIFICATE:
-        {
-            dtprintf("SEC_OID_PKCS9_SIGNING_CERTIFICATE seen\n");
-            break;
-        }
-
-        case SEC_OID_PKCS9_ID_CT_TSTInfo:
-        {
-            SecAsn1TSATSTInfo tstInfo = {{0},};
-            result = verifyTSTInfo(contentInfo->rawContent, signingCerts, &tstInfo, &signerinfo->timestampTime, expectedNonce);
-            if (signerinfo->timestampTime)
-            {
-                const char *tstamp = cfabsoluteTimeToString(signerinfo->timestampTime);
-                if (tstamp)
-                {
-                    dtprintf("Timestamp Authority timestamp: %s\n", tstamp);
-                    free((void *)tstamp);
-                }
-            }
-            break;
-        }
-        case SEC_OID_OTHER:
-        {
-            dtprintf("otherContent : %p\n", (char *)SecCmsContentInfoGetContent (contentInfo));
-            break;
-        }
-        default:
-            dtprintf("ContentTypeTag : %x\n", contentTypeTag);
-            break;
-        }
-    }
-xit:
-       if (cmsMessage)
-               SecCmsMessageDestroy(cmsMessage);
-
-    return result;
-}
-
-