]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/clxutils/newCmsTool/newCmsTool.cpp
Security-57740.51.3.tar.gz
[apple/security.git] / SecurityTests / clxutils / newCmsTool / newCmsTool.cpp
diff --git a/SecurityTests/clxutils/newCmsTool/newCmsTool.cpp b/SecurityTests/clxutils/newCmsTool/newCmsTool.cpp
deleted file mode 100644 (file)
index 3398e1b..0000000
+++ /dev/null
@@ -1,1658 +0,0 @@
-/*
- * cmstool.cpp - manipulate CMS messages, CMSEncoder/CMSDecoder version
- */
-#include <Security/Security.h>
-#include <security_cdsa_utils/cuFileIo.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <utilLib/common.h>
-#include <security_cdsa_utils/cuFileIo.h>
-#include <security_cdsa_utils/cuPrintCert.h>
-#include <clAppUtils/identPicker.h>
-#include <clAppUtils/sslAppUtils.h>
-#include <security_cdsa_utils/cuOidParser.h>
-#include <CoreFoundation/CoreFoundation.h>
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
-#include <Security/SecTrustPriv.h>             /* SecTrustGetCssmResultCode */
-#include <Security/SecIdentityPriv.h>  /* SecIdentityCreateWithCertificate */
-#include <Security/CMSEncoder.h>
-#include <Security/CMSDecoder.h>
-#include <Security/CMSPrivate.h>
-
-#include <Security/SecCertificate.h>
-#include <Security/oidsattr.h>
-
-#define CFRELEASE(cfr) if(cfr != NULL) { CFRelease(cfr); }
-
-static SecKeychainRef keychain_open(const char *name);
-
-static void usage(char **argv)
-{
-    printf("Usage: %s cmd [option ...]\n", argv[0]);
-       printf("cmd values:\n");
-       printf("   sign                 -- create signedData\n");
-       printf("   envel                -- create envelopedData\n");
-       printf("   signEnv              -- create nested EnvelopedData(signedData(data))\n");
-       printf("   certs                -- create certs-only CMS msg\n");
-       printf("   parse                -- parse a CMS message file\n");
-       printf("Input/output options:\n");
-       printf("   -i infile\n");
-       printf("   -o outfile\n");
-       printf("   -D detachedContent   -- detached content (parse only)\n");
-       printf("   -d detached          -- infile contains detached content (sign only)\n");
-       printf("   -f certFileBase      -- dump all certs to certFileBase\n");
-       printf("Signer and recipient options:\n");
-       printf("   -k keychain          -- Keychain to search for certs\n");
-       printf("   -p                   -- Use identity picker\n");
-       printf("   -r recipient         -- add recipient (via email address) of enveloped data\n");
-       printf("   -R recipCertFile     -- add recipient (via cert from file) of enveloped data\n");
-       printf("   -S signerEmail       -- add signer email address\n");
-       printf("   -C cert              -- add (general) signedData cert\n"); 
-       printf("Misc. options:\n");
-       printf("   -e eContentType      -- a(uthData)|r(keyData)\n");
-       printf("   -m                   -- multi updates; default is one-shot\n");
-       printf("   -1 (one)             -- custom encoder/decoder\n");
-       printf("   -2                   -- fetch SecCmsMessageRef\n");
-       printf("   -c                   -- parse signer certs\n");
-       printf("   -a [ceEt]            -- Signed Attributes: c=SmimeCaps,\n");
-       printf("                           e=EncrPrefs, E=MSEncrPrefs, t=signingTime\n");
-       printf("   -A anchorFile        -- Verify certs using specified anchor cert\n");
-       printf("   -M                   -- Do SecTrustEvaluate manually\n");
-       printf("   -t certChainMode     -- none|signer|chain|chainWithRoot; default is chain\n");
-       printf("   -l                   -- loop & pause for malloc debug\n");
-       printf("   -q                   -- quiet\n");
-       printf("   -Z                   -- silent, no output at all except for errors\n");
-       printf("Verification options:\n");
-       printf("   -v sign|encr|signEnv -- verify message is signed/encrypted/both\n");
-       printf("   -s numSigners        -- verify msg has specified number of signers\n");
-       printf("   -E eContentType      -- verify a(authData)|r(keyData)|d(data)\n");
-       printf("   -N numCerts          -- verify number of certs\n");
-       exit(1);
-}
-
-/* high level op */
-typedef enum {
-       CTO_Sign,
-       CTO_Envelop,
-       CTO_SignEnvelop,
-       CTO_CertsOnly,
-       CTO_Parse
-} CT_Op;
-
-/* to verify */
-typedef enum {
-       CTV_None,
-       CTV_Sign,
-       CTV_Envelop,
-       CTV_SignEnvelop
-} CT_Vfy;
-
-/* additional OIDS to specify as eContentType */
-#define OID_PKINIT     0x2B, 6, 1, 5, 2, 3
-#define OID_PKINIT_LEN 6
-
-static const uint8     OID_PKINIT_AUTH_DATA[]      = {OID_PKINIT, 1};
-static const uint8     OID_PKINIT_DH_KEY_DATA[]    = {OID_PKINIT, 2};
-static const uint8     OID_PKINIT_RKEY_DATA[]      = {OID_PKINIT, 3};
-static const uint8     OID_PKINIT_KP_CLIENTAUTH[]  = {OID_PKINIT, 3};
-static const uint8     OID_PKINIT_KPKDC[]                      = {OID_PKINIT, 5};
-
-static const CSSM_OID  CSSMOID_PKINIT_AUTH_DATA = 
-       {OID_PKINIT_LEN+1, (uint8 *)OID_PKINIT_AUTH_DATA};
-static const CSSM_OID  CSSMOID_PKINIT_DH_KEY_DATA =
-       {OID_PKINIT_LEN+1, (uint8 *)OID_PKINIT_DH_KEY_DATA};
-static const CSSM_OID  CSSMOID_PKINIT_RKEY_DATA = 
-       {OID_PKINIT_LEN+1, (uint8 *)OID_PKINIT_RKEY_DATA};
-static const CSSM_OID  CSSMOID_PKINIT_KP_CLIENTAUTH =
-       {OID_PKINIT_LEN+1, (uint8 *)OID_PKINIT_KP_CLIENTAUTH};
-static const CSSM_OID  CSSMOID_PKINIT_KPKDC = 
-       {OID_PKINIT_LEN+1, (uint8 *)OID_PKINIT_KPKDC};
-
-/*
- * Find a cert in specified keychain or keychain list matching specified 
- * email address. We happen to know that the email address is stored with the 
- * kSecAlias attribute. 
- */
-static OSStatus findCert(
-       const char *emailAddress,
-       CFTypeRef kcArArray,                    // kc, array, or even NULL
-       SecCertificateRef *cert)
-{
-       OSStatus                                        ortn;
-       SecKeychainSearchRef            srch;
-       SecKeychainAttributeList        attrList;
-       SecKeychainAttribute            attr;
-       
-       attr.tag = kSecAlias;
-       attr.length = strlen(emailAddress);
-       attr.data = (void *)emailAddress;
-       attrList.count = 1;
-       attrList.attr = &attr;
-       
-       ortn = SecKeychainSearchCreateFromAttributes(kcArArray,
-               kSecCertificateItemClass,
-               &attrList,
-               &srch);
-       if(ortn) {
-               cssmPerror("SecKeychainSearchCreateFromAttributes", ortn);
-               return ortn;
-       }
-       
-       ortn = SecKeychainSearchCopyNext(srch, (SecKeychainItemRef *)cert);
-       if(ortn) {
-               printf("***No certs found matching recipient %s. Aborting.\n",
-                       emailAddress);
-               return ortn;
-       }
-       CFRelease(srch);
-       return noErr;
-}
-
-/* create a SecCertificateRef from a file */
-static SecCertificateRef readCertFile(
-       const char *fileName)
-{
-       unsigned char *certData = NULL;
-       unsigned certDataLen;
-       SecCertificateRef rtnCert = NULL;
-       
-       if(readFile(fileName, &certData, &certDataLen)) {
-               printf("***Error reading %s. Aborting.\n", fileName);
-               return NULL;
-       }
-       CSSM_DATA cssmCert = {certDataLen, (uint8 *)certData};
-       OSStatus ortn = SecCertificateCreateFromData(&cssmCert, 
-               CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER,
-               &rtnCert);
-       if(ortn) {
-               cssmPerror("SecCertificateCreateFromData", ortn);
-               printf("***Error creating cert fromn %s. Aborting.\n", fileName);
-       }
-       free(certData);
-       return rtnCert;
-}
-
-static int dumpCertFiles(
-       CFArrayRef allCerts,
-       const char *fileBase,
-       bool quiet)
-{
-       char fileName[200];
-       
-       if(allCerts == NULL) {
-               printf("...no certs to write.\n");
-               return 0;
-       }
-       CFIndex numCerts = CFArrayGetCount(allCerts);
-       if(numCerts == 0) {
-               printf("...no certs to write.\n");
-               return 0;
-       }
-       for(CFIndex dex=0; dex<numCerts; dex++) {
-               SecCertificateRef secCert = 
-                       (SecCertificateRef)CFArrayGetValueAtIndex(allCerts, dex);
-               CSSM_DATA certData;
-               OSStatus ortn;
-               
-               ortn = SecCertificateGetData(secCert, &certData);
-               if(ortn) {
-                       cssmPerror("SecCertificateGetData", ortn);
-                       return -1;
-               }       
-               sprintf(fileName, "%s_%u.cer", fileBase, (unsigned)dex);
-               if(writeFile(fileName, certData.Data, certData.Length)) {
-                       printf("***Error writing cert data to %s. Aborting.\n", fileName);
-                       return 1;
-               }
-               else if(!quiet) {
-                       printf("...wrote %u bytes to %s.\n",
-                               (unsigned)certData.Length, fileName);
-               }
-       }
-       return 0;
-}
-
-/*
- * Do a random number of random-sized updates on a CMSEncoder.
- */
-static OSStatus updateEncoder(
-       CMSEncoderRef cmsEncoder,
-       const unsigned char *inData,
-       unsigned inDataLen)
-{
-       unsigned toMove = inDataLen;
-       unsigned thisMove;
-       
-       while(toMove != 0) {
-               thisMove = genRand(1, toMove);
-               OSStatus ortn = CMSEncoderUpdateContent(cmsEncoder, inData, thisMove);
-               if(ortn) {
-                       cssmPerror("CMSEncoderUpdateContent", ortn);
-                       return ortn;
-               }
-               toMove -= thisMove;
-               inData += thisMove;
-       }
-       return noErr;
-}
-
-/*
- * Do a random number of random-sized updates on a CMSDecoder.
- */
-static OSStatus updateDecoder(
-       CMSDecoderRef cmsDecoder,
-       const unsigned char *inData,
-       unsigned inDataLen)
-{
-       unsigned toMove = inDataLen;
-       unsigned thisMove;
-       
-       while(toMove != 0) {
-               thisMove = genRand(1, toMove);
-               OSStatus ortn = CMSDecoderUpdateMessage(cmsDecoder, inData, thisMove);
-               if(ortn) {
-                       cssmPerror("CMSDecoderUpdateMessage", ortn);
-                       return ortn;
-               }
-               toMove -= thisMove;
-               inData += thisMove;
-       }
-       return noErr;
-}
-
-#define TRUST_STRING_MAX       128
-
-static OSStatus evalSecTrust(
-       SecTrustRef                     secTrust,
-       CFMutableArrayRef       anchorArray,            // optional
-       char                            *trustStr,                      // caller-mallocd, TRUST_STRING_MAX chars
-       bool                            quiet)
-{
-       OSStatus ortn;
-       SecTrustResultType                      secTrustResult;
-       
-       if(anchorArray) {
-               ortn  = SecTrustSetAnchorCertificates(secTrust, anchorArray);
-               if(ortn) {
-                       /* should never happen */
-                       cssmPerror("SecTrustSetAnchorCertificates", ortn);
-                       return ortn;
-               }
-       }
-       ortn = SecTrustEvaluate(secTrust, &secTrustResult);
-       if(ortn) {
-               /* should never happen */
-               cssmPerror("SecTrustEvaluate", ortn);
-               return ortn;
-       }
-       switch(secTrustResult) {
-               case kSecTrustResultUnspecified:
-                       /* cert chain valid, no special UserTrust assignments */
-               case kSecTrustResultProceed:
-                       /* cert chain valid AND user explicitly trusts this */
-                       sprintf(trustStr, "Successful\n");
-                       return noErr;
-               case kSecTrustResultDeny:
-               case kSecTrustResultConfirm:
-                       /*
-                        * Cert chain may well have verified OK, but user has flagged
-                        * one of these certs as untrustable.
-                        */
-                       sprintf(trustStr, "Not trusted per user-specified Trust level\n");
-                       /* bogus return code I know */
-                       return errSecInvalidTrustSetting;
-               default:
-               {
-                       /* get low-level TP error */
-                       OSStatus tpStatus;
-                       ortn = SecTrustGetCssmResultCode(secTrust, &tpStatus);
-                       if(ortn) {
-                               cssmPerror("SecTrustGetCssmResultCode", ortn);
-                               return ortn;
-                       }
-                       switch(tpStatus) {
-                               case CSSMERR_TP_INVALID_ANCHOR_CERT: 
-                                       sprintf(trustStr, "Untrusted root\n");
-                                       break;
-                               case CSSMERR_TP_NOT_TRUSTED:
-                                       /* no root, not even in implicit SSL roots */
-                                       sprintf(trustStr, "No root cert found\n");
-                                       break;
-                               case CSSMERR_TP_CERT_EXPIRED:
-                                       sprintf(trustStr, "Expired cert\n");
-                                       break;
-                               case CSSMERR_TP_CERT_NOT_VALID_YET:
-                                       sprintf(trustStr, "Cert not valid yet\n");
-                                       break;
-                               default:
-                                       sprintf(trustStr, "Other cert failure (%s)",
-                                               cssmErrToStr(tpStatus));
-                                       break;
-                       }
-                       return tpStatus;
-               }
-       }       /* SecTrustEvaluate error */
-       /* NOT REACHED */
-}
-
-static OSStatus doParse(
-       const unsigned char *data,
-       unsigned                        dataLen,
-       const unsigned char *detachedContent,
-       unsigned                        detachedContentLen,
-       bool                            multiUpdate,
-       CT_Vfy                          vfyOp,
-       const CSSM_OID          *eContentVfy,   // optional to verify
-       int                                     numSignersVfy,  // optional (>=0) to verify
-       int                                     numCertsVfy,    // optionjal (>= 0) to verify
-       bool                            parseSignerCert,
-       const char                      *certFileBase,  // optionally write certs here
-       bool                            customDecoder,  // invoke CMSDecoderSetDecoder()
-       bool                            manTrustEval,   // evaluate SecTrust ourself
-       CFMutableArrayRef       anchorArray,    // optional, and only for manTrustEval
-       bool                            quiet,
-       CFDataRef                       *outData)               // RETURNED 
-{
-       if((data == NULL) || (dataLen == 0)) {
-               fprintf(stderr, "***Parse requires input file. Aborting.\n");
-               return paramErr;
-       }
-       
-       CMSDecoderRef cmsDecoder;
-       size_t numSigners;
-       Boolean isEncrypted;
-       CFArrayRef allCerts = NULL;
-       unsigned signerDex;
-       SecPolicyRef policy = NULL;
-       SecPolicySearchRef policySearch = NULL;
-       CFIndex numCerts = 0;
-       int addDetachedAfterDecode = 0;
-       SecArenaPoolRef arena = NULL;
-       
-       /* 
-        * Four different return codes:
-        * -- ortn used for function returns; if nonzero, bail immediately and goto errOut
-        * -- ourRtn is manually set per the output of CMSDecoderCopySignerStatus and 
-        *    evalSecTrust
-        * -- trustRtn is the output of manual SecTrustEvaluate (via evalSecTrust())
-        * -- vfyErr indicates mismatch in caller-specified error params
-        *
-        * All four have to be zero fgor us to return zero.
-        */
-       OSStatus ourRtn = noErr;
-       OSStatus ortn = noErr;
-       OSStatus trustRtn = noErr;
-       int vfyErr = 0;
-       
-       ortn = CMSDecoderCreate(&cmsDecoder);
-       if(ortn) {
-               cssmPerror("CMSDecoderCreate", ortn);
-               return ortn;
-       }
-       
-       /* subsequent errors to errOut: */
-       
-       if(detachedContent != NULL) {
-               /* 
-                * We can add detached content either before or after the 
-                * update/finalize; to test and verify, flip a coin to decide 
-                * when to do it.
-                */
-               addDetachedAfterDecode = genRand(0, 1);
-               if(!addDetachedAfterDecode) {
-                       CFDataRef cfDetach = CFDataCreate(NULL, detachedContent, detachedContentLen);
-                       ortn = CMSDecoderSetDetachedContent(cmsDecoder, cfDetach);
-                       CFRelease(cfDetach);
-                       if(ortn) {
-                               cssmPerror("CMSDecoderSetDetachedContent", ortn);
-                               goto errOut;
-                       }
-               }
-       }
-       
-       if(customDecoder) {
-               /* Create a decoder; we don't have to free it, but we do have to free the
-                * arena pool */
-               SecCmsDecoderRef coder = NULL;
-               
-               ortn = SecArenaPoolCreate(1024, &arena);
-               if(ortn) {
-                       cssmPerror("SecArenaPoolCreate", ortn);
-                       goto errOut;
-               }
-               ortn = SecCmsDecoderCreate(arena, 
-                       NULL, NULL, NULL, NULL, NULL, NULL, &coder);
-               if(ortn) {
-                       cssmPerror("SecCmsDecoderCreate", ortn);
-                       goto errOut;
-               }
-               ortn = CMSDecoderSetDecoder(cmsDecoder, coder);
-               if(ortn) {
-                       cssmPerror("CMSDecoderSetDecoder", ortn);
-                       goto errOut;
-               }
-               else if(!quiet) {
-                       printf("...set up custom SecCmsDecoderRef\n");
-               }
-       }
-       if(multiUpdate) {
-               ortn = updateDecoder(cmsDecoder, data, dataLen);
-               if(ortn) {
-                       goto errOut;
-               }
-       }
-       else {
-               ortn = CMSDecoderUpdateMessage(cmsDecoder, data, dataLen);
-               if(ortn) {
-                       cssmPerror("CMSDecoderUpdateMessage", ortn);
-                       goto errOut;
-               }
-       }
-       ortn = CMSDecoderFinalizeMessage(cmsDecoder);
-       if(ortn) {
-               cssmPerror("CMSDecoderFinalizeMessage", ortn);
-               goto errOut;
-       }
-       if(addDetachedAfterDecode) {
-               CFDataRef cfDetach = CFDataCreate(NULL, detachedContent, detachedContentLen);
-               ortn = CMSDecoderSetDetachedContent(cmsDecoder, cfDetach);
-               CFRelease(cfDetach);
-               if(ortn) {
-                       cssmPerror("CMSDecoderSetDetachedContent", ortn);
-                       goto errOut;
-               }
-       }
-       ortn = CMSDecoderGetNumSigners(cmsDecoder, &numSigners);
-       if(ortn) {
-               cssmPerror("CMSDecoderGetNumSigners", ortn);
-               goto errOut;
-       }
-       ortn = CMSDecoderIsContentEncrypted(cmsDecoder, &isEncrypted);
-       if(ortn) {
-               cssmPerror("CMSDecoderIsContentEncrypted", ortn);
-               goto errOut;
-       }
-       ortn = CMSDecoderCopyAllCerts(cmsDecoder, &allCerts);
-       if(ortn) {
-               cssmPerror("CMSDecoderCopyAllCerts", ortn);
-               goto errOut;
-       }
-       if(allCerts) {
-               numCerts = CFArrayGetCount(allCerts);
-       }
-       
-       /* optional verify of expected message type */
-       switch(vfyOp) {
-               case CTV_None:
-                       break;
-               case CTV_Sign: 
-                       if((numSigners == 0) && (allCerts == NULL)) {
-                               fprintf(stderr, "***Expected SignedData, but no signersFound\n");
-                               vfyErr = 1;
-                               /* but keep going */
-                       }
-                       if(isEncrypted) {
-                               fprintf(stderr, "***Expected SignedData, but msg IS encrypted\n");
-                               vfyErr = 1;
-                       }
-                       break;
-               case CTV_SignEnvelop:
-                       if(numSigners == 0) {
-                               fprintf(stderr, "***Expected Signed&Enveloped, but no signersFound\n");
-                               vfyErr = 1;
-                       }
-                       if(!isEncrypted) {
-                               fprintf(stderr, "***Expected Signed&Enveloped, but msg not encrypted\n");
-                               vfyErr = 1;
-                       }
-                       break;
-               case CTV_Envelop:
-                       if(numSigners != 0) {
-                               fprintf(stderr, "***Expected EnvelopedData, but signers found\n");
-                               vfyErr = 1;
-                       }
-                       if(!isEncrypted) {
-                               fprintf(stderr, "***Expected EnvelopedData, but msg not encrypted\n");
-                               vfyErr = 1;
-                       }
-                       break;
-       }
-
-       if(numSignersVfy >= 0) {
-               if((unsigned)numSignersVfy != numSigners) {
-                       fprintf(stderr, "***Expected %d signers; found %lu\n",
-                               numSignersVfy, numSigners);
-                       vfyErr = 1;
-               }
-       }
-       if(numCertsVfy >= 0) {
-               if((int)numCerts != numCertsVfy) {
-                       fprintf(stderr, "***Expected %d certs; found %d\n",
-                               numCertsVfy, (int)numCerts);
-                       vfyErr = 1;
-               }
-       }
-       if(!quiet) {
-               fprintf(stderr, "=== CMS message info ===\n");
-               fprintf(stderr, "   Num Signers      : %lu\n", (unsigned long)numSigners);
-               fprintf(stderr, "   Encrypted        : %s\n", isEncrypted ? "true" : "false");
-               fprintf(stderr, "   Num Certs        : %lu\n", 
-                       allCerts ? (unsigned long)CFArrayGetCount(allCerts) : 0);
-       }
-       
-       if((certFileBase != NULL) & (allCerts != NULL)) {
-               dumpCertFiles(allCerts, certFileBase, quiet);
-       }
-
-
-       if(numSigners) {
-               CSSM_OID eContentType = {0, NULL};
-               CFDataRef eContentData = NULL;
-               OidParser oidParser;
-               char str[OID_PARSER_STRING_SIZE];
-               
-               ortn = CMSDecoderCopyEncapsulatedContentType(cmsDecoder, &eContentData);
-               if(ortn) {
-                       cssmPerror("CMSDecoderCopyEncapsulatedContentType", ortn);
-                       goto errOut;
-               }
-               if(eContentData != NULL) {
-                       eContentType.Data = (uint8 *)CFDataGetBytePtr(eContentData);
-                       eContentType.Length = CFDataGetLength(eContentData);
-               }
-               if(!quiet) {
-                       /* can't use stderr - oidparser is fixed w/stdout */
-                       printf("   eContentType     : ");
-                       if(eContentType.Data == NULL) {
-                               printf("***NONE FOUND***\n");
-                       }
-                       else if(eContentType.Length == 0) {
-                               printf("***EMPTY***\n");
-                       }
-                       else {
-                               oidParser.oidParse(eContentType.Data, eContentType.Length, str);
-                               printf("%s\n", str);
-                       }
-               }
-               
-               if(eContentVfy != NULL) {
-                       if(eContentType.Data == NULL) {
-                               fprintf(stderr, "***Tried to verify eContentType, but none found\n");
-                               vfyErr = 1;
-                       }
-                       else if(!appCompareCssmData(eContentVfy, &eContentType)) {
-                               fprintf(stderr, "***eContentType verify error\n");
-                               fprintf(stderr, "   Expected: ");
-                               oidParser.oidParse(eContentVfy->Data, eContentVfy->Length, str);
-                               printf("%s\n", str);
-                               fprintf(stderr, "   Found   : ");
-                               oidParser.oidParse(eContentType.Data, eContentType.Length, str);
-                               printf("%s\n", str);
-                               vfyErr = 1;
-                       }
-               }
-               CFRELEASE(eContentData);
-               
-               /* get a policy for cert evaluation */
-               ortn = SecPolicySearchCreate(CSSM_CERT_X_509v3,
-                       &CSSMOID_APPLE_X509_BASIC,
-                       NULL,
-                       &policySearch);
-               if(ortn) {
-                       cssmPerror("SecPolicySearchCreate", ortn);
-                       goto errOut;
-               }
-               ortn = SecPolicySearchCopyNext(policySearch, &policy);
-               if(ortn) {
-                       cssmPerror("SecPolicySearchCopyNext", ortn);
-                       goto errOut;
-               }
-       }
-       for(signerDex=0; signerDex<numSigners; signerDex++) {
-               CMSSignerStatus         signerStatus = kCMSSignerInvalidIndex;
-               SecCertificateRef       signerCert;
-               CFStringRef                     signerEmailAddress;
-               SecTrustRef                     secTrust;
-               OSStatus                        certVerifyResultCode;
-               char                            trustStr[TRUST_STRING_MAX];
-               
-               ortn = CMSDecoderCopySignerStatus(cmsDecoder, signerDex,
-                       policy, 
-                       manTrustEval ? FALSE : TRUE,    /* evaluateSecTrust */
-                       &signerStatus,
-                       &secTrust,
-                       &certVerifyResultCode);
-               if(ortn) {
-                       cssmPerror("CMSDecoderCopySignerStatus", ortn);
-                       goto errOut;
-               }
-               if(ourRtn == noErr) {
-                       if((signerStatus != kCMSSignerValid) ||
-                          (certVerifyResultCode != CSSM_OK)) {
-                               ourRtn = -1;
-                       }
-               }
-               ortn = CMSDecoderCopySignerEmailAddress(cmsDecoder, signerDex, 
-                       &signerEmailAddress);
-               if(ortn) {
-                       cssmPerror("CMSDecoderCopySignerEmailAddress", ortn);
-                       goto errOut;
-               }
-               ortn = CMSDecoderCopySignerCert(cmsDecoder, signerDex, 
-                       &signerCert);
-               if(ortn) {
-                       cssmPerror("CMSDecoderCopySignerCertificate", ortn);
-                       goto errOut;
-               }
-               if(manTrustEval) {
-                       trustRtn = evalSecTrust(secTrust, anchorArray, trustStr, quiet);
-               }
-               
-               /* display nothing here if quiet true and status is copacetic */
-               if(!quiet || (signerStatus != kCMSSignerValid) || (trustRtn != noErr)) {
-                       fprintf(stderr, "   Signer %u:\n", signerDex);
-                       fprintf(stderr, "      signerStatus  : ");
-                       switch(signerStatus) {
-                               case kCMSSignerUnsigned: 
-                                       fprintf(stderr, "kCMSSignerUnsigned\n"); break;
-                               case kCMSSignerValid: 
-                                       fprintf(stderr, "kCMSSignerValid\n"); break;
-                               case kCMSSignerNeedsDetachedContent: 
-                                       fprintf(stderr, "kCMSSignerNeedsDetachedContent\n"); break;
-                               case kCMSSignerInvalidSignature: 
-                                       fprintf(stderr, "kCMSSignerInvalidSignature\n"); break;
-                               case kCMSSignerInvalidCert: 
-                                       fprintf(stderr, "kCMSSignerInvalidCert\n"); break;
-                               case kCMSSignerInvalidIndex: 
-                                       fprintf(stderr, "kCMSSignerInvalidIndex\n"); break;
-                       }
-                       if(manTrustEval) {
-                               fprintf(stderr, "      Trust Eval    : %s\n", trustStr);
-                       }
-                       fprintf(stderr, "      emailAddrs    : ");
-                       if(signerEmailAddress == NULL) {
-                               fprintf(stderr, "<<none found>>\n");
-                       }
-                       else {
-                               char emailStr[1000];
-                               if(!CFStringGetCString(signerEmailAddress, 
-                                               emailStr, 1000, kCFStringEncodingASCII)) {
-                                       fprintf(stderr, "<<<Error converting email address to C string>>>\n");
-                               }
-                               else {
-                                       fprintf(stderr, "%s\n", emailStr);
-                               }
-                       }
-                       
-                       fprintf(stderr, "      vfyResult     : %s\n",
-                               certVerifyResultCode ? 
-                                       cssmErrToStr(certVerifyResultCode) : "Success");
-               
-                       /* TBD: optionally manually verify the SecTrust object */
-                       
-                       if(parseSignerCert) {
-                               
-                               if(signerCert == NULL) {
-                                       fprintf(stderr, "      <<<Unable to obtain signer cert>>>\n");
-                               }
-                               else {
-                                       CSSM_DATA certData;
-                                       ortn = SecCertificateGetData(signerCert, &certData);
-                                       if(ortn) {
-                                               fprintf(stderr, "      <<<Unable to obtain signer cert>>>\n");
-                                               cssmPerror("SecCertificateGetData", ortn);
-                                       }
-                                       else {
-                                               printf("========== Signer Cert==========\n\n");
-                                               printCert(certData.Data, certData.Length, CSSM_FALSE);
-                                               printf("========== End Signer Cert==========\n\n");
-                                       }
-                               }
-                       }       /* parseSignerCert */
-               }       /* displaying per-signer info */
-               
-               CFRELEASE(signerCert); 
-               signerCert = NULL;
-               CFRELEASE(signerEmailAddress); 
-               signerEmailAddress = NULL;
-               CFRELEASE(secTrust); 
-               secTrust = NULL;
-       }       /* for signerDex */
-       
-       if(ortn == noErr) {
-               ortn = CMSDecoderCopyContent(cmsDecoder, outData);
-               if(ortn) {
-                       cssmPerror("CMSDecoderCopyContent", ortn);
-               }
-       }
-
-errOut:
-       CFRelease(cmsDecoder);
-       if(arena != NULL) {
-               SecArenaPoolFree(arena, false);
-       }
-
-       CFRELEASE(allCerts);
-       CFRELEASE(policySearch);
-       CFRELEASE(policy);
-       if(ourRtn) {
-               return ourRtn;
-       }
-       else if(trustRtn) {
-               return trustRtn;
-       }
-       else if(vfyErr) {
-               return vfyErr;
-       }
-       else {
-               return ortn;
-       }
-}
-
-static OSStatus doSign(
-       CFTypeRef                       signerOrArray,
-       const unsigned char *inData,
-       unsigned                        inDataLen,
-       bool                            multiUpdate,
-       bool                            detachedContent,
-       const CSSM_OID          *eContentType,  // OPTIONAL 
-       CMSSignedAttributes     attrs,
-       CFTypeRef                       otherCerts,             // OPTIONAL
-       bool                            customCoder,
-       bool                            getCmsMsg,
-       CMSCertificateChainMode chainMode,
-       bool                            quiet,
-       CFDataRef                       *outData)               // RETURNED
-{
-       if((inData == NULL) || (inDataLen == 0) || (outData == NULL)) { 
-               fprintf(stderr, "***Sign requires input file. Aborting.\n");
-               return paramErr;
-       }
-       if(signerOrArray == NULL) {
-               fprintf(stderr, "***Sign requires a signing identity. Aborting.\n");
-               return paramErr;
-       }
-       
-       OSStatus ortn;
-       CMSEncoderRef cmsEncoder = NULL;
-       SecCmsMessageRef msg = NULL;            /* for optional CMSEncoderGetCmsMessage */
-       SecArenaPoolRef arena = NULL;
-       CSSM_DATA encoderOut = {0, NULL};
-       
-       if(multiUpdate || otherCerts || getCmsMsg || customCoder ||
-                       (chainMode != kCMSCertificateChain)) {
-               /* one-shot encode doesn't support otherCerts or chainOptions*/
-               
-               ortn = CMSEncoderCreate(&cmsEncoder);
-               if(ortn) {
-                       cssmPerror("CMSEncoderCreate", ortn);
-                       return ortn;
-               }
-               /* subsequent errors to errOut: */
-               if(signerOrArray != NULL) {
-                       ortn = CMSEncoderAddSigners(cmsEncoder, signerOrArray);
-                       if(ortn) {
-                               goto errOut;
-                       }
-               }
-               if(eContentType) {
-                       ortn = CMSEncoderSetEncapsulatedContentType(cmsEncoder, eContentType);
-                       if(ortn) {
-                               goto errOut;
-                       }
-               }
-               if(detachedContent) {
-                       ortn = CMSEncoderSetHasDetachedContent(cmsEncoder, detachedContent);
-                       if(ortn) {
-                               goto errOut;
-                       }
-               }
-               if(otherCerts) {
-                       ortn = CMSEncoderAddSupportingCerts(cmsEncoder, otherCerts);
-                       if(ortn) {
-                               goto errOut;
-                       }
-               }
-               if(attrs) {
-                       ortn = CMSEncoderAddSignedAttributes(cmsEncoder, attrs);
-                       if(ortn) {
-                               goto errOut;
-                       }
-               }
-               if(chainMode != kCMSCertificateChain) {
-                       ortn = CMSEncoderSetCertificateChainMode(cmsEncoder, chainMode);
-                       if(ortn) {
-                               goto errOut;
-                       }
-               }
-               if(getCmsMsg || customCoder) {
-                       /* 
-                        * We just want to trigger the state transition 
-                        * that we know should happen. We also might need
-                        * the msg to create a custom coder. 
-                        */
-                       ortn = CMSEncoderGetCmsMessage(cmsEncoder, &msg);
-                       if(ortn) {
-                               cssmPerror("CMSEncoderGetCmsMessage", ortn);
-                               goto errOut;
-                       }
-               }
-               
-               if(customCoder) {
-                       SecCmsEncoderRef coder = NULL;
-                       ortn = SecArenaPoolCreate(1024, &arena);
-                       if(ortn) {
-                               cssmPerror("SecArenaPoolCreate", ortn);
-                               goto errOut;
-                       }
-                       ortn = SecCmsEncoderCreate(msg, 
-                               NULL, NULL,             // no callback 
-                               &encoderOut,    // data goes here
-                               arena,  
-                               NULL, NULL,             // no password callback (right?) 
-                               NULL, NULL,             // decrypt key callback
-                               NULL, NULL,             // detached digests
-                               &coder);
-                       if(ortn) {
-                               cssmPerror("SecCmsEncoderCreate", ortn);
-                               goto errOut;
-                       }
-                       ortn = CMSEncoderSetEncoder(cmsEncoder, coder);
-                       if(ortn) {
-                               cssmPerror("CMSEncoderSetEncoder", ortn);
-                               goto errOut;
-                       }
-                       else if(!quiet) {
-                               printf("...set up custom SecCmsEncoderRef\n");
-                       }
-               }
-               /* random number of random-sized updates */
-               ortn = updateEncoder(cmsEncoder, inData, inDataLen);
-               if(ortn) {
-                       goto errOut;
-               }
-
-               ortn = CMSEncoderCopyEncodedContent(cmsEncoder, outData);
-               if(ortn) {
-                       cssmPerror("CMSEncoderCopyEncodedContent", ortn);
-               }
-               if(customCoder) {
-                       /* we have the data right here */
-                       *outData =      CFDataCreate(NULL,
-                               (const UInt8 *)encoderOut.Data, encoderOut.Length);
-               }
-       }
-       else {
-               ortn = CMSEncode(signerOrArray, 
-                       NULL,                   /* recipients */
-                       eContentType,
-                       detachedContent,
-                       attrs,
-                       inData, inDataLen,
-                       outData);
-               if(ortn) {
-                       printf("***CMSEncode returned %ld\n", (long)ortn);
-                       cssmPerror("CMSEncode", ortn);
-               }
-       }
-errOut:
-       if(cmsEncoder) {
-               CFRelease(cmsEncoder);
-       }
-       if(arena) {
-               SecArenaPoolFree(arena, false);
-       }
-       return ortn;
-}
-
-static OSStatus doEncrypt(
-       CFTypeRef                       recipOrArray,
-       const unsigned char *inData,
-       unsigned                        inDataLen,
-       bool                            multiUpdate,
-       CFDataRef                       *outData)               // RETURNED
-{
-       if((inData == NULL) || (inDataLen == 0) || (outData == NULL)) { 
-               fprintf(stderr, "***Encrypt requires input file. Aborting.\n");
-               return paramErr;
-       }
-       if(recipOrArray == NULL) {
-               fprintf(stderr, "***Encrypt requires a recipient certificate. Aborting.\n");
-               return paramErr;
-       }
-       
-       OSStatus ortn;
-       CMSEncoderRef cmsEncoder = NULL;
-       
-       if(multiUpdate) {
-               ortn = CMSEncoderCreate(&cmsEncoder);
-               if(ortn) {
-                       cssmPerror("CMSEncoderCreate", ortn);
-                       return ortn;
-               }
-               /* subsequent errors to errOut: */
-               ortn = CMSEncoderAddRecipients(cmsEncoder, recipOrArray);
-               if(ortn) {
-                       goto errOut;
-               }
-               
-               /* random number of random-sized updates */
-               ortn = updateEncoder(cmsEncoder, inData, inDataLen);
-               if(ortn) {
-                       goto errOut;
-               }
-               ortn = CMSEncoderCopyEncodedContent(cmsEncoder, outData);
-               if(ortn) {
-                       cssmPerror("CMSEncoderCopyEncodedContent", ortn);
-               }
-       }
-       else {
-               /* one-shot */
-               ortn = CMSEncode(NULL,  /* signers */
-                       recipOrArray,           
-                       NULL,                           /* eContentType */
-                       FALSE,                          /* detachedContent */
-                       kCMSAttrNone,
-                       inData, inDataLen,
-                       outData);
-               if(ortn) {
-                       printf("***CMSEncode returned %ld\n", (long)ortn);
-                       cssmPerror("CMSEncode", ortn);
-               }
-       }
-errOut:
-       if(cmsEncoder) {
-               CFRelease(cmsEncoder);
-       }
-       return ortn;
-}
-
-/* create nested message: msg = EnvelopedData(SignedData(inData)) */
-static OSStatus doSignEncrypt(
-       CFTypeRef                       recipOrArray,   // encryption recipients
-       CFTypeRef                       signerOrArray,  // signers
-       const CSSM_OID          *eContentType,  // OPTIONAL - for signedData
-       CMSSignedAttributes     attrs,
-       const unsigned char *inData,
-       unsigned                        inDataLen,
-       bool                            multiUpdate,
-       CFTypeRef                       otherCerts,             // OPTIONAL
-       CFDataRef                       *outData)               // RETURNED
-{
-       if((inData == NULL) || (inDataLen == 0) || (outData == NULL)) { 
-               fprintf(stderr, "***Sign/Encrypt requires input file. Aborting.\n");
-               return paramErr;
-       }
-       if(recipOrArray == NULL) {
-               fprintf(stderr, "***Sign/Encrypt requires a recipient certificate. Aborting.\n");
-               return paramErr;
-       }
-       if(signerOrArray == NULL) {
-               fprintf(stderr, "***Sign/Encrypt requires a signer Identity. Aborting.\n");
-               return paramErr;
-       }
-       
-       OSStatus ortn;
-       CMSEncoderRef cmsEncoder = NULL;
-       
-       if(multiUpdate || otherCerts) {
-               ortn = CMSEncoderCreate(&cmsEncoder);
-               if(ortn) {
-                       cssmPerror("CMSEncoderCreate", ortn);
-                       return ortn;
-               }
-               /* subsequent errors to errOut: */
-               ortn = CMSEncoderAddRecipients(cmsEncoder, recipOrArray);
-               if(ortn) {
-                       goto errOut;
-               }
-               ortn = CMSEncoderAddSigners(cmsEncoder, signerOrArray);
-               if(ortn) {
-                       goto errOut;
-               }
-               if(eContentType) {
-                       ortn = CMSEncoderSetEncapsulatedContentType(cmsEncoder, eContentType);
-                       if(ortn) {
-                               goto errOut;
-                       }
-               }
-               if(otherCerts) {
-                       ortn = CMSEncoderAddSupportingCerts(cmsEncoder, otherCerts);
-                       if(ortn) {
-                               goto errOut;
-                       }
-               }
-               if(attrs) {
-                       ortn = CMSEncoderAddSignedAttributes(cmsEncoder, attrs);
-                       if(ortn) {
-                               goto errOut;
-                       }
-               }
-
-               /* random number of random-sized updates */
-               ortn = updateEncoder(cmsEncoder, inData, inDataLen);
-               if(ortn) {
-                       goto errOut;
-               }
-               ortn = CMSEncoderCopyEncodedContent(cmsEncoder, outData);
-               if(ortn) {
-                       cssmPerror("CMSEncoderCopyEncodedContent", ortn);
-               }
-       }
-       else {
-               ortn = CMSEncode(signerOrArray, 
-                       recipOrArray,           
-                       eContentType,   
-                       FALSE,                          /* detachedContent */
-                       attrs,
-                       inData, inDataLen,
-                       outData);
-               if(ortn) {
-                       printf("***CMSEncode returned %ld\n", (long)ortn);
-                       cssmPerror("CMSEncode", ortn);
-               }
-       }
-       
-errOut:
-       if(cmsEncoder) {
-               CFRelease(cmsEncoder);
-       }
-       return ortn;
-}
-
-/*
- * Create a CMS message containing only certs.
- */
-static OSStatus makeCertBag(
-       CFTypeRef       certsOrArray,
-       CFDataRef       *outData)
-{
-       if(certsOrArray == NULL) {
-               printf("***Need some certs to generate this type of message.\n");
-               return -1;
-       }
-       
-       OSStatus ortn;
-       CMSEncoderRef cmsEncoder = NULL;
-       
-       ortn = CMSEncoderCreate(&cmsEncoder);
-       if(ortn) {
-               cssmPerror("CMSEncoderCreate", ortn);
-               return ortn;
-       }
-       /* subsequent errors to errOut: */
-       ortn = CMSEncoderAddSupportingCerts(cmsEncoder, certsOrArray);
-       if(ortn) {
-               goto errOut;
-       }
-       ortn = CMSEncoderCopyEncodedContent(cmsEncoder, outData);
-       if(ortn) {
-               cssmPerror("CMSEncoderCopyEncodedContent", ortn);
-       }
-errOut:
-       CFRelease(cmsEncoder);
-       return ortn;
-}
-
-/*
- * Support maintanance of single item or array of them.
- *
- * Given new incoming 'newThing':
- *   if both *thingArray and *currThing are NULL
- *             *currThing = newThing;
- *             done;
- *   create *thingArray;
- *   add *currThing to *thingArray if present;
- *   add newThing to *thingArray;
- */
-static void addThing(
-       CFTypeRef newThing,
-       CFTypeRef *currThing,
-       CFMutableArrayRef *thingArray)
-{
-       if((*currThing == NULL) && (*thingArray == NULL)) {
-               /* first occurrence of a thing */
-               *currThing = newThing;
-               return;
-       }
-       
-       /* at least two things - prepare array */
-       if(*thingArray == NULL) {
-               *thingArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-       }
-       if(*currThing != NULL) {
-               /* move current thing to array */
-               CFArrayAppendValue(*thingArray, *currThing);
-               CFRelease(*currThing);
-               *currThing = NULL;
-       }
-       CFArrayAppendValue(*thingArray, newThing);
-       CFRelease(newThing);
-}
-
-int main(int argc, char **argv)
-{
-       if(argc < 2) {
-               usage(argv);
-       }
-       
-       CT_Op op;
-       bool needId = false;
-       if(!strcmp(argv[1], "sign")) {
-               op = CTO_Sign;
-               needId = true;
-       }
-       else if(!strcmp(argv[1], "envel")) {
-               op = CTO_Envelop;
-       }
-       else if(!strcmp(argv[1], "signEnv")) {
-               op = CTO_SignEnvelop;
-               needId = true;
-       }
-       else if(!strcmp(argv[1], "certs")) {
-               op = CTO_CertsOnly;
-       }       
-       else if(!strcmp(argv[1], "parse")) {
-               op = CTO_Parse;
-       }
-       else {
-               fprintf(stderr, "***Unrecognized cmd.\n");
-               usage(argv);
-       }
-
-       extern int optind;
-       extern char *optarg;
-       int arg;
-       OSStatus ortn;
-       
-       /* optional args */
-       char *inFileName = NULL;
-       char *outFileName = NULL;
-       bool detachedContent = false;
-       char *detachedFile = NULL;
-       bool useIdPicker = false;
-       bool quiet = false;
-       bool silent = false;
-       bool parseSignerCert = false;
-       const CSSM_OID *eContentType = NULL;
-       bool multiUpdate = false;
-       bool loopPause = false;
-       char *certFileBase = NULL;
-       CMSSignedAttributes signedAttrs = 0;
-       char *anchorFile = NULL;
-       bool manTrustEval = false;
-       CMSCertificateChainMode chainMode = kCMSCertificateChain;
-
-       /* for verification, usually in quiet/script mode */
-       CT_Vfy vfyOp = CTV_None;
-       const CSSM_OID *eContentVfy = NULL;
-       int numSignersVfy = -1;
-       int numCertsVfy = -1;
-       
-       /* for verifying functions in CMSPrivate.h */
-       bool customCoder = false;
-       bool fetchSecCmsMsg = false;
-       
-       /* 
-        * Signer/recipient items and arrays - use one item if possible, 
-        * else array (to test both paths)
-        */
-       SecIdentityRef signerId = NULL;
-       CFMutableArrayRef signerArray = NULL;
-       SecCertificateRef recipCert = NULL;
-       CFMutableArrayRef recipArray = NULL;
-       SecCertificateRef generalCert = NULL;
-       CFMutableArrayRef generalCertArray = NULL;
-       SecKeychainRef kcRef = NULL;
-       CFMutableArrayRef anchorArray = NULL;
-       
-       optind = 2;
-       while ((arg = getopt(argc, argv, "i:o:k:pr:R:dD:e:mlqcv:s:E:S:C:f:N:a:A:M12t:Z")) != -1) {
-               switch (arg) {
-                       case 'i':
-                               inFileName = optarg;
-                               break;
-                       case 'o':
-                               outFileName = optarg;
-                               break;
-                       case 'k':
-                               kcRef = keychain_open(optarg);
-                               if(!kcRef) {
-                               //      cssmPerror("SecKeychainOpen", ortn);
-                                       exit(1);
-                               }
-                               break;
-                       case 'p':
-                               useIdPicker = true;
-                               break;
-                       case 'r':
-                       {
-                               SecCertificateRef newCert = NULL;
-                               char *recipient = optarg;
-                               ortn = findCert(recipient, kcRef, &newCert);
-                               if(ortn) {
-                                       exit(1);
-                               }
-                               addThing(newCert, (CFTypeRef *)&recipCert, &recipArray);
-                               break;
-                       }
-                       case 'R':
-                       {
-                               SecCertificateRef certRef = readCertFile(optarg);
-                               if(certRef == NULL) {
-                                       exit(1);
-                               }
-                               addThing(certRef, (CFTypeRef *)&recipCert, &recipArray);
-                               break;
-                       }
-                       case 'S':
-                       {
-                               SecIdentityRef newId = NULL;
-                               SecCertificateRef newCert = NULL;
-                               char *signerEmail = optarg;
-                               
-                               /* 
-                                * first find the cert, optionally in the keychain already 
-                                * specified via -k
-                                */
-                               ortn = findCert(signerEmail, kcRef, &newCert);
-                               if(ortn) {
-                                       exit(1);
-                               }
-                               
-                               /* map cert to an identity */
-                               ortn = SecIdentityCreateWithCertificate(kcRef, newCert, &newId);
-                               if(ortn) {
-                                       cssmPerror("SecIdentityCreateWithCertificate", ortn);
-                                       exit(1);
-                               }
-                               
-                               addThing(newId, (CFTypeRef *)&signerId, &signerArray);
-                               CFRelease(newCert);
-                               break;
-                       }
-                       case 'C':
-                       {
-                               SecCertificateRef newCert = readCertFile(optarg);
-                               if(newCert == NULL) {
-                                       exit(1);
-                               }
-                               addThing(newCert, (CFTypeRef *)&generalCert, &generalCertArray);
-                               break;
-                       }       
-                       case 'c':
-                               parseSignerCert = true;
-                               break;
-                       case 'v':
-                               if(!strcmp(optarg, "sign")) {
-                                       vfyOp = CTV_Sign;
-                               }
-                               else if(!strcmp(optarg, "encr")) {
-                                       vfyOp = CTV_Envelop;
-                               }
-                               else if(!strcmp(optarg, "signEnv")) {
-                                       vfyOp = CTV_SignEnvelop;
-                               }
-                               else {
-                                       usage(argv);
-                               }
-                               break;
-                       case 'e':
-                               switch(optarg[0]) {
-                                       case 'a':
-                                               eContentType = &CSSMOID_PKINIT_AUTH_DATA;
-                                               break;
-                                       case 'r':
-                                               eContentType = &CSSMOID_PKINIT_RKEY_DATA;
-                                               break;
-                                       default:
-                                               usage(argv);
-                               }
-                               break;
-                       case 'E':
-                               switch(optarg[0]) {
-                                       case 'a':
-                                               eContentVfy = &CSSMOID_PKINIT_AUTH_DATA;
-                                               break;
-                                       case 'r':
-                                               eContentVfy = &CSSMOID_PKINIT_RKEY_DATA;
-                                               break;
-                                       case 'd':
-                                               eContentVfy = &CSSMOID_PKCS7_Data;
-                                               break;
-                                       default:
-                                               usage(argv);
-                               }
-                               break;
-                       case 'd':
-                               if(op != CTO_Sign) {
-                                       printf("-d only valid for op sign\n");
-                                       exit(1);
-                               }
-                               detachedContent = true;
-                               break;
-                       case 'D':
-                               if(op != CTO_Parse) {
-                                       printf("-D only valid for op sign\n");
-                                       exit(1);
-                               }
-                               detachedFile = optarg;
-                               break;
-                       case 'l':
-                               loopPause = true;
-                               break;
-                       case 'm':
-                               multiUpdate = true;
-                               break;
-                       case 's':
-                               numSignersVfy = atoi(optarg);
-                               break;
-                       case 'f':
-                               certFileBase = optarg;
-                               break;
-                       case 'N':
-                               numCertsVfy = atoi(optarg);
-                               break;
-                       case '1':
-                               customCoder = true;
-                               break;
-                       case '2':
-                               fetchSecCmsMsg = true;
-                               break;
-                       case 'a':
-                               for(; *optarg; optarg++) {
-                                       switch(*optarg) {
-                                               case 'c':
-                                                       signedAttrs |= kCMSAttrSmimeCapabilities;
-                                                       break;
-                                               case 'e':
-                                                       signedAttrs |= kCMSAttrSmimeEncryptionKeyPrefs;
-                                                       break;
-                                               case 'E':
-                                                       signedAttrs |= kCMSAttrSmimeMSEncryptionKeyPrefs;
-                                                       break;
-                                               case 't':
-                                                       signedAttrs |= kCMSAttrSigningTime;
-                                                       break;
-                                               default:
-                                                       usage(argv);
-                                       }
-                               }
-                               break;
-                       case 'A':
-                               anchorFile = optarg;
-                               break;
-                       case 'M':
-                               manTrustEval = true;
-                               break;
-                       case 't':
-                               if(!strcmp(optarg, "none")) {
-                                       chainMode = kCMSCertificateNone;
-                               }
-                               else if(!strcmp(optarg, "signer")) {
-                                       chainMode = kCMSCertificateSignerOnly;
-                               }
-                               else if(!strcmp(optarg, "chain")) {
-                                       chainMode = kCMSCertificateChain;
-                               }
-                               else if(!strcmp(optarg, "chainWithRoot")) {
-                                       chainMode = kCMSCertificateChainWithRoot;
-                               }
-                               else {
-                                       printf("***Bogus cert chain spec***\n");
-                                       usage(argv);
-                               }
-                               break;
-                       case 'q':
-                               quiet = true;
-                               break;
-                       case 'Z':
-                               quiet = true;
-                               silent = true;
-                               break;
-                       default:
-                       case '?':
-                               usage(argv);
-               }
-       }
-       if(optind != argc) {
-               /* getopt does not return '?' */
-               usage(argv);
-       }
-       
-       unsigned char *inData = NULL;
-       unsigned inDataLen = 0;
-       unsigned char *detachedData = NULL;
-       unsigned detachedDataLen = 0;
-       CFDataRef outData = NULL;
-       CFIndex byteCount = 0; 
-       if(!silent) {
-               testStartBanner((char *)"newCmsTool", argc, argv);
-       }
-       
-       if(inFileName) {
-               if(readFile(inFileName, &inData, &inDataLen)) {
-                       fprintf(stderr, "***Error reading infile %s. Aborting.\n", inFileName);
-                       exit(1);
-               }
-       }
-       if(detachedFile) {
-               if(readFile(detachedFile, &detachedData, &detachedDataLen)) {
-                       fprintf(stderr, "***Error reading detachedFile %s. Aborting.\n", detachedFile);
-                       exit(1);
-               }
-       }
-       
-       /* signer IDs */
-       if(useIdPicker) {
-               ortn = sslSimpleIdentPicker(kcRef, &signerId);
-               if(ortn) {
-                       fprintf(stderr, "***Error obtaining identity via picker. Aborting.\n");
-                       exit(1);
-               }
-       }
-       if(anchorFile) {
-               SecCertificateRef secCert = readCertFile(anchorFile);
-               if(secCert == NULL) {
-                       exit(1);
-               }
-               anchorArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-               CFArrayAppendValue(anchorArray, secCert);
-               CFRelease(secCert);
-       }
-       
-       /* 
-        * In order for signed blobs to contain a full cert chain, and to find
-        * certs matching a specific recipient cert email address, the keychain 
-        * containing intermediates must be in the user's keychain search list 
-        * (or, alternatively, the intermedaite certs must be added manually).
-        * To alleviate the burden on test scripts, we'll ensure that an optionally 
-        * specified keychain is in factin the search list when we sign a message 
-        * here. 
-        * Careful - make sure to ALWAYS restore the search list!
-        */
-       CFArrayRef originalSearchList = NULL;
-       if(kcRef != NULL) {
-               ortn = SecKeychainCopySearchList(&originalSearchList);
-               if(ortn) {
-                       cssmPerror("SecKeychainCopySearchList", ortn);
-                       exit(1);
-               }
-               CFMutableArrayRef newList = CFArrayCreateMutableCopy(
-                       NULL, 0, originalSearchList);
-               CFArrayAppendValue(newList, kcRef);
-               ortn = SecKeychainSetSearchList(newList);
-               if(ortn) {
-                       cssmPerror("SecKeychainSetSearchList", ortn);
-                       exit(1);
-               }
-               /* DO NOT EXIT WITHOUT RESTORING TO originalSearchList */
-       }
-       do {
-               switch(op) {
-                       case CTO_Sign:
-                               ortn = doSign((signerArray != NULL) ? 
-                                               (CFTypeRef)signerArray : (CFTypeRef)signerId, 
-                                       inData, inDataLen, 
-                                       multiUpdate, detachedContent, eContentType, signedAttrs, 
-                                       (generalCertArray != NULL) ?
-                                               (CFTypeRef)generalCertArray : (CFTypeRef)generalCert,
-                                       customCoder, fetchSecCmsMsg, chainMode, quiet,
-                                       &outData);
-                               break;
-                       case CTO_Envelop:
-                               ortn = doEncrypt(recipArray ? 
-                                               (CFTypeRef)recipArray : (CFTypeRef)recipCert,
-                                       inData, inDataLen, 
-                                       multiUpdate, &outData);
-                               break;
-                       case CTO_SignEnvelop:
-                               ortn = doSignEncrypt(recipArray ?
-                                               (CFTypeRef)recipArray : (CFTypeRef)recipCert, 
-                                       signerArray ? 
-                                               (CFTypeRef)signerArray : (CFTypeRef)signerId, 
-                                       eContentType, signedAttrs,
-                                       inData, inDataLen, multiUpdate, 
-                                       (generalCertArray != NULL) ?
-                                               (CFTypeRef)generalCertArray : (CFTypeRef)generalCert,
-                                       &outData);
-                               break;
-                       case CTO_CertsOnly:
-                               ortn = makeCertBag((generalCertArray != NULL) ?
-                                               (CFTypeRef)generalCertArray : (CFTypeRef)generalCert,
-                                               &outData);
-                               break;
-                       case CTO_Parse:
-                               ortn = doParse(inData, inDataLen, 
-                                       detachedData, detachedDataLen,
-                                       multiUpdate, 
-                                       vfyOp, eContentVfy, numSignersVfy, numCertsVfy,
-                                       parseSignerCert, certFileBase, customCoder, 
-                                       manTrustEval, anchorArray,
-                                       quiet, &outData);
-                               break;
-               }
-               
-               if(loopPause) {
-                       if(outData) {
-                               printf("...generated %u bytes of data.\n",
-                                       (unsigned)CFDataGetLength(outData));
-                       }
-                       fpurge(stdin);
-                       printf("q to quit, anything else to loop again: ");
-                       char resp = getchar();
-                       if(resp == 'q') {
-                               break;
-                       }
-                       else {
-                               CFRELEASE(outData);
-                               outData = NULL;
-                       }
-               }
-       } while (loopPause);
-       
-       if(originalSearchList) {
-               ortn = SecKeychainSetSearchList(originalSearchList);
-               if(ortn) {
-                       cssmPerror("SecKeychainSetSearchList", ortn);
-                       /* keep going */
-               }
-       }
-       
-       if(ortn) {
-               goto errOut;
-       }
-       
-       byteCount = outData ? CFDataGetLength(outData) : 0;
-       if(outData && outFileName) {
-               if(writeFile(outFileName, CFDataGetBytePtr(outData), byteCount)) {
-                       fprintf(stderr, "***Error writing to %s.\n", outFileName);
-                       ortn = -1;
-               }
-               else {
-                       if(!quiet) {
-                               fprintf(stderr, "...wrote %u bytes to %s.\n", 
-                                       (unsigned)byteCount, outFileName);
-                       }
-               }
-       }
-       else if(byteCount) {
-               fprintf(stderr, "...generated %u bytes but no place to write it.\n", 
-                       (unsigned)byteCount);
-       }
-       else if(outFileName) {
-               fprintf(stderr, "...nothing to write to file %s.\n", outFileName);
-               /* assume this is an error, caller wanted something */
-               ortn = -1;
-       }
-errOut:
-       return ortn;
-}
-
-/*
-       From SecurityTool/keychain_utilites.cpp
-       This properly supports dynamic keychains, i.e. smartcards
-*/
-
-SecKeychainRef keychain_open(const char *name)
-{
-       SecKeychainRef keychain = NULL;
-       OSStatus result;
-       
-//     check_obsolete_keychain(name);
-       if (name && name[0] != '/')
-       {
-               CFArrayRef dynamic = NULL;
-               result = SecKeychainCopyDomainSearchList(
-                                                                                                kSecPreferencesDomainDynamic, &dynamic);
-               if (result)
-               {
-                       //      cssmPerror("SecKeychainOpen", ortn);
-               //      sec_error("SecKeychainCopyDomainSearchList %s: %s", 
-               //                        name, sec_errstr(result));
-                       cssmPerror("SecKeychainCopyDomainSearchList", result);
-                       return NULL;
-               }
-               else
-               {
-                       uint32_t i;
-                       uint32_t count = dynamic ? CFArrayGetCount(dynamic) : 0;
-                       
-                       for (i = 0; i < count; ++i)
-                       {
-                               char pathName[PATH_MAX];
-                               UInt32 ioPathLength = sizeof(pathName);
-                               bzero(pathName, ioPathLength);
-                               keychain = (SecKeychainRef)CFArrayGetValueAtIndex(dynamic, i);
-                               result = SecKeychainGetPath(keychain, &ioPathLength, pathName);
-                               if (result)
-                               {
-                               //      sec_error("SecKeychainGetPath %s: %s",  name, sec_errstr(result));
-                                       cssmPerror("SecKeychainCopyDomainSearchList", result);
-                                       return NULL;
-                               }
-                               if (!strncmp(pathName, name, ioPathLength))
-                               {
-                                       CFRetain(keychain);
-                                       CFRelease(dynamic);
-                                       return keychain;
-                               }
-                       }
-                       CFRelease(dynamic);
-               }
-       }
-       
-       result = SecKeychainOpen(name, &keychain);
-       if (result)
-       {
-       //      sec_error("SecKeychainOpen %s: %s", name, sec_errstr(result));
-               cssmPerror("SecKeychainOpen", result);
-       }
-       
-       return keychain;
-}
-