+++ /dev/null
-/*
- * 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;
-}