]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/clxutils/anchorTest/anchorTest.cpp
Security-57740.51.3.tar.gz
[apple/security.git] / SecurityTests / clxutils / anchorTest / anchorTest.cpp
diff --git a/SecurityTests/clxutils/anchorTest/anchorTest.cpp b/SecurityTests/clxutils/anchorTest/anchorTest.cpp
deleted file mode 100644 (file)
index 8a3bde3..0000000
+++ /dev/null
@@ -1,1125 +0,0 @@
-/*
- * anchorTest.cpp - test cert encode/decode using known good system
- *                  anchors
- */
-#include <stdio.h>
-#include <string.h>
-#include <Security/cssm.h>
-#include <Security/x509defs.h>
-#include <Security/oidsattr.h>
-#include <Security/oidscert.h>
-#include <Security/certextensions.h>
-#include <Security/SecTrust.h>
-#include <Security/SecTrustSettingsPriv.h>
-#include <security_cdsa_utils/cuOidParser.h>
-#include <security_cdsa_utils/cuPrintCert.h>
-#include <utilLib/common.h>
-#include <utilLib/cspwrap.h>
-#include <security_cdsa_utils/cuFileIo.h>
-#include <clAppUtils/clutils.h>
-#include <clAppUtils/certVerify.h>
-#include <clAppUtils/tpUtils.h>
-#include <Security/SecAsn1Coder.h>
-#include <Security/X509Templates.h>
-
-#define ENC_TBS_BLOB   "encodedTbs.der"
-#define DEC_TBS_BLOB   "decodedTbs.der"
-
-static void usage(char **argv)
-{
-       printf("Usage: %s [options]\n", argv[0]);
-       printf("Options:\n");
-       printf("  w    -- writeBlobs\n");
-       printf("  e    -- allow expired roots\n");
-       printf("  t    -- use Trust Settings\n");
-       printf("  q    -- quiet\n");
-       printf("  v    -- verbose\n");
-       exit(1);
-}
-
-/*
- * Certs for which we skip the "compare TBS blob" test, enumerated by 
- * DER-encoded issuer name.
- *
- * Get this formatted data from the extractCertFields program. 
- *
- * All of these have non-standard KeyUsage encoding (legal but it's
- * not the same as ours or everyone else's).
- */
-/*
-   Country         : HU
-   Locality        : Budapest
-   Org             : NetLock Halozatbiztonsagi Kft.
-   OrgUnit         : Tanusitvanykiadok
-   Common Name     : NetLock Expressz (Class C) Tanusitvanykiado 
- */
-static const uint8 anchor_46_derIssuer_bytes[] = {
-   0x30,  0x81,  0x9b,  0x31,  0x0b,  0x30,  0x09,  0x06,  
-   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x48,  0x55,  
-   0x31,  0x11,  0x30,  0x0f,  0x06,  0x03,  0x55,  0x04,  
-   0x07,  0x13,  0x08,  0x42,  0x75,  0x64,  0x61,  0x70,  
-   0x65,  0x73,  0x74,  0x31,  0x27,  0x30,  0x25,  0x06,  
-   0x03,  0x55,  0x04,  0x0a,  0x13,  0x1e,  0x4e,  0x65,  
-   0x74,  0x4c,  0x6f,  0x63,  0x6b,  0x20,  0x48,  0x61,  
-   0x6c,  0x6f,  0x7a,  0x61,  0x74,  0x62,  0x69,  0x7a,  
-   0x74,  0x6f,  0x6e,  0x73,  0x61,  0x67,  0x69,  0x20,  
-   0x4b,  0x66,  0x74,  0x2e,  0x31,  0x1a,  0x30,  0x18,  
-   0x06,  0x03,  0x55,  0x04,  0x0b,  0x13,  0x11,  0x54,  
-   0x61,  0x6e,  0x75,  0x73,  0x69,  0x74,  0x76,  0x61,  
-   0x6e,  0x79,  0x6b,  0x69,  0x61,  0x64,  0x6f,  0x6b,  
-   0x31,  0x34,  0x30,  0x32,  0x06,  0x03,  0x55,  0x04,  
-   0x03,  0x13,  0x2b,  0x4e,  0x65,  0x74,  0x4c,  0x6f,  
-   0x63,  0x6b,  0x20,  0x45,  0x78,  0x70,  0x72,  0x65,  
-   0x73,  0x73,  0x7a,  0x20,  0x28,  0x43,  0x6c,  0x61,  
-   0x73,  0x73,  0x20,  0x43,  0x29,  0x20,  0x54,  0x61,  
-   0x6e,  0x75,  0x73,  0x69,  0x74,  0x76,  0x61,  0x6e,  
-   0x79,  0x6b,  0x69,  0x61,  0x64,  0x6f
-};
-static const CSSM_DATA anchor_46_derIssuer = { 158, (uint8 *)anchor_46_derIssuer_bytes };
-
-/*
-   Country         : HU
-   State           : Hungary
-   Locality        : Budapest
-   Org             : NetLock Halozatbiztonsagi Kft.
-   OrgUnit         : Tanusitvanykiadok
-   Common Name     : NetLock Kozjegyzoi (Class A) Tanusitvanykiado
-*/
-static const uint8 anchor_53_derIssuer_bytes[] = {
-   0x30,  0x81,  0xaf,  0x31,  0x0b,  0x30,  0x09,  0x06,  
-   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x48,  0x55,  
-   0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  0x55,  0x04,  
-   0x08,  0x13,  0x07,  0x48,  0x75,  0x6e,  0x67,  0x61,  
-   0x72,  0x79,  0x31,  0x11,  0x30,  0x0f,  0x06,  0x03,  
-   0x55,  0x04,  0x07,  0x13,  0x08,  0x42,  0x75,  0x64,  
-   0x61,  0x70,  0x65,  0x73,  0x74,  0x31,  0x27,  0x30,  
-   0x25,  0x06,  0x03,  0x55,  0x04,  0x0a,  0x13,  0x1e,  
-   0x4e,  0x65,  0x74,  0x4c,  0x6f,  0x63,  0x6b,  0x20,  
-   0x48,  0x61,  0x6c,  0x6f,  0x7a,  0x61,  0x74,  0x62,  
-   0x69,  0x7a,  0x74,  0x6f,  0x6e,  0x73,  0x61,  0x67,  
-   0x69,  0x20,  0x4b,  0x66,  0x74,  0x2e,  0x31,  0x1a,  
-   0x30,  0x18,  0x06,  0x03,  0x55,  0x04,  0x0b,  0x13,  
-   0x11,  0x54,  0x61,  0x6e,  0x75,  0x73,  0x69,  0x74,  
-   0x76,  0x61,  0x6e,  0x79,  0x6b,  0x69,  0x61,  0x64,  
-   0x6f,  0x6b,  0x31,  0x36,  0x30,  0x34,  0x06,  0x03,  
-   0x55,  0x04,  0x03,  0x13,  0x2d,  0x4e,  0x65,  0x74,  
-   0x4c,  0x6f,  0x63,  0x6b,  0x20,  0x4b,  0x6f,  0x7a,  
-   0x6a,  0x65,  0x67,  0x79,  0x7a,  0x6f,  0x69,  0x20,  
-   0x28,  0x43,  0x6c,  0x61,  0x73,  0x73,  0x20,  0x41,  
-   0x29,  0x20,  0x54,  0x61,  0x6e,  0x75,  0x73,  0x69,  
-   0x74,  0x76,  0x61,  0x6e,  0x79,  0x6b,  0x69,  0x61,  
-   0x64,  0x6f
-};
-static const CSSM_DATA anchor_53_derIssuer = { 178, (uint8 *)anchor_53_derIssuer_bytes };
-
-/*
-   Country         : HU
-   Locality        : Budapest
-   Org             : NetLock Halozatbiztonsagi Kft.
-   OrgUnit         : Tanusitvanykiadok
-   Common Name     : NetLock Uzleti (Class B) Tanusitvanykiado
-*/
-static const uint8 anchor_60_derIssuer_bytes[] = {
-   0x30,  0x81,  0x99,  0x31,  0x0b,  0x30,  0x09,  0x06,  
-   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x48,  0x55,  
-   0x31,  0x11,  0x30,  0x0f,  0x06,  0x03,  0x55,  0x04,  
-   0x07,  0x13,  0x08,  0x42,  0x75,  0x64,  0x61,  0x70,  
-   0x65,  0x73,  0x74,  0x31,  0x27,  0x30,  0x25,  0x06,  
-   0x03,  0x55,  0x04,  0x0a,  0x13,  0x1e,  0x4e,  0x65,  
-   0x74,  0x4c,  0x6f,  0x63,  0x6b,  0x20,  0x48,  0x61,  
-   0x6c,  0x6f,  0x7a,  0x61,  0x74,  0x62,  0x69,  0x7a,  
-   0x74,  0x6f,  0x6e,  0x73,  0x61,  0x67,  0x69,  0x20,  
-   0x4b,  0x66,  0x74,  0x2e,  0x31,  0x1a,  0x30,  0x18,  
-   0x06,  0x03,  0x55,  0x04,  0x0b,  0x13,  0x11,  0x54,  
-   0x61,  0x6e,  0x75,  0x73,  0x69,  0x74,  0x76,  0x61,  
-   0x6e,  0x79,  0x6b,  0x69,  0x61,  0x64,  0x6f,  0x6b,  
-   0x31,  0x32,  0x30,  0x30,  0x06,  0x03,  0x55,  0x04,  
-   0x03,  0x13,  0x29,  0x4e,  0x65,  0x74,  0x4c,  0x6f,  
-   0x63,  0x6b,  0x20,  0x55,  0x7a,  0x6c,  0x65,  0x74,  
-   0x69,  0x20,  0x28,  0x43,  0x6c,  0x61,  0x73,  0x73,  
-   0x20,  0x42,  0x29,  0x20,  0x54,  0x61,  0x6e,  0x75,  
-   0x73,  0x69,  0x74,  0x76,  0x61,  0x6e,  0x79,  0x6b,  
-   0x69,  0x61,  0x64,  0x6f
-};
-static const CSSM_DATA anchor_60_derIssuer = { 156, (uint8 *)anchor_60_derIssuer_bytes };
-
-/*
- Country         : TR
- Locality        : Ankara
- Org             : (c) 2005 TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
- Common Name     : TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı
- Serial Number   : 01
- Not Before      : 10:27:17 May 13, 2005
- Not After       : 10:27:17 Mar 22, 2015
-*/
-static const uint8 turk1_derIssuer_bytes[] = {
-       0x30,  0x81,  0xb7,  0x31,  0x3f,  0x30,  0x3d,  0x06,  
-       0x03,  0x55,  0x04,  0x03,  0x0c,  0x36,  0x54,  0xc3,  
-       0x9c,  0x52,  0x4b,  0x54,  0x52,  0x55,  0x53,  0x54,  
-       0x20,  0x45,  0x6c,  0x65,  0x6b,  0x74,  0x72,  0x6f,  
-       0x6e,  0x69,  0x6b,  0x20,  0x53,  0x65,  0x72,  0x74,  
-       0x69,  0x66,  0x69,  0x6b,  0x61,  0x20,  0x48,  0x69,  
-       0x7a,  0x6d,  0x65,  0x74,  0x20,  0x53,  0x61,  0xc4,  
-       0x9f,  0x6c,  0x61,  0x79,  0xc4,  0xb1,  0x63,  0xc4,  
-       0xb1,  0x73,  0xc4,  0xb1,  0x31,  0x0b,  0x30,  0x09,  
-       0x06,  0x03,  0x55,  0x04,  0x06,  0x0c,  0x02,  0x54,  
-       0x52,  0x31,  0x0f,  0x30,  0x0d,  0x06,  0x03,  0x55,  
-       0x04,  0x07,  0x0c,  0x06,  0x41,  0x4e,  0x4b,  0x41,  
-       0x52,  0x41,  0x31,  0x56,  0x30,  0x54,  0x06,  0x03,  
-       0x55,  0x04,  0x0a,  0x0c,  0x4d,  0x28,  0x63,  0x29,  
-       0x20,  0x32,  0x30,  0x30,  0x35,  0x20,  0x54,  0xc3,  
-       0x9c,  0x52,  0x4b,  0x54,  0x52,  0x55,  0x53,  0x54,  
-       0x20,  0x42,  0x69,  0x6c,  0x67,  0x69,  0x20,  0xc4,  
-       0xb0,  0x6c,  0x65,  0x74,  0x69,  0xc5,  0x9f,  0x69,  
-       0x6d,  0x20,  0x76,  0x65,  0x20,  0x42,  0x69,  0x6c,  
-       0x69,  0xc5,  0x9f,  0x69,  0x6d,  0x20,  0x47,  0xc3,  
-       0xbc,  0x76,  0x65,  0x6e,  0x6c,  0x69,  0xc4,  0x9f,  
-       0x69,  0x20,  0x48,  0x69,  0x7a,  0x6d,  0x65,  0x74,  
-       0x6c,  0x65,  0x72,  0x69,  0x20,  0x41,  0x2e,  0xc5,  
-       0x9e,  0x2e
-};
-static const CSSM_DATA turk1_derIssuer = { 186, (uint8 *)turk1_derIssuer_bytes };
-
-/*
- Country         : TR
- Locality        : Ankara
- Org             : TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Kasım 2005
- Common Name     : TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı 
- Serial Number   : 01
- Not Before      : 10:07:57 Nov 7, 2005
- Not After       : 10:07:57 Sep 16, 2015
-*/
-static const uint8 turk2_derIssuer_bytes[] = {
-       0x30,  0x81,  0xbe,  0x31,  0x3f,  0x30,  0x3d,  0x06,  
-       0x03,  0x55,  0x04,  0x03,  0x0c,  0x36,  0x54,  0xc3,  
-       0x9c,  0x52,  0x4b,  0x54,  0x52,  0x55,  0x53,  0x54,  
-       0x20,  0x45,  0x6c,  0x65,  0x6b,  0x74,  0x72,  0x6f,  
-       0x6e,  0x69,  0x6b,  0x20,  0x53,  0x65,  0x72,  0x74,  
-       0x69,  0x66,  0x69,  0x6b,  0x61,  0x20,  0x48,  0x69,  
-       0x7a,  0x6d,  0x65,  0x74,  0x20,  0x53,  0x61,  0xc4,  
-       0x9f,  0x6c,  0x61,  0x79,  0xc4,  0xb1,  0x63,  0xc4,  
-       0xb1,  0x73,  0xc4,  0xb1,  0x31,  0x0b,  0x30,  0x09,  
-       0x06,  0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x54,  
-       0x52,  0x31,  0x0f,  0x30,  0x0d,  0x06,  0x03,  0x55,  
-       0x04,  0x07,  0x0c,  0x06,  0x41,  0x6e,  0x6b,  0x61,  
-       0x72,  0x61,  0x31,  0x5d,  0x30,  0x5b,  0x06,  0x03,  
-       0x55,  0x04,  0x0a,  0x0c,  0x54,  0x54,  0xc3,  0x9c,  
-       0x52,  0x4b,  0x54,  0x52,  0x55,  0x53,  0x54,  0x20,  
-       0x42,  0x69,  0x6c,  0x67,  0x69,  0x20,  0xc4,  0xb0,  
-       0x6c,  0x65,  0x74,  0x69,  0xc5,  0x9f,  0x69,  0x6d,  
-       0x20,  0x76,  0x65,  0x20,  0x42,  0x69,  0x6c,  0x69,  
-       0xc5,  0x9f,  0x69,  0x6d,  0x20,  0x47,  0xc3,  0xbc,  
-       0x76,  0x65,  0x6e,  0x6c,  0x69,  0xc4,  0x9f,  0x69,  
-       0x20,  0x48,  0x69,  0x7a,  0x6d,  0x65,  0x74,  0x6c,  
-       0x65,  0x72,  0x69,  0x20,  0x41,  0x2e,  0xc5,  0x9e,  
-       0x2e,  0x20,  0x28,  0x63,  0x29,  0x20,  0x4b,  0x61,  
-       0x73,  0xc4,  0xb1,  0x6d,  0x20,  0x32,  0x30,  0x30,  
-       0x35
-};
-static const CSSM_DATA turk2_derIssuer = { 193, (uint8 *)turk2_derIssuer_bytes };
-
-/*
- Country         : TR
- Locality        : Ankara
- Org             : TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Aralık 2007
- Common Name     : TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı 
- Serial Number   : 01
- Not Before      : 18:37:19 Dec 25, 2007
- Not After       : 18:37:19 Dec 22, 2017
-*/
-static const uint8 turk3_derIssuer_bytes[] = {
-       0x30,  0x81,  0xbf,  0x31,  0x3f,  0x30,  0x3d,  0x06,  
-       0x03,  0x55,  0x04,  0x03,  0x0c,  0x36,  0x54,  0xc3,  
-       0x9c,  0x52,  0x4b,  0x54,  0x52,  0x55,  0x53,  0x54,  
-       0x20,  0x45,  0x6c,  0x65,  0x6b,  0x74,  0x72,  0x6f,  
-       0x6e,  0x69,  0x6b,  0x20,  0x53,  0x65,  0x72,  0x74,  
-       0x69,  0x66,  0x69,  0x6b,  0x61,  0x20,  0x48,  0x69,  
-       0x7a,  0x6d,  0x65,  0x74,  0x20,  0x53,  0x61,  0xc4,  
-       0x9f,  0x6c,  0x61,  0x79,  0xc4,  0xb1,  0x63,  0xc4,  
-       0xb1,  0x73,  0xc4,  0xb1,  0x31,  0x0b,  0x30,  0x09,  
-       0x06,  0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x54,  
-       0x52,  0x31,  0x0f,  0x30,  0x0d,  0x06,  0x03,  0x55,  
-       0x04,  0x07,  0x0c,  0x06,  0x41,  0x6e,  0x6b,  0x61,  
-       0x72,  0x61,  0x31,  0x5e,  0x30,  0x5c,  0x06,  0x03,  
-       0x55,  0x04,  0x0a,  0x0c,  0x55,  0x54,  0xc3,  0x9c,  
-       0x52,  0x4b,  0x54,  0x52,  0x55,  0x53,  0x54,  0x20,  
-       0x42,  0x69,  0x6c,  0x67,  0x69,  0x20,  0xc4,  0xb0,  
-       0x6c,  0x65,  0x74,  0x69,  0xc5,  0x9f,  0x69,  0x6d,  
-       0x20,  0x76,  0x65,  0x20,  0x42,  0x69,  0x6c,  0x69,  
-       0xc5,  0x9f,  0x69,  0x6d,  0x20,  0x47,  0xc3,  0xbc,  
-       0x76,  0x65,  0x6e,  0x6c,  0x69,  0xc4,  0x9f,  0x69,  
-       0x20,  0x48,  0x69,  0x7a,  0x6d,  0x65,  0x74,  0x6c,  
-       0x65,  0x72,  0x69,  0x20,  0x41,  0x2e,  0xc5,  0x9e,  
-       0x2e,  0x20,  0x28,  0x63,  0x29,  0x20,  0x41,  0x72,  
-       0x61,  0x6c,  0xc4,  0xb1,  0x6b,  0x20,  0x32,  0x30,  
-       0x30,  0x37
-};
-static const CSSM_DATA turk3_derIssuer = { 194, (uint8 *)turk3_derIssuer_bytes };
-
-/*
-Cert File Name: globalSignRoot.cer
-   Country         : BE
-   Org             : GlobalSign nv-sa
-   OrgUnit         : Root CA
-   Common Name     : GlobalSign Root CA
-*/
-static const uint8 globalSignRoot_derIssuer_bytes[] = {
-   0x30,  0x57,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
-   0x55,  0x04,  0x06,  0x13,  0x02,  0x42,  0x45,  0x31,  
-   0x19,  0x30,  0x17,  0x06,  0x03,  0x55,  0x04,  0x0a,  
-   0x13,  0x10,  0x47,  0x6c,  0x6f,  0x62,  0x61,  0x6c,  
-   0x53,  0x69,  0x67,  0x6e,  0x20,  0x6e,  0x76,  0x2d,  
-   0x73,  0x61,  0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  
-   0x55,  0x04,  0x0b,  0x13,  0x07,  0x52,  0x6f,  0x6f,  
-   0x74,  0x20,  0x43,  0x41,  0x31,  0x1b,  0x30,  0x19,  
-   0x06,  0x03,  0x55,  0x04,  0x03,  0x13,  0x12,  0x47,  
-   0x6c,  0x6f,  0x62,  0x61,  0x6c,  0x53,  0x69,  0x67,  
-   0x6e,  0x20,  0x52,  0x6f,  0x6f,  0x74,  0x20,  0x43,  
-   0x41
-};
-static const CSSM_DATA globalSignRoot_derIssuer = { 89, (uint8 *)globalSignRoot_derIssuer_bytes };
-
-/***********************
-Cert File Name: swisssign.der
-Subject Name       :
-   Country         : CH
-   Org             : SwissSign
-   Common Name     : SwissSign CA (RSA IK May 6 1999 18:00:58)
-   Email addrs     : ca@SwissSign.com
-   
- This one has a bogus AuthorityKeyId, with a value of {0x30, 0} inside the octet string. 
- ***********************/
-static const uint8 swisssign_derIssuer_bytes[] = {
-   0x30,  0x76,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
-   0x55,  0x04,  0x06,  0x13,  0x02,  0x43,  0x48,  0x31,  
-   0x12,  0x30,  0x10,  0x06,  0x03,  0x55,  0x04,  0x0a,  
-   0x13,  0x09,  0x53,  0x77,  0x69,  0x73,  0x73,  0x53,  
-   0x69,  0x67,  0x6e,  0x31,  0x32,  0x30,  0x30,  0x06,  
-   0x03,  0x55,  0x04,  0x03,  0x13,  0x29,  0x53,  0x77,  
-   0x69,  0x73,  0x73,  0x53,  0x69,  0x67,  0x6e,  0x20,  
-   0x43,  0x41,  0x20,  0x28,  0x52,  0x53,  0x41,  0x20,  
-   0x49,  0x4b,  0x20,  0x4d,  0x61,  0x79,  0x20,  0x36,  
-   0x20,  0x31,  0x39,  0x39,  0x39,  0x20,  0x31,  0x38,  
-   0x3a,  0x30,  0x30,  0x3a,  0x35,  0x38,  0x29,  0x31,  
-   0x1f,  0x30,  0x1d,  0x06,  0x09,  0x2a,  0x86,  0x48,  
-   0x86,  0xf7,  0x0d,  0x01,  0x09,  0x01,  0x16,  0x10,  
-   0x63,  0x61,  0x40,  0x53,  0x77,  0x69,  0x73,  0x73,  
-   0x53,  0x69,  0x67,  0x6e,  0x2e,  0x63,  0x6f,  0x6d
-   
-};
-static const CSSM_DATA swisssign_derIssuer = { 120, (uint8 *)swisssign_derIssuer_bytes };
-
-/*
- * Simple class to hold arrays of fields.
- */
-class FieldArray {
-public:
-       /*
-        * Create from existing field array obtained from
-        * CSSM_CL_CertGetAllFields(). We'll do the CSSM_CL_FreeFields()
-        * in our destructor.
-        */
-       FieldArray(
-               CSSM_FIELD              *fields, 
-               uint32                  numFields,
-               CSSM_CL_HANDLE  clHand);
-       
-       /*
-        * Create empty array of specified size. We don't own the fields 
-        * themselves.
-        */
-       FieldArray(
-               uint32                  size);
-       
-       ~FieldArray();
-       
-       /*
-        * Append a field - no realloc!
-        */
-       void appendField(CSSM_FIELD &field);
-       
-       /* get specified field */
-       CSSM_FIELD &fieldAt(uint32 index);
-       
-       /* get nth occurence of field matching specified OID */
-       int  fieldForOid(
-               const CSSM_OID  &oid,
-               unsigned                n,                      // n == 0 --> first one
-               CSSM_FIELD              *&found);       // RETURNED
-               
-       CSSM_FIELD      *mFields;
-       uint32          mNumFields;             // sizeof of *fields
-       uint32          mMallocdSize;   // if NULL, read-only
-       CSSM_CL_HANDLE  mClHand;
-};
-
-FieldArray::FieldArray(
-       CSSM_FIELD *fields, 
-       uint32 numFields,
-       CSSM_CL_HANDLE clHand)
-{
-       mFields = fields;
-       mNumFields = numFields;
-       mMallocdSize = 0;
-       mClHand = clHand;
-}
-
-FieldArray::FieldArray(
-       uint32 size)
-{
-       unsigned len = sizeof(CSSM_FIELD) * size;
-       mFields = (CSSM_FIELD_PTR)malloc(len);
-       memset(mFields, 0, len);
-       mNumFields = 0;
-       mMallocdSize = size;
-       mClHand = 0;
-}
-
-FieldArray::~FieldArray()
-{
-       if(mMallocdSize != 0) {
-               /* 
-                * Just free the array of fields we mallocd, not the fields 
-                * themselves
-                */
-               free(mFields);
-       }
-       else {
-               /* The CL mallocd these fields, tell it to free the whole thing */
-               CSSM_RETURN crtn = CSSM_CL_FreeFields(mClHand, 
-                       mNumFields, &mFields);
-               if(crtn) {
-                       printError("CSSM_CL_FreeFields", crtn);
-               }
-       }
-       mFields = NULL;
-       mNumFields = 0;
-       mMallocdSize = 0;
-}
-
-void FieldArray::appendField(
-       CSSM_FIELD &field)
-{
-       if(mMallocdSize == 0) {
-               printf("***Attempt to append to a read-only FieldArray\n");
-               exit(1);
-       }
-       if(mNumFields >= mMallocdSize) {
-               printf("***Attempt to append past present size of FieldArray\n");
-               exit(1);
-       }
-       mFields[mNumFields] = field;
-       mNumFields++;
-}
-
-CSSM_FIELD &FieldArray::fieldAt(
-       uint32 index)
-{
-       if(index >= mNumFields) {
-               printf("***Attempt to access past present size of FieldArray\n");
-               exit(1);
-       }
-       return mFields[index];
-}
-
-/* get nth occurence of field matching specified OID */
-/* returns nonzero on error */
-int FieldArray::fieldForOid(
-       const CSSM_OID  &oid,
-       unsigned                n,                      // n == 0 --> first one
-       CSSM_FIELD              *&found)        // RETURNED
-{
-       unsigned foundDex = 0;
-       for(unsigned dex=0; dex<mNumFields; dex++) {
-               CSSM_FIELD &field = mFields[dex];
-               if(appCompareCssmData(&field.FieldOid, &oid)) {
-                       if(foundDex == n) {
-                               found = &field;
-                               return 0;
-                       }
-                       foundDex++;
-               }
-       }
-       printf("FieldArray::fieldForOid field not found\n");
-       return 1;
-}
-
-/*
- * How many items in a NULL-terminated array of pointers?
- */
-static unsigned nssArraySize(
-       const void **array)
-{
-    unsigned count = 0;
-    if (array) {
-               while (*array++) {
-                       count++;
-               }
-    }
-    return count;
-}
-
-static void doPrintCert(
-       const CSSM_DATA &cert)
-{
-       printCert(cert.Data, cert.Length, CSSM_TRUE);
-}
-
-/*
- * The extensions whose presence causes us to skip the "compare
- * encoded and original TBS" test.
- */
-#define USE_SKIPPED_EXTENS             1
-#if            USE_SKIPPED_EXTENS
-static const CSSM_OID *skippedExtens[] = {     // %%% FIXME: this is a workaround for <rdar://8265523>; shouldn't need to skip!
-       &CSSMOID_PolicyMappings,
-       &CSSMOID_PolicyConstraints
-};
-#define NUM_SKIPPED_EXTENS     \
-       (sizeof(skippedExtens) / sizeof(skippedExtens[0]))
-#endif /* USE_SKIPPED_EXTENS */
-
-static const CSSM_DATA *skippedCerts[] = {
-       &anchor_46_derIssuer,
-       &anchor_53_derIssuer,
-       &anchor_60_derIssuer,
-       &turk1_derIssuer,
-       &turk2_derIssuer,
-       &turk3_derIssuer,
-       &globalSignRoot_derIssuer,
-       &swisssign_derIssuer
-};
-#define NUM_SKIPPED_CERTS      (sizeof(skippedCerts) / sizeof(skippedCerts[0]))
-
-static bool skipThisCert(
-       const NSS_TBSCertificate &tbs)
-{
-       /* search by extension - currently unused */
-       unsigned dex;
-       #if USE_SKIPPED_EXTENS
-       unsigned numExtens = nssArraySize((const void **)tbs.extensions);
-       /* skip this section if that's empty - compiler warning causes failure */
-       for(dex=0; dex<numExtens; dex++) {
-               NSS_CertExtension *exten = tbs.extensions[dex];
-               CSSM_OID *oid = &exten->extnId;
-               for(unsigned skipDex=0; skipDex<NUM_SKIPPED_EXTENS; skipDex++) {
-                       if(appCompareCssmData(skippedExtens[skipDex], oid)) {
-                               return true;
-                       }
-               }
-       }
-       #endif  /* USE_SKIPPED_EXTENS */
-       
-       /* search by specific issuer */
-       for(dex=0; dex<NUM_SKIPPED_CERTS; dex++) {
-               if(appCompareCssmData(skippedCerts[dex], &tbs.derIssuer)) {
-                       return true;
-               }
-       }
-       return false;
-}
-
-/*
- * Given a field OID, figure out what WE think this field is.
- */
-/* the field types we grok */
-typedef enum {
-       FT_Unknown,             // probably means we're out of sync with the CL
-       FT_Normal,              // standard component of TBS
-       FT_ReadOnly,    // Read only, don't use to create template
-       FT_NotTBS,              // part of top-level cert, don't use to create TBS
-       FT_ExtenParsed, // extension the CL SHOULD HAVE parsed
-       FT_ExtenUnknown // extension the CL should NOT have parsed              
-} FieldType;
-
-/* map OID --> FieldType */
-typedef struct {
-       const CSSM_OID  *oid;
-       FieldType               type;
-} FieldOidType;
-
-/* 
- * The CL-specific mapping table. 
- * This has to change whenever the CL is modified to add or delete
- * an extension or field!
- * For newbies, a tip: this basically has to stay in sync with the 
- * fieldFuncTable array in Security/AppleX509CL/CertFields.cpp. 
- */
-FieldOidType knownFields[] = {
-       {       &CSSMOID_X509V1Version, FT_Normal },
-       {       &CSSMOID_X509V1SerialNumber, FT_Normal },
-       {       &CSSMOID_X509V1IssuerNameCStruct, FT_Normal },
-       {       &CSSMOID_X509V1SubjectNameCStruct, FT_Normal },
-       {       &CSSMOID_X509V1SignatureAlgorithmTBS, FT_Normal },
-       {       &CSSMOID_X509V1SignatureAlgorithm, FT_NotTBS },
-       {       &CSSMOID_X509V1ValidityNotBefore, FT_Normal },
-       {       &CSSMOID_X509V1ValidityNotAfter, FT_Normal },
-       {       &CSSMOID_X509V1CertificateIssuerUniqueId, FT_Normal },
-       {       &CSSMOID_X509V1CertificateSubjectUniqueId, FT_Normal },
-       /* only one of these two can be set - use the SubjectPublicKeyInfo
-        * version */
-       {       &CSSMOID_X509V1SubjectPublicKeyCStruct, FT_Normal },
-       {       &CSSMOID_CSSMKeyStruct, FT_ReadOnly },
-       {       &CSSMOID_X509V1Signature, FT_NotTBS },
-       {   &CSSMOID_X509V1IssuerName, FT_ReadOnly },           // DER encoded
-       {   &CSSMOID_X509V1SubjectName, FT_ReadOnly },          // DER encoded
-       {   &CSSMOID_X509V1IssuerNameStd, FT_ReadOnly },        // DER encoded
-       {   &CSSMOID_X509V1SubjectNameStd,FT_ReadOnly },        // DER encoded
-               
-       /* Extensions */
-       {       &CSSMOID_KeyUsage, FT_ExtenParsed },
-       {   &CSSMOID_BasicConstraints, FT_ExtenParsed },
-       {       &CSSMOID_ExtendedKeyUsage, FT_ExtenParsed } ,
-       {       &CSSMOID_SubjectKeyIdentifier, FT_ExtenParsed } ,
-       {       &CSSMOID_AuthorityKeyIdentifier, FT_ExtenParsed } ,
-       {       &CSSMOID_SubjectAltName, FT_ExtenParsed } ,
-       {       &CSSMOID_IssuerAltName, FT_ExtenParsed } ,
-       {       &CSSMOID_CertificatePolicies, FT_ExtenParsed } ,
-       {       &CSSMOID_NetscapeCertType, FT_ExtenParsed } ,
-       {       &CSSMOID_CrlDistributionPoints, FT_ExtenParsed },
-       {   &CSSMOID_AuthorityInfoAccess, FT_ExtenParsed },
-       {   &CSSMOID_SubjectInfoAccess, FT_ExtenParsed },
-       {   &CSSMOID_X509V3CertificateExtensionCStruct, FT_ExtenUnknown },
-       {   &CSSMOID_QC_Statements, FT_ExtenParsed },
-       {       &CSSMOID_NameConstraints, FT_ExtenParsed },
-       {       &CSSMOID_PolicyMappings, FT_ExtenParsed },
-       {       &CSSMOID_PolicyConstraints, FT_ExtenParsed },
-//     {       &CSSMOID_InhibitAnyPolicy, FT_ExtenParsed } //%%% FIXME: CSSMOID_InhibitAnyPolicy not exported!?
-};
-#define NUM_KNOWN_FIELDS (sizeof(knownFields) / sizeof(knownFields[0]))
-
-static FieldType typeForOid(
-       const CSSM_OID &oid)
-{
-       for(unsigned dex=0; dex<NUM_KNOWN_FIELDS; dex++) {
-               FieldOidType &ft = knownFields[dex];
-               if(appCompareCssmData(&oid, ft.oid)) {
-                       return ft.type;
-               }
-       }
-       /* not found */
-       return FT_Unknown;
-}
-
-static const char *fieldTypeStr(
-       FieldType type)
-{
-       switch(type) {
-               case FT_Unknown:                return "FT_Unknown";
-               case FT_Normal:                 return "FT_Normal";
-               case FT_ReadOnly:               return "FT_ReadOnly";
-               case FT_NotTBS:                 return "FT_NotTBS";
-               case FT_ExtenParsed:    return "FT_ExtenParsed";
-               case FT_ExtenUnknown:   return "FT_ExtenUnknown";
-               default:
-                       printf("***BRRZAP!\n");
-                       exit(1);
-       }
-}
-
-static const uint8 emptyAuthKeyId[2] = {0x30, 0};
-
-/*
- * Extensions come in two flavors - parsed and not. However the 
- * CL will give us an unparsed version for extensions it normally 
- * understands but failed to decode. Detect that, and basic
- * extension formatting screwups, here.
- */
-static int vfyExtens(
-       FieldArray &extenFields,
-       const CSSM_DATA &cert,          // for error display only 
-       CSSM_BOOL quiet)        
-{
-       for(unsigned dex=0; dex<extenFields.mNumFields; dex++) {
-               CSSM_FIELD &extenField = extenFields.fieldAt(dex);
-               FieldType type = typeForOid(extenField.FieldOid);
-               FieldType expectType;
-               
-               /* first verify well-formed extension field */
-               CSSM_DATA &fieldValue = extenField.FieldValue;
-               CSSM_X509_EXTENSION *exten = (CSSM_X509_EXTENSION *)fieldValue.Data;
-               if((exten == NULL) || 
-                               (fieldValue.Length != sizeof(CSSM_X509_EXTENSION))) {
-                       doPrintCert(cert);
-                       printf("***Malformed CSSM_X509_EXTENSION\n");
-                       if(testError(quiet)) {
-                               return 1;
-                       }
-                       /* well let's limp along */
-                       continue;
-               }
-
-               /* currently (since Radar 3593624), these are both always valid */
-               if((exten->BERvalue.Data == NULL) || 
-                  (exten->value.parsedValue == NULL)) {  /* actually, one of three variants */
-                       printf("***Malformed CSSM_X509_EXTENSION (1)\n");
-                       return 1;
-               }
-               
-               switch(exten->format) {
-                       case CSSM_X509_DATAFORMAT_ENCODED:
-                               if(type != FT_ExtenUnknown) {
-                                       doPrintCert(cert);
-                                       printf("***Entension format ENCODED, expected PARSED\n");
-                                       if(testError(quiet)) {
-                                               return 1;
-                                       }
-                               }
-                               
-                               /* 
-                                * Now make sure that the underlying extension ID isn't
-                                * one that the CL was SUPPOSED to parse 
-                                */
-                               // %%% FIXME: need to investigate why these are not fully parsed: <rdar://8265523>
-                               if(appCompareCssmData(&exten->extnId, &CSSMOID_PolicyConstraints)) {
-                                       printf("...skipping policyConstraints extension per <rdar://8265523> (fix me!)\n");
-                                       break;
-                               }
-                               if(appCompareCssmData(&exten->extnId, &CSSMOID_PolicyMappings)) {
-                                       printf("...skipping policyMappings extension per <rdar://8265523> (fix me!)\n");
-                                       break;
-                               }
-                               
-                               expectType = typeForOid(exten->extnId);
-                               if(expectType != FT_Unknown) {
-                                       /* 
-                                        * Swisscom root has an authorityKeyId extension with an illegal value, 
-                                        * data inside the octet string is <30 00>, no context-specific wrapper
-                                        * or tag. 
-                                        * Instead of a hopeless complaint about that cert, let's just tolerate it 
-                                        * like this...
-                                        */
-                                       if(appCompareCssmData(&exten->extnId, &CSSMOID_AuthorityKeyIdentifier) &&
-                                          (exten->BERvalue.Length == 2) &&
-                                          !memcmp(emptyAuthKeyId, exten->BERvalue.Data, 2)) {
-                                               printf("...skipping bogus swisssign AuthorityKeyId\n");
-                                               break;
-                                       }
-                                       doPrintCert(cert);
-                                       printf("***underlying exten type %s, expect Unknown\n",
-                                               fieldTypeStr(expectType));
-                                       if(testError(quiet)) {
-                                               return 1;
-                                       }
-                               }
-                               break;
-                               
-                       case CSSM_X509_DATAFORMAT_PARSED:
-                               if(type != FT_ExtenParsed) {
-                                       doPrintCert(cert);
-                                       printf("***Entension format PARSED, expected ENCODED\n");
-                                       if(testError(quiet)) {
-                                               return 1;
-                                       }
-                               }
-                               if(exten->value.parsedValue == NULL) {
-                                       doPrintCert(cert);
-                                       printf("***Parsed extension with NULL parsedValue\n");
-                                       if(testError(quiet)) {
-                                               return 1;
-                                       }
-                               }
-                               break;
-                               
-                       default:
-                               doPrintCert(cert);
-                               printf("***Unknown Entension format %u\n",
-                                       exten->format);
-                               if(testError(quiet)) {
-                                       return 1;
-                               }
-                               break;
-                               
-               }       /* switch(exten.format) */
-       }
-       return 0;
-}
-
-/*
- * Here's the hard part.
- * Given a raw cert and its components in two FieldArrays, crate a TBS
- * cert from scratch from those fields and ensure that the result 
- * is the same as the raw TBS field in the original cert. 
- */
-static int buildTbs(
-       CSSM_CL_HANDLE  clHand,
-       const CSSM_DATA &rawCert,
-       FieldArray              &allFields,             // on entry, standard fields
-       FieldArray              &extenFields,   // extensions only 
-       CSSM_BOOL               quiet,
-       CSSM_BOOL               verbose,
-       CSSM_BOOL               writeBlobs)
-{
-       /*
-        * First do raw BER-decode in two ways - one to get the 
-        * extensions as they actuallly appear in the cert, and one
-        * to get the raw undecoded TBS.
-        */
-       SecAsn1CoderRef coder;
-       OSStatus ortn = SecAsn1CoderCreate(&coder);
-       if(ortn) {
-               cssmPerror("SecAsn1CoderCreate", ortn);
-               return testError(quiet);
-       }
-       
-       NSS_SignedCertOrCRL signedCert; // with TBS as ASN_ANY
-       memset(&signedCert, 0, sizeof(signedCert));
-       if(SecAsn1DecodeData(coder, &rawCert, kSecAsn1SignedCertOrCRLTemplate,
-                       &signedCert)) {
-               doPrintCert(rawCert);
-               printf("***Error decoding cert to kSecAsn1SignedCertOrCRL\n");
-               return testError(quiet);
-       }
-       
-       NSS_Certificate fullCert;               // fully decoded
-       memset(&fullCert, 0, sizeof(fullCert));
-       if(SecAsn1DecodeData(coder, &rawCert, kSecAsn1SignedCertTemplate,
-                       &fullCert)) {
-               doPrintCert(rawCert);
-               printf("***Error decoding cert to kSecAsn1Certificate\n");
-               return testError(quiet);
-       }
-        
-       NSS_TBSCertificate &tbs = fullCert.tbs;
-       unsigned numExtens = nssArraySize((const void **)tbs.extensions);
-       if(numExtens != extenFields.mNumFields) {
-               /* The CL told us the wrong number of extensions */
-               doPrintCert(rawCert);
-               printf("***NSS says %u extens, CL says %u\n", numExtens,
-                       (unsigned)extenFields.mNumFields);
-               return testError(quiet);
-       }
-       
-       if(skipThisCert(tbs)) {
-               if(verbose) {
-                       printf("   ...skipping TBS blob check\n");
-               }
-               SecAsn1CoderRelease(coder);
-               return 0;
-       }       
-       
-       /*
-        * The CL returns extension fields in an order which differs from
-        * the order of the extensions in the actual cert (because it
-        * does a table-based lookup, field by field, when doing a 
-        * CSSM_CL_CertGetAllFields()). We have to add the extensions
-        * from extenFields to allFields in the order they appear in 
-        * OUR decoded fullCert.
-        */
-       unsigned numUnknowns = 0;
-       for(unsigned dex=0; dex<numExtens; dex++) {
-               NSS_CertExtension *exten = tbs.extensions[dex];
-               CSSM_OID &oid = exten->extnId;
-               FieldType type = typeForOid(oid);
-               CSSM_FIELD *found = NULL;
-               int rtn;
-               switch(type) {
-                       case FT_ExtenParsed:
-                               /* 
-                                * look for this exact extension
-                                * NOTE we're assuming that only one copy of 
-                                * each specific parsed extension exists. The 
-                                * 509 spec does't specifically require this but
-                                * I've never seen a case of multiple extensions
-                                * of the same type in one cert. 
-                                */
-                               rtn = extenFields.fieldForOid(oid, 0, found);
-                               break;
-                       case FT_Unknown:
-                               /* search for nth unparsed exten field */
-                               rtn = extenFields.fieldForOid(
-                                       CSSMOID_X509V3CertificateExtensionCStruct,
-                                       numUnknowns++,
-                                       found);
-                               break;
-                       default:
-                               /* caller was already supposed to check this */
-                               doPrintCert(rawCert);
-                               printf("***HEY! buildTBS was given a bogus extension!\n");
-                               return 1;
-               }
-               if(rtn) {
-                       doPrintCert(rawCert);
-                       printf("***buildTBS could not find extension in CL's fields\n");
-                       return testError(quiet);
-               }
-               
-               allFields.appendField(*found);
-       }       /* processing extensions */
-       
-       /* 
-        * OK, the field array in allFields is ready to go down to 
-        * the CL.
-        */
-       CSSM_RETURN crtn;
-       CSSM_DATA clTbs = {0, NULL};
-       crtn = CSSM_CL_CertCreateTemplate(clHand,
-               allFields.mNumFields,
-               allFields.mFields,
-               &clTbs);
-       if(crtn) {
-               doPrintCert(rawCert);
-               printError("CSSM_CL_CertCreateTemplate", crtn);
-               return testError(quiet);
-       }
-       
-       /*
-        * The moment of truth. Is that template identical to the 
-        * raw undecoded TBS blob we got by decoding a NSS_SignedCertOrCRL?
-        */
-       int ourRtn = 0;
-       if(!appCompareCssmData(&clTbs, &signedCert.tbsBlob)) {
-               doPrintCert(rawCert);
-               printf("***Encoded TBS does not match decoded TBS.\n");
-               if(writeBlobs) {
-                       writeFile(ENC_TBS_BLOB, clTbs.Data, clTbs.Length);
-                       writeFile(DEC_TBS_BLOB, signedCert.tbsBlob.Data, 
-                               signedCert.tbsBlob.Length);
-                       printf("...wrote TBS blobs to %s and %s\n",
-                               ENC_TBS_BLOB, DEC_TBS_BLOB);
-               }
-               ourRtn = testError(quiet);
-       }
-       CSSM_FREE(clTbs.Data);
-       SecAsn1CoderRelease(coder);
-       return ourRtn;
-}
-
-/* verify root with itself using TP */
-static int verifyRoot(
-       CSSM_TP_HANDLE  tpHand,
-       CSSM_CL_HANDLE  clHand,
-       CSSM_CSP_HANDLE cspHand,
-       const CSSM_DATA &cert,
-       CSSM_BOOL               allowExpired,
-       CSSM_BOOL               useTrustSettings,
-       CSSM_BOOL               quiet)
-{
-       BlobList blobs;
-       blobs.addBlob(cert, CSSM_TRUE);
-       int i;
-       
-       const char *certStatus;
-       if(useTrustSettings) {
-               /*
-                * CSSM_CERT_STATUS_IS_IN_INPUT_CERTS 
-                * CSSM_CERT_STATUS_IS_ROOT
-                * CSSM_CERT_STATUS_TRUST_SETTINGS_FOUND_SYSTEM
-                * CSSM_CERT_STATUS_TRUST_SETTINGS_TRUST
-                */
-               certStatus = "0:0x314";  
-       }
-       else {
-               /*
-                * CSSM_CERT_STATUS_IS_IN_INPUT_CERTS (new since radar 3855635 was fixed)
-                * CSSM_CERT_STATUS_IS_IN_ANCHORS
-                * CSSM_CERT_STATUS_IS_ROOT
-                */
-               certStatus = "0:0x1C";  
-       }
-
-       /* try one with allowExpiredRoot false, then true on error and if so 
-        * enabled to make sure we know what's going wrong */
-       CSSM_BOOL expireEnable = CSSM_FALSE;
-       for(int dex=0; dex<2; dex++) {
-               i = certVerifySimple(tpHand, clHand, cspHand,
-                       blobs,          // certs
-                       blobs,          // and roots
-                       CSSM_FALSE, // useSystemAnchors
-                       CSSM_TRUE,  // leaf is CA
-                       expireEnable,
-                       CVP_Basic,
-                       NULL,           // SSL host
-                       CSSM_FALSE, // SSL client
-                       NULL,           // sender email
-                       0,                      // key use
-                       NULL,           // expected error str
-                       0, NULL,        // per-cert errors
-                       1, &certStatus, // per-cert status
-                       useTrustSettings,
-                       quiet, 
-                       CSSM_FALSE);    // verbose
-               if(i == 0) {
-                       /* success */
-                       if(dex == 1) {
-                               printf("...warning: expired root detected. Be aware.\n");
-                       }
-                       return 0;
-               }
-               if(!allowExpired) {
-                       /* no second chance */
-                       return i;
-               }
-               expireEnable = CSSM_TRUE;
-               if(useTrustSettings) {
-                       /* now expect EXPIRED, IS_ROOT, IS_IN_INPUT_CERTS, TRUST_SETTINGS_FOUND_SYSTEM,
-                        * CSSM_CERT_STATUS_TRUST_SETTINGS_TRUST */
-                       certStatus = "0:0x315"; 
-               }
-               else {
-                       /* now expect EXPIRED, IS_ROOT, IS_IN_ANCHORS, IS_IN_INPUT_CERTS */
-                       certStatus = "0:0x1d";  
-               }
-       }
-       return i;
-}
-
-
-static int doTest(
-       CSSM_CL_HANDLE  clHand,
-       CSSM_TP_HANDLE  tpHand,
-       CSSM_CSP_HANDLE cspHand,
-       const CSSM_DATA &cert,
-       CSSM_BOOL               allowExpired,
-       CSSM_BOOL               quiet,
-       CSSM_BOOL               verbose,
-       CSSM_BOOL               writeBlobs,
-       CSSM_BOOL               useTrustSettings)
-{
-       /* first see if this anchor self-verifies. */
-       if(verifyRoot(tpHand, clHand, cspHand, cert, allowExpired, 
-                       useTrustSettings, quiet)) {
-               doPrintCert(cert);
-               printf("***This anchor does not self-verify!\n");
-               return testError(quiet);
-       }
-       
-       /* have the CL parse it to the best of its ability */
-       CSSM_FIELD_PTR certFields;
-       uint32 numFields;
-       CSSM_RETURN crtn = CSSM_CL_CertGetAllFields(clHand, &cert, &numFields, 
-               &certFields);
-       if(crtn) {
-               printError("CSSM_CL_CertGetAllFields", crtn);
-               doPrintCert(cert);
-               printf("***The CL can not parse this anchor!\n");
-               return testError(quiet);
-       }
-
-       /* save, this object does the free fields when it goes out of scope */
-       FieldArray parsed(certFields, numFields, clHand);
-       
-       /* 
-        * We're going to build a TBSCert from these received fields.
-        * Extensions need to be processed specially because they 
-        * come back from the CL ordered differently than they appear
-        * in the cert. 
-        *
-        * First make two buckets for making copies of incoming fields.
-        */
-       FieldArray forCreate(numFields);        // for creating template
-       FieldArray extenFields(numFields);
-       
-       for(unsigned dex=0; dex<numFields; dex++) {
-               CSSM_FIELD &parsedField = parsed.fieldAt(dex);
-               FieldType type = typeForOid(parsedField.FieldOid);
-               switch(type) {
-                       case FT_Normal:
-                               forCreate.appendField(parsedField);
-                               break;
-                       case FT_ReadOnly:
-                       case FT_NotTBS:
-                               /* ignore */
-                               break;
-                       case FT_ExtenParsed:
-                       case FT_ExtenUnknown:
-                               /* extensions, save and process later */
-                               extenFields.appendField(parsedField);
-                               break;
-                       default:
-                               doPrintCert(cert);
-                               printf("***This anchor contains an unknown field!\n");
-                               if(testError(quiet)) {
-                                       return 1;
-                               }
-                               /* well let's limp along */
-                               forCreate.appendField(parsedField);
-                               break;
-               }
-       }
-       
-       /* basic extension verification */
-       if(vfyExtens(extenFields, cert, quiet)) {
-               return 1;
-       }
-       return buildTbs(clHand, cert, forCreate, extenFields, quiet, 
-               verbose, writeBlobs);
-}
-
-int main(int argc, char **argv)
-{
-       CSSM_BOOL quiet = CSSM_FALSE;
-       CSSM_BOOL verbose = CSSM_FALSE;
-       CSSM_BOOL writeBlobs = CSSM_FALSE;
-       CSSM_BOOL allowExpired = CSSM_FALSE;
-       CSSM_BOOL useTrustSettings = CSSM_FALSE;
-
-       for(int arg=1; arg<argc; arg++) {
-               switch(argv[arg][0]) {
-                       case 'q':
-                               quiet = CSSM_TRUE;
-                               break;
-                       case 'v':
-                               verbose = CSSM_TRUE;
-                               break;
-                       case 'w':
-                               writeBlobs = CSSM_TRUE;
-                               break;
-                       case 't':
-                               useTrustSettings = CSSM_TRUE;
-                               break;
-                       case 'e':
-                               allowExpired = CSSM_TRUE;
-                               break;
-                       default:
-                               usage(argv);
-               }
-       }
-       
-       printf("Starting anchorTest; args: ");
-       for(int i=1; i<argc; i++) {
-               printf("%s ", argv[i]);
-       }
-       printf("\n");
-
-       /* get system anchors only; convert to CSSM */
-       CFArrayRef cfAnchors;
-       OSStatus ortn;
-       CSSM_DATA *anchors;
-       unsigned numAnchors;
-       ortn = getSystemAnchors(&cfAnchors, &anchors, &numAnchors);
-       if(ortn) {
-               exit(1);
-       }
-       if(numAnchors < 50) {
-               printf("***Hey! I can only find %u anchors; there should be way more than that.\n",
-                       numAnchors);
-               exit(1);
-       }
-
-       CSSM_CL_HANDLE clHand = clStartup();
-       CSSM_TP_HANDLE tpHand = tpStartup();
-       CSSM_CSP_HANDLE cspHand = cspStartup();
-       if((clHand == 0) || (tpHand == 0) || (cspHand == 0)) {
-               return 0;
-       }
-
-       int rtn = 0;
-       for(unsigned dex=0; dex<numAnchors; dex++) {
-               if(!quiet) {
-                       printf("...anchor %u\n", dex);
-               }
-               rtn = doTest(clHand, tpHand, cspHand, anchors[dex], allowExpired,
-                       quiet, verbose, writeBlobs, useTrustSettings);
-               if(rtn) {
-                       break;
-               }
-       }
-       if(rtn == 0) {
-               if(!quiet) {
-                       printf("...%s success.\n", argv[0]);
-               }
-       }
-       return rtn;
-}