kc-51-testSecItemFind.c   [plain text]


//
//  testSecItemFind.c
//
//	Tests the ability of SecItemCopyMatching to replace the following
//	deprecated keychain search functions:
//
//	- SecKeychainSearchCreateFromAttributes +
//	  SecKeychainSearchCopyNext  [for keys, certificates, passwords]
//
//	- SecIdentitySearchCreate (or SecIdentitySearchCreateWithPolicy) +
//	  SecIdentitySearchCopyNext  [for identities]
//
//
//	This tool incidentally tests other Security API functions, including:
//	- SecItemAdd
//	- SecItemImport
//	- SecItemDelete
//	- SecKeyGenerateSymmetric
//
//
//	To build and run this tool (from Terminal):
//      cc -framework Security -framework CoreFoundation -o testSecItemFind testSecItemFind.c
//		./testSecItemFind
//
//	IMPORTANT: when building this code yourself, make sure that the AUTO_TEST
//	symbol is undefined (or defined to 0) below. If the AUTO_TEST symbol is
//	defined and non-zero, it is assumed that this tool is being built as part of
//	an automated regression test suite by internal Security test harness code.
//
//
//  Last modified: Tue Nov 16 2010 (kcm)


#define AUTO_TEST 1

#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <Security/Security.h>

#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <time.h>
#include <sys/param.h>

#if AUTO_TEST
#import "testmore.h"
#import "testenv.h"
#import "testleaks.h"
#else
#define tests_begin(ARGC, ARGV)		/* no-op */
#define tests_end(RESULT)			/* no-op */
#define plan_tests(COUNT)			/* no-op */
#define ok(RESULT, REASON)			/* no-op */
#endif

/* Following is a 3-element certificate chain
 * (ROOT_CERT, INTERMEDIATE_CERT, LEAF_CERT)
 */
unsigned char ROOT_CERT[985]={
	0x30,0x82,0x03,0xD5,0x30,0x82,0x02,0xBD,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
	0x30,0x0B,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x30,0x81,0x9D,
	0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x0C,0x11,0x54,0x65,0x73,0x74,0x2D,
	0x35,0x36,0x38,0x35,0x33,0x31,0x36,0x2D,0x52,0x4F,0x4F,0x54,0x31,0x0E,0x30,0x0C,
	0x06,0x03,0x55,0x04,0x0A,0x0C,0x05,0x41,0x70,0x70,0x6C,0x65,0x31,0x14,0x30,0x12,
	0x06,0x03,0x55,0x04,0x0B,0x0C,0x0B,0x43,0x6F,0x72,0x65,0x20,0x43,0x72,0x79,0x70,
	0x74,0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,
	0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x12,0x30,0x10,
	0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,
	0x31,0x2B,0x30,0x29,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,
	0x1C,0x73,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x2D,0x64,0x65,0x76,0x40,0x67,0x72,
	0x6F,0x75,0x70,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,
	0x0D,0x30,0x39,0x31,0x32,0x31,0x38,0x31,0x37,0x32,0x39,0x32,0x33,0x5A,0x17,0x0D,
	0x31,0x30,0x31,0x32,0x31,0x38,0x31,0x37,0x32,0x39,0x32,0x33,0x5A,0x30,0x81,0x9D,
	0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x0C,0x11,0x54,0x65,0x73,0x74,0x2D,
	0x35,0x36,0x38,0x35,0x33,0x31,0x36,0x2D,0x52,0x4F,0x4F,0x54,0x31,0x0E,0x30,0x0C,
	0x06,0x03,0x55,0x04,0x0A,0x0C,0x05,0x41,0x70,0x70,0x6C,0x65,0x31,0x14,0x30,0x12,
	0x06,0x03,0x55,0x04,0x0B,0x0C,0x0B,0x43,0x6F,0x72,0x65,0x20,0x43,0x72,0x79,0x70,
	0x74,0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,
	0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x12,0x30,0x10,
	0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,
	0x31,0x2B,0x30,0x29,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,
	0x1C,0x73,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x2D,0x64,0x65,0x76,0x40,0x67,0x72,
	0x6F,0x75,0x70,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x82,0x01,
	0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,
	0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xB0,0x4C,
	0x94,0xF7,0x56,0x26,0x91,0xB8,0xD1,0x5B,0x7C,0xEE,0x74,0xCB,0x1F,0x43,0xFE,0x88,
	0x24,0xAD,0xB0,0x1E,0x85,0x86,0xE9,0x3F,0xE7,0x74,0x40,0x6C,0x4A,0x8E,0x6B,0x50,
	0x7A,0x1B,0x43,0x9A,0x9E,0xF4,0x81,0xB3,0xF1,0xDB,0x6E,0xD4,0xFA,0xAE,0x06,0xCB,
	0x7F,0xE6,0xCA,0x06,0x06,0xC4,0x1E,0x2D,0xF3,0xFA,0x67,0xD6,0x95,0x0E,0xAC,0xCA,
	0x2B,0x25,0x14,0x4C,0x20,0x04,0xB4,0x26,0xAC,0x15,0x62,0x15,0xA6,0x21,0x14,0x51,
	0xCC,0x77,0x82,0x11,0xD0,0xF8,0xB0,0x06,0xC1,0x0F,0xFB,0x08,0x60,0x53,0x11,0x1F,
	0x00,0xA8,0x27,0x0E,0x2C,0x2C,0x63,0x34,0x6A,0xC5,0x4B,0x2D,0xCC,0x07,0xF6,0x39,
	0xDC,0x00,0xCF,0x6E,0x29,0x15,0x3E,0x3F,0x6C,0x89,0xB9,0x48,0x97,0x19,0xA2,0xB8,
	0x44,0x8D,0x98,0x85,0xF4,0x0B,0x70,0x06,0xD6,0x9A,0x39,0x4F,0x44,0x92,0x73,0x74,
	0xDF,0x46,0x10,0x9C,0xB5,0xBB,0x69,0xF4,0xE1,0xB5,0x61,0x2E,0xFF,0x92,0xDB,0x47,
	0x93,0x48,0x45,0xEB,0x7E,0xFA,0xCC,0xDB,0xCE,0x50,0x0A,0xCA,0xAF,0xAB,0x7D,0x09,
	0x9A,0x1E,0xC4,0x08,0xA1,0xD4,0xB9,0x2A,0x42,0x49,0x10,0x75,0x63,0x4E,0x51,0x3B,
	0xF7,0xF4,0xCA,0xCB,0x05,0xC9,0xE0,0xC9,0xD3,0x04,0x14,0x81,0xF6,0x9A,0xEE,0x0C,
	0x2B,0x56,0x87,0x20,0x50,0x27,0x14,0x71,0x1C,0x30,0x18,0x8C,0xDD,0xF4,0xA9,0x41,
	0x13,0x6D,0xE4,0x41,0xB1,0xE0,0x7E,0x09,0xD7,0x99,0xCE,0xE4,0x7A,0x91,0x65,0xBB,
	0x3F,0xE1,0xD4,0x07,0x8D,0xA9,0x23,0x0A,0xA4,0x80,0x47,0x58,0xD5,0x25,0x02,0x03,
	0x01,0x00,0x01,0xA3,0x20,0x30,0x1E,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,
	0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,
	0x04,0x03,0x02,0x02,0x84,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,
	0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x38,0x44,0x10,0xF4,0x24,0x4A,0xAA,
	0x9F,0x0D,0x37,0x5E,0x75,0xB7,0xF5,0xC5,0x27,0x19,0x57,0xE5,0x25,0x4A,0x44,0x03,
	0x5F,0x2E,0xD4,0x70,0x69,0xDD,0x55,0xDB,0x47,0x07,0x06,0x3E,0x5D,0xA4,0xBB,0x64,
	0xE2,0xA6,0x09,0x8B,0x6D,0x0B,0x50,0x33,0x5A,0x92,0x5A,0x5B,0xDF,0x6A,0x9F,0x81,
	0x5F,0x17,0x95,0xB0,0xC6,0xC3,0xCD,0x6D,0x17,0xDD,0x83,0xC1,0xA5,0xB7,0xCD,0xFF,
	0xE8,0x13,0x10,0x35,0x85,0x3E,0xCA,0xE4,0xF5,0x22,0x58,0x1E,0x68,0x14,0x62,0x35,
	0xE4,0x65,0xB4,0xD3,0x42,0x5A,0x03,0x5C,0x2D,0x76,0xD5,0x9B,0xAA,0xCB,0x3A,0xAC,
	0x55,0x58,0xAD,0x67,0x30,0xDC,0xC3,0xA7,0xA9,0x37,0xBB,0x61,0xA2,0xEA,0x6E,0x0C,
	0xB0,0x4B,0x0D,0x64,0x3D,0x59,0x3C,0xA3,0xA1,0x73,0x4F,0x33,0xDB,0x6F,0xBF,0x2D,
	0xB2,0x9D,0xCE,0x05,0x1C,0xF0,0xAB,0x4A,0xB0,0x70,0x5D,0x32,0x20,0x22,0xD7,0x12,
	0xC0,0x1C,0x0B,0x0D,0xC0,0x72,0x6B,0x6F,0xA4,0xF8,0xAA,0xD2,0x34,0x36,0x63,0x84,
	0x80,0xF0,0x70,0x5E,0x09,0xEA,0xFF,0x48,0x49,0x85,0x83,0x8E,0x8E,0x6E,0x4C,0x2E,
	0x2F,0xBB,0xBF,0xDF,0x3B,0x73,0x65,0xA2,0x0D,0x09,0x84,0x8F,0x08,0x86,0x61,0x27,
	0x58,0xB6,0x7E,0x2D,0xEC,0x08,0xBA,0x40,0x5D,0x20,0x54,0x37,0xDD,0xCC,0xE5,0xDB,
	0x38,0x68,0xEE,0x56,0x9F,0x92,0xDD,0x03,0x04,0xD2,0x94,0x51,0xD3,0xA9,0x08,0x2E,
	0x6E,0x25,0x8E,0xBF,0x8A,0xA9,0x2B,0xAD,0x50,0x00,0xA7,0x39,0x11,0x6A,0x9A,0x28,
	0x99,0x9A,0xB9,0x3B,0xB9,0xB5,0x9C,0x19,0x3A,
};

unsigned char INTERMEDIATE_CERT[1037]={
	0x30,0x82,0x04,0x09,0x30,0x82,0x02,0xF1,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x02,
	0x30,0x0B,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x30,0x81,0x9D,
	0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x0C,0x11,0x54,0x65,0x73,0x74,0x2D,
	0x35,0x36,0x38,0x35,0x33,0x31,0x36,0x2D,0x52,0x4F,0x4F,0x54,0x31,0x0E,0x30,0x0C,
	0x06,0x03,0x55,0x04,0x0A,0x0C,0x05,0x41,0x70,0x70,0x6C,0x65,0x31,0x14,0x30,0x12,
	0x06,0x03,0x55,0x04,0x0B,0x0C,0x0B,0x43,0x6F,0x72,0x65,0x20,0x43,0x72,0x79,0x70,
	0x74,0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,
	0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x12,0x30,0x10,
	0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,
	0x31,0x2B,0x30,0x29,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,
	0x1C,0x73,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x2D,0x64,0x65,0x76,0x40,0x67,0x72,
	0x6F,0x75,0x70,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,
	0x0D,0x30,0x39,0x31,0x32,0x31,0x38,0x31,0x37,0x33,0x30,0x35,0x34,0x5A,0x17,0x0D,
	0x31,0x30,0x31,0x32,0x31,0x38,0x31,0x37,0x33,0x30,0x35,0x34,0x5A,0x30,0x81,0xA5,
	0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x54,0x65,0x73,0x74,0x2D,
	0x35,0x36,0x38,0x35,0x33,0x31,0x36,0x2D,0x49,0x4E,0x54,0x45,0x52,0x4D,0x45,0x44,
	0x49,0x41,0x54,0x45,0x31,0x0E,0x30,0x0C,0x06,0x03,0x55,0x04,0x0A,0x0C,0x05,0x41,
	0x70,0x70,0x6C,0x65,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0B,0x43,
	0x6F,0x72,0x65,0x20,0x43,0x72,0x79,0x70,0x74,0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,
	0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
	0x13,0x02,0x55,0x53,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,
	0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x2B,0x30,0x29,0x06,0x09,0x2A,0x86,
	0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x1C,0x73,0x65,0x63,0x75,0x72,0x69,0x74,
	0x79,0x2D,0x64,0x65,0x76,0x40,0x67,0x72,0x6F,0x75,0x70,0x2E,0x61,0x70,0x70,0x6C,
	0x65,0x2E,0x63,0x6F,0x6D,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
	0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,
	0x0A,0x02,0x82,0x01,0x01,0x00,0xC4,0xBD,0x46,0x0E,0x0F,0x5C,0x1C,0xA2,0x23,0xD2,
	0x3B,0x8C,0xC4,0x02,0x52,0x8C,0xD8,0xB1,0xC2,0x58,0x2E,0x84,0xAA,0x6C,0xCB,0x4B,
	0xE4,0xF1,0xE7,0x48,0x98,0x46,0x6B,0xD0,0x50,0xB0,0xA3,0x1F,0x23,0xC6,0x3C,0x81,
	0x73,0xE7,0xEA,0xAA,0x55,0xF7,0x37,0x58,0x85,0xF6,0x96,0x0D,0xC0,0x81,0x8D,0x3D,
	0xD9,0xAD,0xFA,0x32,0x46,0x56,0x4A,0x53,0xF5,0x53,0x34,0x5B,0xFC,0xFC,0x51,0x2A,
	0x45,0xD4,0xCB,0x53,0xF9,0x58,0xBF,0x7D,0x48,0xB3,0x23,0x41,0xD7,0x93,0x1C,0xC2,
	0x32,0xE8,0x1C,0x82,0xDC,0xDC,0xCB,0xED,0x0B,0xDA,0x8A,0x1C,0xC0,0x0E,0x83,0x24,
	0xE6,0x2E,0x68,0xA6,0xB6,0x60,0xEE,0xAF,0xB1,0x07,0xF1,0xC0,0xDB,0x29,0x83,0x9E,
	0x0C,0xF4,0xCF,0x67,0x5B,0x49,0x3A,0x17,0x7E,0xC1,0xEB,0x75,0x3E,0xDD,0x0F,0x9A,
	0xC7,0x06,0x60,0x2B,0x18,0xBD,0xAA,0x96,0xD1,0xE1,0x9C,0xF0,0x34,0xFF,0x3E,0x8C,
	0x4A,0x96,0x5D,0x68,0x7C,0xCF,0xA1,0x14,0xED,0xB1,0x8E,0x10,0x8D,0x1F,0x15,0x22,
	0x4E,0x8E,0x1A,0xC7,0xAD,0xB9,0x16,0xCB,0x3C,0xCB,0x5D,0xB9,0xAC,0xD9,0xFE,0xAE,
	0xDE,0x06,0x3B,0xB6,0xA1,0xAA,0x7C,0x91,0x76,0xC6,0xA4,0x81,0xBD,0x29,0x86,0x33,
	0xA6,0xB5,0x4D,0x28,0x94,0x51,0x81,0x3F,0x68,0x95,0xEB,0x41,0x7A,0xE9,0x87,0xD7,
	0xDC,0xC8,0xA0,0x5F,0xAB,0x29,0xD9,0xC4,0x08,0xC8,0xA0,0x0B,0x77,0xAC,0x6C,0x21,
	0x10,0xA4,0xED,0x86,0x78,0x99,0x1F,0xA7,0x23,0x33,0x34,0x89,0x80,0x02,0xBC,0xAF,
	0xC6,0x3E,0x38,0xFB,0x7C,0x47,0x02,0x03,0x01,0x00,0x01,0xA3,0x4C,0x30,0x4A,0x30,
	0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,
	0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x02,0x84,
	0x30,0x27,0x06,0x03,0x55,0x1D,0x11,0x04,0x20,0x30,0x1E,0x81,0x1C,0x73,0x65,0x63,
	0x75,0x72,0x69,0x74,0x79,0x2D,0x64,0x65,0x76,0x40,0x67,0x72,0x6F,0x75,0x70,0x2E,
	0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
	0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x3C,0x66,0x3B,
	0x9D,0x6E,0xA9,0x0E,0xC9,0xC2,0x6C,0xF4,0x79,0xFB,0xD5,0x6E,0x1F,0x01,0x4E,0x0D,
	0x2C,0x64,0x7B,0x6E,0xD7,0xC7,0xA7,0x64,0x8B,0xF0,0xCD,0x93,0xCD,0x12,0x29,0x71,
	0x87,0x3E,0xA3,0x1E,0x7F,0x57,0xC7,0xD9,0xBF,0xD2,0xF2,0x03,0x27,0xD5,0x5E,0xEF,
	0x59,0xBC,0x91,0x37,0xB4,0x4A,0xEE,0xD2,0x2F,0xEA,0x92,0x07,0xBC,0xEC,0xAC,0x6A,
	0xF1,0x34,0xA4,0x40,0x61,0x8B,0xB9,0x3D,0xAF,0x5B,0x86,0x6E,0xEE,0x4C,0xCB,0x7F,
	0x1F,0xD0,0x0F,0x9E,0x5A,0xF0,0x39,0xFD,0x89,0xF3,0x03,0x61,0x5A,0xDF,0x6B,0x5F,
	0xE3,0x33,0x51,0x80,0x1B,0x61,0xFE,0x7A,0xC7,0x27,0xBF,0x12,0xB5,0x69,0x79,0x1E,
	0xAD,0x75,0xA8,0xFA,0x94,0xCC,0x22,0x4C,0xF9,0xB4,0xD3,0xD0,0xDC,0x57,0xD3,0x66,
	0x96,0xDD,0x8A,0xC0,0xE4,0x11,0x5A,0xD9,0xB3,0x76,0x17,0x04,0xDA,0x62,0x71,0x58,
	0xEA,0x99,0xC3,0x06,0xA7,0xE8,0xDB,0xA9,0x05,0xEC,0xA3,0xCA,0xDA,0x2E,0x77,0x66,
	0xF4,0xC4,0xD2,0xC6,0xF0,0x5F,0xE6,0x88,0xDF,0x7F,0x23,0xDE,0x7B,0x04,0xA4,0x22,
	0x45,0xEF,0x0A,0x13,0x79,0x8E,0xE1,0x14,0x22,0x79,0x22,0x86,0x1A,0x4C,0xA7,0xBA,
	0x06,0x55,0xD9,0x5E,0xF3,0x9C,0xE0,0x1F,0xE3,0xA4,0x1C,0x8E,0x01,0x9F,0x7E,0xEF,
	0xD2,0xA7,0x8D,0xD6,0x4D,0x1A,0x3D,0xA7,0xB2,0xDB,0x44,0x25,0xB5,0xA6,0x8A,0xD5,
	0x49,0x87,0x04,0x6C,0x41,0x13,0x88,0x7A,0xFB,0x5E,0x16,0xA2,0x8F,0x37,0x81,0x47,
	0xD8,0x27,0x3D,0xBD,0xB1,0x3E,0xCE,0x2A,0x07,0x75,0x45,0x5F,0x44,
};

unsigned char LEAF_CERT[1037]={
	0x30,0x82,0x04,0x09,0x30,0x82,0x02,0xF1,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x03,
	0x30,0x0B,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x30,0x81,0xA5,
	0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x54,0x65,0x73,0x74,0x2D,
	0x35,0x36,0x38,0x35,0x33,0x31,0x36,0x2D,0x49,0x4E,0x54,0x45,0x52,0x4D,0x45,0x44,
	0x49,0x41,0x54,0x45,0x31,0x0E,0x30,0x0C,0x06,0x03,0x55,0x04,0x0A,0x0C,0x05,0x41,
	0x70,0x70,0x6C,0x65,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0B,0x43,
	0x6F,0x72,0x65,0x20,0x43,0x72,0x79,0x70,0x74,0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,
	0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
	0x13,0x02,0x55,0x53,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,
	0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x2B,0x30,0x29,0x06,0x09,0x2A,0x86,
	0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x1C,0x73,0x65,0x63,0x75,0x72,0x69,0x74,
	0x79,0x2D,0x64,0x65,0x76,0x40,0x67,0x72,0x6F,0x75,0x70,0x2E,0x61,0x70,0x70,0x6C,
	0x65,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x30,0x39,0x31,0x32,0x31,0x38,0x31,
	0x37,0x33,0x32,0x31,0x36,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x31,0x38,0x31,0x37,
	0x33,0x32,0x31,0x36,0x5A,0x30,0x81,0x9D,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,
	0x03,0x0C,0x11,0x54,0x65,0x73,0x74,0x2D,0x35,0x36,0x38,0x35,0x33,0x31,0x36,0x2D,
	0x4C,0x45,0x41,0x46,0x31,0x0E,0x30,0x0C,0x06,0x03,0x55,0x04,0x0A,0x0C,0x05,0x41,
	0x70,0x70,0x6C,0x65,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0B,0x43,
	0x6F,0x72,0x65,0x20,0x43,0x72,0x79,0x70,0x74,0x6F,0x31,0x0B,0x30,0x09,0x06,0x03,
	0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
	0x13,0x02,0x55,0x53,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,
	0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x2B,0x30,0x29,0x06,0x09,0x2A,0x86,
	0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x1C,0x73,0x65,0x63,0x75,0x72,0x69,0x74,
	0x79,0x2D,0x64,0x65,0x76,0x40,0x67,0x72,0x6F,0x75,0x70,0x2E,0x61,0x70,0x70,0x6C,
	0x65,0x2E,0x63,0x6F,0x6D,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
	0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,
	0x0A,0x02,0x82,0x01,0x01,0x00,0xBF,0x1B,0x87,0x6B,0x10,0xF8,0xF6,0x24,0x07,0x40,
	0xC3,0xE3,0x81,0x26,0xD6,0xF4,0xFF,0xAA,0x6C,0x26,0xD4,0xBF,0xF7,0x9A,0xF5,0xB8,
	0x63,0xBD,0x8B,0xFD,0x4B,0xFE,0xFF,0x4B,0xA2,0x15,0x13,0x52,0x84,0x87,0x9E,0x2B,
	0x32,0x5B,0xF8,0x01,0x28,0x5E,0xF1,0x9C,0xE7,0x52,0xB0,0x89,0xB8,0x4A,0xD0,0x87,
	0x40,0x0C,0xCD,0xAC,0x11,0x22,0x89,0x44,0x26,0x3B,0x40,0xF3,0x34,0x61,0x14,0x3A,
	0x94,0xF3,0x1F,0x27,0x62,0xF8,0x8C,0xB4,0xF5,0x1E,0xA6,0x37,0x53,0xB2,0xB3,0x1E,
	0x35,0xF6,0x00,0x34,0x4B,0x28,0x72,0x5B,0x9D,0xD8,0xEA,0x06,0x91,0x77,0x57,0x38,
	0x9C,0xA5,0x66,0x5F,0x1A,0x9A,0x0B,0xCC,0x2F,0x2E,0x58,0xA2,0x70,0x66,0xA6,0xEF,
	0x1B,0x3A,0x0E,0xF0,0x4B,0xA6,0x9D,0x6D,0x63,0xE0,0x1C,0x9C,0x8E,0xFF,0x6F,0x50,
	0x5F,0x03,0x1A,0x80,0x12,0x4A,0xB6,0x89,0x83,0x5C,0x51,0x9F,0x2F,0xEA,0xE4,0x7F,
	0x12,0xFB,0xE4,0x92,0xF0,0x8B,0x17,0x35,0x02,0x73,0xA0,0x7D,0xA2,0xB9,0x89,0xE2,
	0x78,0x52,0xA1,0x08,0x42,0x78,0xD5,0xD3,0x8C,0x3C,0xF2,0x88,0x5E,0x7A,0xCC,0x94,
	0x80,0x42,0xEA,0xED,0x6E,0x64,0x19,0x5E,0x53,0x05,0xB6,0x60,0xDB,0x81,0x92,0x2C,
	0x3D,0xD4,0xAF,0xF8,0xED,0xD9,0x28,0xCE,0x0B,0xD9,0xDC,0x20,0x0C,0xA9,0x8D,0xA4,
	0x54,0xD1,0xDA,0xDE,0x30,0x4A,0x67,0xC6,0xAC,0x4E,0xE3,0xB4,0xD7,0x16,0xF5,0xDC,
	0xE3,0x52,0xAC,0x01,0x1C,0xB6,0xC1,0x5B,0xB4,0xEA,0x67,0x25,0xFE,0xF6,0x58,0x5C,
	0xFE,0x88,0x4E,0xCF,0xF1,0x11,0x02,0x03,0x01,0x00,0x01,0xA3,0x4C,0x30,0x4A,0x30,
	0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,
	0x0F,0x06,0x03,0x55,0x1D,0x25,0x04,0x08,0x30,0x06,0x06,0x04,0x55,0x1D,0x25,0x00,
	0x30,0x27,0x06,0x03,0x55,0x1D,0x11,0x04,0x20,0x30,0x1E,0x81,0x1C,0x73,0x65,0x63,
	0x75,0x72,0x69,0x74,0x79,0x2D,0x64,0x65,0x76,0x40,0x67,0x72,0x6F,0x75,0x70,0x2E,
	0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
	0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x1A,0xE5,0xD1,
	0x13,0x66,0x83,0xC7,0x1A,0xB0,0x50,0xF0,0x1B,0x6E,0x70,0x6E,0x36,0x1A,0x0F,0x12,
	0x9E,0x0B,0xFD,0x4B,0x79,0xEC,0xAA,0x5E,0x2A,0x37,0x79,0x50,0x97,0x13,0x9E,0xB6,
	0x43,0xF0,0xD2,0xC6,0xF3,0x43,0x73,0x33,0x6C,0xCB,0x73,0xE5,0xBE,0x4C,0x42,0x6F,
	0x33,0x76,0x96,0xA2,0x6B,0xA0,0x8D,0xAD,0x46,0xA5,0xD4,0xAC,0x0E,0x55,0x80,0x1A,
	0x6E,0xAF,0xC2,0x2E,0xB3,0xD4,0x64,0xC3,0x65,0xFA,0x1C,0x42,0x47,0x12,0x9F,0x44,
	0xD2,0x1F,0xCF,0xA1,0x53,0x49,0x66,0x66,0x14,0x21,0xD4,0x17,0xD1,0x26,0x75,0xAD,
	0x08,0x93,0x9C,0x3B,0xB7,0x7C,0x03,0x2F,0x76,0x5D,0xB7,0x25,0x83,0x68,0xE3,0x01,
	0x5C,0xCD,0x87,0x7A,0x71,0x8B,0x8D,0x5D,0x27,0x27,0xF2,0x24,0x56,0x7C,0x7E,0x33,
	0x8F,0xE6,0x02,0x46,0xAD,0x63,0x28,0x85,0xA2,0x9E,0xEA,0x5A,0xC4,0x92,0xCE,0x76,
	0xE8,0xD4,0xD4,0x7D,0x48,0x44,0xA4,0x21,0x8C,0xB7,0xC2,0x15,0x80,0x87,0x19,0xB1,
	0x10,0x6A,0xC7,0x51,0xB7,0x25,0x40,0x26,0x8A,0xCC,0xB6,0x0C,0xE2,0x0D,0xA1,0x40,
	0x20,0x85,0x0F,0xE5,0xB9,0xB5,0x32,0x10,0xA9,0x5F,0x25,0xCA,0xD2,0x95,0x11,0x54,
	0x41,0xEA,0xC3,0xBA,0x0C,0x24,0x10,0x28,0xC9,0x09,0xAF,0x7E,0xDF,0x6A,0x2F,0x30,
	0x49,0x7C,0xB0,0x23,0x46,0xA8,0xDC,0xE3,0x6A,0x17,0x87,0xF7,0xCC,0x3A,0xBD,0x11,
	0x95,0xC3,0x0A,0x37,0xD1,0x1F,0x20,0xB6,0x1B,0xB2,0xA2,0x45,0xFF,0xC1,0x0D,0x9A,
	0x56,0xCD,0x5A,0xF6,0x08,0xAA,0xBD,0xAB,0x13,0xC6,0xFD,0xAA,0xEC,
};

/* Test certificate for Code Signing policy
 */
unsigned char Test_codesign[1017]={
	0x30,0x82,0x03,0xF5,0x30,0x82,0x02,0xDD,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x77,
	0xCE,0xF5,0x3D,0x30,0x0B,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
	0x30,0x81,0xA5,0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x54,0x65,
	0x73,0x74,0x2D,0x35,0x36,0x38,0x35,0x33,0x31,0x36,0x2D,0x49,0x4E,0x54,0x45,0x52,
	0x4D,0x45,0x44,0x49,0x41,0x54,0x45,0x31,0x0E,0x30,0x0C,0x06,0x03,0x55,0x04,0x0A,
	0x0C,0x05,0x41,0x70,0x70,0x6C,0x65,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0B,
	0x0C,0x0B,0x43,0x6F,0x72,0x65,0x20,0x43,0x72,0x79,0x70,0x74,0x6F,0x31,0x0B,0x30,
	0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x0B,0x30,0x09,0x06,0x03,
	0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,
	0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x2B,0x30,0x29,0x06,
	0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x1C,0x73,0x65,0x63,0x75,
	0x72,0x69,0x74,0x79,0x2D,0x64,0x65,0x76,0x40,0x67,0x72,0x6F,0x75,0x70,0x2E,0x61,
	0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x31,0x30,0x30,0x35,
	0x32,0x30,0x30,0x31,0x32,0x35,0x33,0x32,0x5A,0x17,0x0D,0x31,0x31,0x30,0x35,0x32,
	0x30,0x30,0x31,0x32,0x35,0x33,0x32,0x5A,0x30,0x81,0xA8,0x31,0x24,0x30,0x22,0x06,
	0x03,0x55,0x04,0x03,0x0C,0x1B,0x54,0x65,0x73,0x74,0x2D,0x37,0x38,0x37,0x35,0x38,
	0x30,0x31,0x20,0x28,0x43,0x6F,0x64,0x65,0x20,0x53,0x69,0x67,0x6E,0x69,0x6E,0x67,
	0x29,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,
	0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0B,0x0C,
	0x07,0x43,0x6F,0x72,0x65,0x20,0x4F,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,
	0x08,0x0C,0x02,0x43,0x41,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
	0x55,0x53,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,
	0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x2B,0x30,0x29,0x06,0x09,0x2A,0x86,0x48,0x86,
	0xF7,0x0D,0x01,0x09,0x01,0x16,0x1C,0x73,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x2D,
	0x64,0x65,0x76,0x40,0x67,0x72,0x6F,0x75,0x70,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,
	0x63,0x6F,0x6D,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
	0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,
	0x82,0x01,0x01,0x00,0xC0,0x5E,0x52,0x53,0xB0,0x05,0x8D,0x9E,0xF2,0xBF,0x2E,0xA1,
	0x95,0xD5,0x10,0x97,0xFC,0x8E,0x77,0x6E,0x63,0x7A,0x7D,0xD2,0x56,0x05,0xE9,0xEE,
	0x3D,0xEE,0xCA,0xA4,0xBB,0x99,0x42,0xA2,0x55,0x67,0x97,0x15,0xFB,0x94,0x6D,0x22,
	0x39,0x7F,0xE9,0xC0,0x72,0x41,0x8F,0xF5,0x76,0x55,0x65,0x3B,0x39,0x5F,0x31,0x15,
	0x72,0x2A,0xB4,0x2F,0xED,0xB7,0x6A,0x3E,0xE9,0x3A,0x1C,0x50,0xD4,0x31,0x6D,0x7A,
	0x71,0x28,0x98,0x8D,0x8A,0xBF,0x90,0x01,0x8A,0xFF,0x42,0x62,0xEB,0xE5,0xC8,0x5A,
	0xB2,0x5A,0xB8,0x46,0x27,0xDA,0xD5,0x70,0xAF,0xD4,0xF6,0xF2,0xEC,0xD6,0x43,0x7E,
	0x25,0x31,0xED,0xA2,0x1E,0xFA,0x77,0xF4,0x59,0xBF,0x3F,0x11,0xAE,0xF1,0x0E,0xC9,
	0xFD,0x56,0xCA,0xA0,0x3E,0x8B,0xA5,0xE9,0xF6,0x91,0x82,0xE0,0xC6,0x5E,0x35,0x92,
	0x3F,0x0E,0x77,0x23,0x88,0x6F,0x33,0x91,0xAC,0x98,0xC5,0xF5,0x52,0x12,0xB2,0x3A,
	0x08,0x66,0xEB,0xC8,0x14,0x8E,0xED,0x0F,0xE5,0x76,0xCE,0x36,0xE8,0xED,0xB6,0x41,
	0xD6,0xF3,0x1C,0x24,0xBA,0xCC,0xEE,0x28,0xF8,0xC8,0xAE,0x87,0x15,0x1D,0x33,0x47,
	0xEA,0x5B,0x7D,0xE2,0x80,0xA9,0x6B,0xE3,0x8B,0x36,0xD0,0x25,0x2C,0x32,0xDA,0xFF,
	0x7C,0x85,0x28,0x48,0xDB,0x35,0x2A,0x1A,0xBE,0x7F,0xCD,0xE1,0xA6,0x79,0x35,0xB3,
	0x79,0xA3,0xB9,0x15,0xC6,0x31,0xA1,0xB4,0x63,0xD8,0x05,0x1D,0xDD,0x11,0x74,0xCD,
	0xCF,0xBD,0x27,0x02,0xB7,0xD8,0xA9,0xA1,0x1D,0xFB,0xA1,0xEC,0x44,0x8D,0x21,0x64,
	0x84,0x2E,0x6B,0x3B,0x02,0x03,0x01,0x00,0x01,0xA3,0x2A,0x30,0x28,0x30,0x0E,0x06,
	0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x16,0x06,
	0x03,0x55,0x1D,0x25,0x01,0x01,0xFF,0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,
	0x05,0x05,0x07,0x03,0x03,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,
	0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x80,0xC4,0xB6,0x9D,0xBE,0x72,0x30,
	0x72,0xFD,0x49,0x43,0x8F,0x3B,0xFE,0xC6,0xF1,0x4D,0xAA,0xB3,0xD1,0xD6,0x0C,0x54,
	0x9D,0x24,0xDF,0x86,0x9B,0x0A,0x68,0x55,0x4B,0x5A,0x20,0x53,0xC0,0xBF,0x82,0xAF,
	0xC7,0x19,0x19,0x43,0xA1,0xA4,0x53,0xF4,0xE5,0x33,0xE6,0xF7,0xAD,0x8E,0x6D,0xD8,
	0x94,0x23,0xEB,0x3E,0x6A,0xCF,0xDA,0x4B,0x09,0x6E,0x26,0x2B,0x62,0x70,0x98,0x0A,
	0xCE,0x58,0x70,0xA6,0xAD,0x08,0x45,0xAB,0x9E,0x89,0xBB,0xF8,0x84,0x6F,0x0D,0x9B,
	0x77,0xBA,0x60,0x9E,0xB8,0xA6,0xB6,0x7D,0x20,0xE9,0x83,0x72,0xE1,0xE9,0xB0,0x0E,
	0x0D,0x27,0xFB,0xD0,0x4C,0x81,0x88,0xAF,0x82,0x8F,0xB9,0x82,0xAD,0x1D,0x1B,0x54,
	0x11,0x84,0x16,0xFC,0x0B,0x53,0xB8,0xED,0x71,0xA2,0x6A,0xD9,0xC7,0x88,0xEE,0xD6,
	0x0C,0x5E,0xAD,0x2E,0x50,0xBA,0x56,0x12,0x95,0x5C,0x7F,0xF1,0x3B,0x48,0xB5,0x17,
	0x53,0xA9,0xC5,0x4C,0xD6,0x8C,0x39,0xCB,0x1A,0x5B,0xB6,0x4B,0x73,0x67,0x1E,0xB5,
	0x7D,0x13,0xAE,0x6B,0xD5,0xF4,0x59,0xE3,0xA1,0x4C,0x6A,0xEC,0xA5,0x27,0x07,0x9D,
	0x93,0x8F,0xF5,0xBB,0x50,0x28,0x00,0x05,0x25,0xCD,0xED,0xF7,0xA9,0x11,0x22,0x7E,
	0x92,0x4D,0xF5,0x7C,0x55,0xF4,0x1C,0x7A,0xA3,0xBC,0x24,0xC7,0xFB,0xED,0x6A,0x0A,
	0x1E,0xD5,0x9D,0x63,0xE0,0x2B,0x91,0x59,0x48,0xF2,0xF6,0xEB,0xF9,0xEB,0x9E,0x4D,
	0x3E,0xAE,0x44,0x9D,0xF9,0x93,0xB5,0x44,0xA1,0x36,0x3E,0x4E,0xC7,0xD9,0x47,0x83,
	0xCE,0xDD,0xA0,0x7C,0xA1,0xB4,0x75,0x1F,0xC8,
};

/* Test certificate for S/MIME policy (encrypt only, no sign)
 */
unsigned char Test_smime_encryptonly[1060]={
	0x30,0x82,0x04,0x20,0x30,0x82,0x03,0x08,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x77,
	0xCF,0x46,0x7D,0x30,0x0B,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
	0x30,0x81,0xA5,0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x54,0x65,
	0x73,0x74,0x2D,0x35,0x36,0x38,0x35,0x33,0x31,0x36,0x2D,0x49,0x4E,0x54,0x45,0x52,
	0x4D,0x45,0x44,0x49,0x41,0x54,0x45,0x31,0x0E,0x30,0x0C,0x06,0x03,0x55,0x04,0x0A,
	0x0C,0x05,0x41,0x70,0x70,0x6C,0x65,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0B,
	0x0C,0x0B,0x43,0x6F,0x72,0x65,0x20,0x43,0x72,0x79,0x70,0x74,0x6F,0x31,0x0B,0x30,
	0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x0B,0x30,0x09,0x06,0x03,
	0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,
	0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x2B,0x30,0x29,0x06,
	0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x1C,0x73,0x65,0x63,0x75,
	0x72,0x69,0x74,0x79,0x2D,0x64,0x65,0x76,0x40,0x67,0x72,0x6F,0x75,0x70,0x2E,0x61,
	0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x31,0x30,0x30,0x37,
	0x32,0x37,0x32,0x30,0x35,0x39,0x35,0x38,0x5A,0x17,0x0D,0x31,0x32,0x30,0x37,0x32,
	0x37,0x32,0x30,0x35,0x39,0x35,0x38,0x5A,0x30,0x81,0xB2,0x31,0x21,0x30,0x1F,0x06,
	0x03,0x55,0x04,0x03,0x0C,0x18,0x54,0x65,0x73,0x74,0x2D,0x45,0x6E,0x63,0x72,0x79,
	0x70,0x74,0x69,0x6F,0x6E,0x20,0x28,0x53,0x2F,0x4D,0x49,0x4D,0x45,0x29,0x31,0x13,
	0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,
	0x6E,0x63,0x2E,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B,0x0C,0x1C,0x43,0x6F,
	0x72,0x65,0x20,0x4F,0x53,0x20,0x49,0x6E,0x66,0x6F,0x72,0x6D,0x61,0x74,0x69,0x6F,
	0x6E,0x20,0x53,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x31,0x0B,0x30,0x09,0x06,0x03,
	0x55,0x04,0x08,0x0C,0x02,0x43,0x41,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
	0x13,0x02,0x55,0x53,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x0C,0x09,0x43,
	0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x23,0x30,0x21,0x06,0x09,0x2A,0x86,
	0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x14,0x73,0x6D,0x69,0x6D,0x65,0x2D,0x74,
	0x65,0x73,0x74,0x40,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x82,0x01,
	0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,
	0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xBB,0x8F,
	0xC3,0x01,0xD7,0x8A,0x62,0xE2,0xDD,0x26,0xE3,0x13,0x3E,0x61,0xC7,0x90,0xDE,0x98,
	0xCB,0x4A,0xC6,0x80,0xB3,0x36,0x99,0x8A,0xDE,0x6D,0xCF,0x60,0x7B,0x38,0x2E,0x86,
	0x0F,0x9E,0x9F,0xB0,0xCB,0x23,0xB1,0x52,0x0E,0x6E,0x70,0xD5,0x8D,0x56,0x32,0x36,
	0x35,0x7D,0x59,0x32,0xE6,0x3F,0x67,0x2F,0xC0,0x0F,0x2B,0x85,0x47,0x20,0x70,0x22,
	0xE5,0xB0,0x3C,0xF7,0xE3,0x4A,0x40,0xA5,0xB2,0x28,0xE5,0xB1,0x85,0x47,0x54,0x03,
	0xD1,0xB6,0x96,0x3E,0xDB,0x8D,0xD0,0x0E,0x5E,0x7A,0x65,0x2A,0x8A,0xBE,0xF7,0xB0,
	0x28,0x70,0x42,0x55,0x5A,0xAE,0xE6,0x58,0x91,0x20,0x5D,0x5B,0xFF,0x9B,0xF0,0x0C,
	0x49,0x94,0x55,0x68,0x46,0x34,0x2A,0xE4,0xA1,0x69,0x89,0xC8,0xB1,0xE7,0x07,0xB7,
	0xEC,0x2C,0x8A,0x65,0xF0,0xC6,0x51,0x3F,0x7C,0xC9,0x6F,0x42,0x71,0x15,0x30,0x9F,
	0xB5,0xA7,0xA5,0xD1,0xFE,0x2B,0x46,0x4F,0x3D,0xFD,0xCD,0xA8,0x1B,0x82,0x7B,0xA0,
	0x7B,0x9F,0x34,0x00,0xB7,0xC5,0x9F,0xCC,0x74,0xB4,0x35,0xC6,0x31,0x38,0x8D,0x91,
	0x79,0xE8,0xAF,0xCB,0xE4,0x17,0x78,0x11,0x7A,0x41,0xB1,0xF8,0x4D,0x2C,0xEE,0x7E,
	0x8D,0xEB,0x09,0x89,0xDC,0x74,0x2B,0xC1,0x25,0x57,0x3E,0x55,0x79,0x98,0x8B,0x5C,
	0xCF,0x05,0x38,0x69,0xF9,0x99,0x07,0x42,0x6D,0x99,0x1B,0x5E,0x89,0xBD,0xB6,0x4B,
	0x52,0x0F,0xDD,0xF9,0x67,0x53,0xDF,0xE2,0x25,0xBC,0x6C,0x72,0x19,0x6A,0x28,0xCE,
	0x6A,0xB4,0x22,0x93,0x20,0xDE,0xB6,0xF5,0x83,0x6A,0xC6,0x82,0x36,0x2B,0x02,0x03,
	0x01,0x00,0x01,0xA3,0x4B,0x30,0x49,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,
	0xFF,0x04,0x04,0x03,0x02,0x05,0x20,0x30,0x16,0x06,0x03,0x55,0x1D,0x25,0x01,0x01,
	0xFF,0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04,0x30,
	0x1F,0x06,0x03,0x55,0x1D,0x11,0x04,0x18,0x30,0x16,0x81,0x14,0x73,0x6D,0x69,0x6D,
	0x65,0x2D,0x74,0x65,0x73,0x74,0x40,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,
	0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,
	0x82,0x01,0x01,0x00,0x7D,0xB4,0x4B,0x4B,0xE1,0xB3,0x29,0x22,0x72,0x7E,0x66,0xEA,
	0x78,0x51,0xBB,0x38,0xA0,0x44,0x6E,0xAE,0xB7,0xFE,0x43,0x24,0x78,0xAE,0x93,0x3B,
	0xF0,0x2B,0xAB,0x31,0x61,0x9F,0x6E,0x1F,0x89,0x0F,0x2C,0xD0,0xC4,0x29,0xE0,0x1C,
	0x4C,0x7B,0x96,0x82,0x0D,0x29,0x08,0x1F,0xDE,0x35,0xA2,0x12,0x0D,0xB4,0xA0,0x5D,
	0xE4,0xE8,0x38,0xC3,0x5C,0x99,0xFD,0x2E,0xE9,0x3B,0xC7,0xFC,0x67,0x3D,0xBD,0x1E,
	0x46,0x3A,0xDD,0xFB,0x24,0xF0,0x83,0x77,0x4F,0xA0,0x63,0x40,0x58,0x28,0x3C,0x32,
	0x3B,0xEB,0x8B,0x20,0x29,0xFD,0x22,0x4A,0xEC,0x3C,0x78,0xE2,0xD5,0xD3,0x54,0x35,
	0x8F,0x4D,0x48,0x61,0x2E,0xB6,0xC1,0xE5,0x3A,0x95,0xCD,0xBF,0x73,0xA2,0x1A,0x15,
	0xC3,0x24,0x0F,0xDB,0x86,0x08,0x55,0x01,0xBC,0x8C,0x4F,0x83,0x4E,0x90,0x55,0x84,
	0xF8,0x82,0xB1,0x1E,0x9F,0x70,0xD3,0xE8,0xE8,0xD3,0xDB,0x97,0xE0,0x66,0xAA,0x54,
	0x58,0x32,0x16,0x56,0xA3,0xF3,0x9B,0xCE,0xC4,0xA3,0x65,0x66,0x71,0xFD,0x20,0x87,
	0x3A,0x34,0x74,0xAB,0x6B,0x26,0xB8,0x18,0x8A,0x77,0xFF,0x77,0x21,0x6A,0xF0,0x38,
	0x12,0x74,0x45,0x1F,0x67,0x3D,0xBD,0xDF,0xBF,0x32,0x82,0x8E,0x4D,0xC5,0x3D,0x59,
	0x07,0xCD,0x1A,0x05,0xB6,0x96,0xD7,0x95,0xDB,0x44,0x81,0x59,0xD7,0x2A,0x88,0x0D,
	0x3C,0xD8,0xD5,0x2B,0x92,0xA8,0xC1,0x8D,0xDE,0x60,0x6F,0x98,0xE4,0x3C,0xB8,0xEC,
	0x52,0x2A,0x56,0x6E,0xF1,0x76,0x56,0x64,0x3D,0xD9,0x09,0xB9,0x4B,0x73,0xEF,0x11,
	0x78,0xFB,0xA6,0x9A,
};

/* Test identity for S/MIME policy (sign only, no encrypt)
 */
unsigned char Test_smime_signonly_p12[2761] = {
	0x30,0x82,0x0a,0xc5,0x02,0x01,0x03,0x30,0x82,0x0a,0x8c,0x06,0x09,0x2a,0x86,0x48,
	0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x82,0x0a,0x7d,0x04,0x82,0x0a,0x79,0x30,0x82,
	0x0a,0x75,0x30,0x82,0x04,0xef,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
	0x06,0xa0,0x82,0x04,0xe0,0x30,0x82,0x04,0xdc,0x02,0x01,0x00,0x30,0x82,0x04,0xd5,
	0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x1c,0x06,0x0a,0x2a,
	0x86,0x48,0x86,0xf7,0x0d,0x01,0x0c,0x01,0x06,0x30,0x0e,0x04,0x08,0x03,0x00,0x56,
	0xda,0x33,0x28,0xb6,0xbc,0x02,0x02,0x08,0x00,0x80,0x82,0x04,0xa8,0x36,0xa9,0x2d,
	0xab,0xcc,0x17,0x76,0x6e,0x1c,0xf2,0x82,0xb1,0xc1,0xac,0x19,0xbe,0xb3,0x71,0x4f,
	0x1a,0xe6,0x0f,0x2d,0x7e,0xd4,0x66,0x0a,0x70,0x85,0x41,0xa5,0x92,0x06,0x02,0x71,
	0x0f,0x7a,0xed,0xef,0x52,0x96,0xd2,0x67,0xf4,0xa8,0x5b,0xde,0x6e,0xc6,0xdc,0xc6,
	0xe8,0x6e,0x86,0x11,0x94,0x60,0x0d,0xa1,0x24,0x57,0x1f,0x51,0xd8,0x7d,0x28,0xf9,
	0x10,0xcb,0x68,0x1b,0x32,0xe4,0xa3,0x60,0x7c,0xb2,0x2b,0x33,0x4e,0x23,0xec,0x60,
	0x4c,0xe0,0x1a,0x39,0x03,0x60,0xb7,0x09,0x4d,0xb7,0x8c,0x94,0x91,0x44,0xa7,0xc7,
	0x3b,0xd7,0xc5,0xc5,0x0f,0x4a,0x54,0xe5,0xee,0x41,0xd5,0x32,0xf2,0xfc,0x7a,0x4d,
	0x68,0x5d,0xfc,0xe9,0xab,0xa0,0x74,0xb9,0x6f,0x68,0xc4,0x68,0xa1,0x91,0x5d,0x74,
	0x2b,0x06,0xfc,0xa7,0x93,0x2c,0xc3,0x8e,0xaf,0x12,0x84,0x09,0x1f,0xa8,0xd7,0xb3,
	0xf2,0x13,0x33,0xdf,0xd2,0xa5,0x34,0xa5,0x08,0x73,0xea,0x8f,0xc3,0x88,0xd4,0xa1,
	0xce,0xa9,0x56,0xc4,0x4f,0xc9,0x48,0xfb,0x84,0x26,0x16,0xc8,0x1a,0x15,0x6d,0x10,
	0x8e,0x4e,0x85,0xfc,0x8b,0xb7,0xfc,0x69,0x6a,0x79,0xc0,0xff,0xed,0xfd,0x7b,0x0b,
	0x7f,0x5b,0x8d,0x89,0x4e,0xb6,0x25,0x0e,0x04,0x42,0xdb,0x15,0x7b,0xbc,0x7b,0x75,
	0x91,0x12,0x7c,0x0f,0x22,0xfd,0xd4,0x4d,0x3c,0x9c,0x6c,0x10,0x40,0x9e,0x3e,0x0b,
	0xfd,0x2e,0x2d,0x23,0x27,0x96,0x86,0x85,0x44,0xdd,0xc4,0x44,0xbf,0x74,0x09,0x2f,
	0x90,0x48,0x3d,0x8a,0x05,0xbe,0x44,0xe5,0x75,0x1f,0x4e,0xbc,0x91,0xfd,0xf5,0x1a,
	0xde,0xd4,0x99,0xf4,0xbe,0x2f,0x28,0xbf,0x47,0x49,0x90,0xb5,0xea,0xd6,0x48,0xcb,
	0x7b,0xde,0xea,0x3d,0x07,0x8d,0xf4,0x7c,0xd7,0x4d,0xcb,0xc1,0xcb,0xa3,0x30,0x2f,
	0x7c,0x59,0x09,0xad,0xb3,0x27,0x66,0x2a,0x87,0x51,0xd7,0x7b,0xbb,0xb1,0x6d,0x4e,
	0x0e,0x1a,0x6a,0x7a,0xf8,0x31,0x99,0xa8,0x1c,0x06,0x1a,0x4e,0x83,0xa8,0xac,0xaf,
	0x72,0xdb,0x89,0x1b,0xe1,0x9d,0x52,0x22,0x94,0xaf,0x6a,0xe0,0x5c,0x60,0xd5,0xf2,
	0x6a,0xde,0x1f,0x51,0xb0,0x19,0x13,0xff,0xb9,0xfe,0x15,0xeb,0x4a,0x5c,0x44,0xe6,
	0xbd,0x3d,0xbd,0xdc,0xb2,0xa8,0x96,0xa2,0x05,0x7e,0xdc,0x39,0x15,0x7a,0xc9,0xdc,
	0xb3,0x2b,0xa2,0x1c,0xe1,0x78,0xfb,0x5b,0x12,0x35,0xc2,0x05,0xed,0x59,0xa2,0xf1,
	0x8d,0x5b,0xe2,0xf8,0x95,0xc7,0xdd,0x20,0xf9,0xcc,0xfd,0x43,0xbe,0x03,0x0f,0xdb,
	0xa1,0x21,0x7b,0x86,0x0e,0x0b,0x26,0xbd,0x38,0x10,0x62,0xbc,0x5c,0x43,0x48,0x6f,
	0xbc,0x6c,0x68,0x83,0xd4,0x54,0x5b,0x80,0x25,0x13,0x69,0x18,0xce,0x8e,0xe9,0x3f,
	0xfb,0x81,0x51,0x92,0x19,0x3f,0x4b,0x41,0x53,0x39,0x3e,0xa2,0xef,0x90,0x59,0x5c,
	0x30,0x22,0x36,0xed,0x78,0x78,0xc5,0x70,0x9c,0x8b,0x96,0x8d,0xe8,0x7a,0x9b,0x27,
	0xdc,0x9b,0x4f,0x2b,0x30,0x86,0x27,0x95,0x70,0x8f,0xc0,0xd5,0xd4,0x79,0x9f,0x0f,
	0x38,0x49,0x1d,0xe9,0x76,0xcf,0x6c,0x34,0x06,0xc0,0xfa,0xa0,0xab,0x41,0x1c,0x26,
	0x04,0x18,0x0f,0xa8,0x45,0xf5,0xdc,0x82,0x5d,0x8a,0xe6,0x2b,0x84,0xe9,0xaa,0xa2,
	0xbd,0xf4,0xc6,0x94,0xa6,0xbb,0x6f,0x35,0x3c,0x5f,0x9a,0x45,0xd3,0x3e,0x6b,0x75,
	0x54,0x10,0x5a,0x6f,0x0c,0x26,0xe7,0xb1,0x92,0x6c,0x93,0xf1,0xce,0x02,0x97,0xbe,
	0xf8,0x76,0xbc,0x9b,0xff,0x09,0xe2,0x8a,0x62,0xdc,0x19,0xfa,0x33,0x94,0x07,0x4b,
	0x7d,0x62,0xe3,0xca,0xc6,0x1e,0xc4,0x18,0xd7,0xa8,0xbb,0x79,0xd1,0x4e,0x2e,0x37,
	0xa4,0x02,0x06,0x80,0xa4,0xed,0xbf,0x3e,0x8b,0xc7,0xcd,0xf2,0xa5,0x8f,0x68,0x1e,
	0xb2,0x72,0xc2,0xa2,0xa7,0x8d,0x03,0x51,0x0f,0xe2,0x7a,0x04,0x03,0x83,0x2f,0x71,
	0x16,0x85,0x7e,0xf3,0x29,0xc7,0x31,0x27,0x24,0xae,0x8b,0x08,0xe7,0x6b,0x7d,0x5f,
	0x27,0xdd,0xdb,0x28,0x63,0x65,0xbb,0x2a,0x6e,0x63,0xc4,0xa4,0x90,0x36,0x8e,0xc4,
	0x8b,0x55,0x6f,0x99,0x4f,0xf3,0x63,0xef,0xc7,0x3a,0xd5,0x55,0xf3,0x98,0xaa,0x9c,
	0x20,0x9d,0x9b,0x07,0x44,0x92,0x27,0x2c,0xc5,0x22,0x78,0x85,0x66,0x71,0xd5,0x0f,
	0xea,0xa7,0xdc,0x0c,0xad,0x07,0x2a,0xa5,0x34,0xca,0xbc,0x8e,0xff,0xfd,0x0b,0xb0,
	0x9d,0x21,0x16,0x9d,0xfa,0x21,0xaf,0xec,0x25,0x6a,0xd7,0x7d,0xff,0xe6,0x73,0xe3,
	0x6c,0x4e,0x9c,0xe0,0xeb,0x0c,0x56,0x32,0xa9,0xbb,0x48,0xe5,0xa7,0x4b,0x59,0x1d,
	0x70,0x31,0xf2,0x79,0x88,0x50,0xc4,0x59,0x01,0x3c,0xc2,0x61,0xbe,0xe7,0xbc,0xc0,
	0x6f,0xb4,0x27,0x90,0xcd,0x4f,0x44,0x60,0x9f,0x02,0x5a,0x68,0x81,0xb6,0x6f,0x78,
	0x10,0xd3,0x3e,0xb3,0xb4,0xc5,0x6f,0xa6,0x3e,0x77,0x30,0x29,0xd7,0xa7,0xda,0x5f,
	0xb4,0x3e,0x3f,0xf9,0xb3,0x04,0xd8,0xe5,0x75,0xc5,0x1e,0xcf,0xa6,0x85,0x4c,0x57,
	0xf6,0xbb,0x8f,0xda,0x80,0x02,0x4b,0x79,0x0f,0x94,0xed,0x98,0xdb,0x64,0x8d,0x8f,
	0x8e,0x90,0x5b,0x31,0x80,0x1b,0x50,0x8b,0x99,0x7b,0x23,0x94,0xf2,0x1e,0x8e,0xe6,
	0xce,0x7f,0x2f,0x16,0x64,0x7f,0xdb,0x16,0x08,0x97,0x78,0x5c,0x4d,0xef,0x9c,0x63,
	0x0f,0x37,0x14,0x58,0x68,0x57,0x29,0x42,0xd3,0x4d,0x97,0x62,0xe8,0x08,0xe4,0x60,
	0x87,0x07,0x73,0x11,0x21,0x5e,0x8c,0x97,0x78,0xdb,0x2f,0x81,0xb3,0xa0,0xfd,0x17,
	0x0b,0xf0,0x29,0x88,0x1a,0x39,0xec,0x0c,0xfb,0x30,0x0d,0x0a,0x9a,0x60,0xe2,0xaf,
	0xf9,0xb3,0x9c,0xdd,0xa6,0x2e,0x7c,0x90,0xf7,0x31,0x3c,0x35,0xe8,0x2f,0xdd,0x54,
	0xdf,0x45,0x54,0xcf,0xdd,0xfc,0xf6,0x36,0x3f,0x36,0x8a,0x23,0x60,0xd0,0x4b,0xe2,
	0x0b,0xb5,0x90,0xc4,0xbe,0xaf,0xa1,0xd6,0xc2,0x69,0x0a,0x5b,0x74,0xae,0xa5,0xb3,
	0x12,0xaf,0x06,0x98,0xfe,0xc3,0x52,0xbb,0xf0,0xde,0x67,0xd4,0x8d,0x2a,0xf4,0x35,
	0x71,0xaf,0x5e,0x24,0xc4,0x2a,0x48,0xa6,0x42,0x32,0x10,0xb0,0x09,0x74,0x83,0x9e,
	0x3c,0x50,0x15,0x74,0xeb,0x2e,0x29,0x64,0x3e,0xe5,0x6e,0x13,0xc0,0x5b,0x9b,0x5b,
	0x1f,0x8f,0xe5,0x49,0x25,0x36,0x57,0x90,0x81,0xce,0x27,0xf4,0x8d,0x42,0x5d,0x04,
	0x2c,0x44,0x7a,0xeb,0xe0,0x10,0x4e,0xba,0x21,0xf3,0x1d,0xdf,0xb0,0xe4,0x56,0xf9,
	0x5a,0xbe,0xfe,0x1a,0x6d,0xeb,0x2d,0xe2,0x93,0x5f,0xa1,0x74,0x86,0x0c,0x64,0x68,
	0xf4,0x67,0xf3,0xe0,0xfa,0xe6,0x9d,0x6a,0xfe,0xb6,0x5f,0x58,0x2d,0xa7,0x77,0x07,
	0x58,0xc8,0x79,0x51,0xa5,0x8e,0xbd,0x4c,0x61,0x80,0x9d,0x91,0xda,0x32,0xee,0x09,
	0x02,0xca,0x14,0xf8,0xfa,0x08,0xf3,0x4a,0xf5,0x6a,0x50,0xcd,0x98,0x21,0xbd,0xb4,
	0x5e,0x4c,0x20,0x8f,0x0a,0x94,0xd0,0x6c,0x96,0xf1,0xa2,0xff,0xf6,0x1f,0x15,0xd5,
	0x1d,0x64,0x92,0x82,0xaf,0x01,0xca,0xa0,0x38,0xe9,0x80,0xea,0xe9,0xb3,0xdf,0xed,
	0xa8,0x03,0x31,0x5e,0x05,0x12,0xcd,0x29,0x33,0x59,0xf9,0xf2,0xbc,0x7f,0x05,0x86,
	0x9e,0x96,0xc4,0x52,0x2d,0x1f,0x1e,0x29,0x05,0x68,0xde,0xf1,0x3c,0x2d,0x65,0x97,
	0x7c,0xde,0x28,0x88,0xab,0xd3,0x12,0x5e,0x3d,0x15,0x45,0xc3,0x05,0x47,0x13,0x03,
	0x65,0xad,0x49,0x5f,0x8a,0x15,0xf5,0x27,0xc1,0x13,0xa5,0x16,0x85,0x13,0x11,0xf6,
	0x71,0x03,0x2c,0xaf,0xce,0xc4,0x36,0x17,0x0b,0xfd,0x4a,0x4c,0xce,0x9e,0x0d,0xcc,
	0xa5,0xa3,0x30,0xce,0x61,0x30,0x82,0x05,0x7e,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
	0x0d,0x01,0x07,0x01,0xa0,0x82,0x05,0x6f,0x04,0x82,0x05,0x6b,0x30,0x82,0x05,0x67,
	0x30,0x82,0x05,0x63,0x06,0x0b,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x0c,0x0a,0x01,
	0x02,0xa0,0x82,0x04,0xee,0x30,0x82,0x04,0xea,0x30,0x1c,0x06,0x0a,0x2a,0x86,0x48,
	0x86,0xf7,0x0d,0x01,0x0c,0x01,0x03,0x30,0x0e,0x04,0x08,0xb1,0xca,0xab,0x81,0x75,
	0x32,0xf4,0x2c,0x02,0x02,0x08,0x00,0x04,0x82,0x04,0xc8,0xc8,0xe4,0x07,0x32,0x15,
	0x32,0xb1,0xce,0xca,0xa4,0x03,0x84,0x91,0xbc,0x74,0x45,0x63,0x46,0xa8,0x20,0xcf,
	0xa2,0x2d,0x0e,0xfb,0xf7,0xfa,0x3d,0xad,0x72,0xa4,0x97,0xc9,0x14,0xb9,0x55,0x00,
	0x5e,0xb6,0x17,0xf9,0xba,0xe4,0xf4,0x4b,0x36,0x31,0xbb,0xfc,0x4a,0xb3,0xfe,0xd7,
	0xf5,0xd0,0xe8,0x63,0x43,0x6b,0x7e,0xfe,0xcc,0xa8,0x2f,0x8a,0x8a,0xf3,0xfb,0x23,
	0x0c,0xed,0x03,0x20,0x66,0xe2,0x90,0x9b,0x68,0x71,0xfb,0x44,0x68,0xe5,0x87,0x97,
	0x0a,0x97,0x63,0x53,0x3c,0x07,0x86,0x63,0xb2,0x0f,0x8e,0xe8,0xb5,0x0a,0x0c,0xe2,
	0x12,0x6d,0x33,0xa1,0xa5,0xc5,0xc4,0xab,0xf7,0x23,0x35,0x53,0x69,0xc1,0x37,0x28,
	0x86,0x42,0xa1,0x9c,0xe4,0xf5,0x2e,0x8c,0x92,0x1a,0xeb,0x67,0x10,0xcb,0x24,0xb5,
	0xd6,0x75,0x33,0x7a,0x5f,0x20,0x8f,0x1e,0x13,0x4c,0x4c,0xa1,0x53,0x87,0x8c,0xad,
	0x04,0x28,0xe0,0x21,0x65,0xf0,0x1b,0x62,0x15,0x95,0x36,0xd1,0x21,0xe1,0x50,0x0d,
	0xe4,0xed,0x07,0x8d,0x37,0xd3,0x06,0x2d,0x88,0x46,0x0f,0x54,0x16,0x19,0xac,0xc7,
	0x0b,0xcf,0x83,0xe9,0x49,0xbc,0x9e,0x7f,0x38,0xed,0xe4,0xf1,0x84,0x6a,0x0e,0xd1,
	0x92,0x39,0x61,0x36,0xa3,0x12,0xfc,0x31,0x4c,0xde,0x9d,0xcf,0xa0,0x90,0xd0,0x17,
	0x29,0x51,0x93,0x04,0xb1,0xe9,0xab,0x5e,0x5d,0x9e,0x2f,0x99,0xe9,0x53,0x95,0x27,
	0x39,0x5a,0x48,0x64,0x56,0x7b,0x97,0x9e,0x5d,0xf0,0xc9,0xd5,0x6b,0x57,0x0e,0xdc,
	0x69,0x7f,0x2d,0x6e,0xd7,0x3a,0xd8,0x31,0xcb,0x14,0xf4,0x3b,0x33,0xaf,0x62,0x95,
	0xbe,0x6b,0xe9,0xd7,0x2a,0x17,0x6c,0x9d,0x65,0x6c,0x2a,0xf5,0x38,0x39,0x95,0x8c,
	0xc6,0x97,0xc9,0xa1,0xe8,0x07,0x09,0x62,0x71,0x92,0xc2,0x4f,0xb1,0x25,0x83,0x90,
	0x44,0x54,0xcd,0x5c,0x3d,0x7b,0x0f,0xf1,0xdf,0x00,0xe2,0x4a,0x0e,0xd4,0xfe,0xa8,
	0x3e,0x81,0x4e,0x6c,0x92,0x49,0xa0,0x49,0xc4,0x3a,0x80,0x78,0x1d,0xb2,0x43,0xbd,
	0x21,0x5a,0xe0,0xbd,0x99,0xe0,0x77,0xd1,0xe6,0x2d,0x73,0xd4,0x4b,0xa9,0x07,0xcc,
	0xbd,0x12,0xa2,0x06,0x08,0x60,0xbd,0x99,0xfd,0x9f,0xcc,0x23,0x6f,0xd2,0xd0,0xdf,
	0xbe,0x63,0xef,0xe9,0x15,0x24,0x54,0x55,0x73,0x85,0x9e,0x26,0x62,0xd8,0xc1,0x14,
	0xce,0xcc,0x3b,0xf6,0x87,0x68,0xfa,0x3d,0x6e,0xb1,0x1c,0x5e,0x4e,0x05,0xe4,0xbc,
	0x95,0x1b,0xb4,0xd5,0xa1,0xfb,0xe2,0x25,0x48,0xe9,0x63,0x36,0xdf,0x33,0x8e,0xed,
	0x1d,0xdf,0x63,0x1a,0xfd,0xb6,0xc9,0x09,0x3a,0xc2,0x9f,0x1d,0xd4,0x45,0x00,0x2a,
	0x86,0x09,0x9c,0x30,0x4e,0xc0,0x81,0x9c,0x30,0x14,0x6b,0x4c,0x52,0xfd,0xca,0x36,
	0xef,0x99,0x2e,0xd1,0x86,0xc0,0xdf,0x9d,0x6a,0xb5,0xfa,0xa3,0x12,0xe0,0x5f,0x73,
	0xb4,0xfd,0xd7,0x59,0x23,0x6d,0xa8,0x77,0x8f,0x65,0x4a,0x65,0x46,0x5e,0x56,0xe0,
	0x23,0xbb,0xc5,0x38,0xff,0xf0,0x4a,0x2e,0xab,0x20,0x75,0x02,0xc5,0x85,0x7e,0x6b,
	0x3f,0xa4,0x00,0xf5,0x39,0x88,0xd1,0x9c,0xc9,0xe9,0x77,0xeb,0x8d,0xce,0x2e,0x74,
	0x5c,0xb9,0x6c,0xb0,0x6d,0x9e,0x5f,0x7b,0x93,0x7b,0x22,0x0e,0xb3,0x55,0x65,0xca,
	0x64,0xec,0xc0,0xa5,0xff,0x19,0x0a,0x2d,0x1c,0xc9,0xd3,0xe3,0xb6,0x18,0xe3,0x8c,
	0x83,0xd8,0x43,0x01,0xf8,0x6e,0x64,0x07,0xb9,0xac,0x20,0x29,0xeb,0x36,0xf5,0x04,
	0xd8,0x41,0xeb,0x8d,0x23,0x39,0x21,0x83,0xb6,0x82,0xbd,0x18,0xac,0xc6,0xb7,0x5b,
	0xf7,0x4d,0x80,0x7a,0xf6,0xdc,0x40,0x04,0x9c,0xec,0xb2,0xea,0xd6,0xf1,0x5d,0xa4,
	0x62,0x43,0x05,0x0b,0xba,0x29,0x36,0xeb,0xbd,0x23,0xb6,0x02,0xf6,0x62,0x4e,0xf3,
	0xff,0xee,0x3d,0x92,0xbe,0x65,0xc0,0x4a,0xb1,0x60,0x60,0x46,0x23,0x85,0x67,0x71,
	0xe4,0x25,0x6b,0x58,0xdc,0x91,0x4c,0x05,0x54,0xfa,0x4b,0xa5,0x60,0x82,0x3e,0xa2,
	0x4f,0x3e,0xc7,0xe5,0xf0,0x2b,0xa6,0x9d,0x55,0xdc,0x98,0x46,0xd7,0xec,0x3e,0x47,
	0x5b,0x4c,0x02,0x46,0x9c,0x2d,0x25,0x6d,0x55,0x25,0xfc,0x67,0xc2,0xe9,0xbf,0xa1,
	0xb0,0x5b,0x97,0xf8,0x4f,0xae,0xdf,0xab,0x50,0xa0,0x0b,0x5b,0xc8,0x78,0xcc,0xcd,
	0x50,0x55,0xc6,0x46,0x21,0x01,0x7e,0xac,0x38,0xe2,0x10,0x34,0x0b,0x22,0x64,0xa7,
	0xa5,0xe4,0x7f,0x60,0x51,0x75,0xdf,0x32,0x87,0xd4,0xa6,0x06,0x4f,0x8c,0x60,0x15,
	0xd0,0x1f,0xc1,0xbb,0xa4,0xca,0x4a,0xac,0x80,0xf1,0x7f,0x3a,0xfc,0x4a,0xe7,0x4e,
	0xb8,0xc2,0xdb,0x84,0xd8,0x5c,0xeb,0x44,0x23,0xec,0x9e,0x92,0x72,0xb7,0x45,0x02,
	0xee,0x52,0x08,0x47,0xb6,0x09,0x5d,0xdc,0xe5,0x26,0xae,0x61,0x42,0x77,0x13,0x85,
	0xa2,0x4f,0xf0,0xb0,0x46,0x88,0x2a,0x3c,0x09,0x98,0x89,0xe3,0xf1,0x69,0x89,0x0a,
	0x76,0xd9,0x8e,0x7e,0x0c,0xd7,0xcc,0x16,0xda,0xfd,0xfb,0x96,0x2b,0xd7,0xe2,0x8d,
	0x54,0x3f,0x75,0x2f,0x66,0x6b,0x72,0x8f,0xbd,0x5c,0x3c,0x05,0xa7,0xe4,0x11,0x06,
	0xcf,0x4a,0xd6,0x32,0x95,0x42,0x71,0xc6,0x2b,0xf9,0x8b,0xe6,0xda,0x0c,0x37,0xa8,
	0xed,0x7b,0x71,0x9a,0xea,0x8e,0xa1,0xbd,0x27,0x8f,0x45,0x00,0x48,0x40,0xba,0xf4,
	0x41,0x0e,0xb6,0x98,0x88,0xed,0xc7,0x3d,0xbd,0x59,0x52,0xc4,0xeb,0xbc,0xb8,0x0b,
	0x22,0x5e,0x68,0x79,0xc9,0x71,0x3d,0xd7,0x31,0x4c,0x55,0x40,0xcd,0x1f,0x41,0x0c,
	0xd7,0xb0,0x02,0x47,0xb0,0x9f,0xfa,0xb2,0x60,0xd4,0x3c,0x64,0xe8,0xc5,0xae,0xe8,
	0x12,0xad,0x84,0xc3,0xe1,0xfd,0x1e,0x20,0x6f,0x20,0x2e,0xbe,0xa9,0xd4,0x30,0xb6,
	0x6c,0xa5,0xf0,0x03,0x75,0xae,0x1b,0xb1,0x15,0x36,0x8d,0xba,0x0f,0x1e,0xb7,0x74,
	0x8b,0xa4,0x41,0xfd,0x13,0x7a,0xa9,0x16,0x22,0x54,0xe4,0x60,0x38,0x52,0xb6,0x60,
	0x8b,0x7f,0x7a,0xb9,0x2a,0xb0,0x28,0x63,0x71,0xeb,0x29,0x52,0xab,0x66,0x70,0x66,
	0x72,0x12,0xe9,0x4d,0xf4,0x01,0xba,0x88,0xb6,0x15,0xe1,0xb9,0x67,0x10,0x0a,0x59,
	0xc8,0x12,0x1b,0x81,0x6a,0x4c,0x79,0x0f,0x94,0xd7,0xa7,0xa8,0x4c,0x25,0xf2,0xd3,
	0x4d,0x23,0x6c,0x9d,0x65,0x81,0x75,0x72,0xd9,0xca,0xa5,0x32,0xa5,0x9a,0xcc,0xef,
	0xfe,0xb2,0x30,0x2f,0x6c,0x17,0x53,0xac,0x9d,0xc6,0xd5,0x6a,0x85,0x35,0xfa,0x17,
	0xe4,0xfa,0xb8,0x93,0x18,0xc6,0x82,0x42,0xa4,0xaf,0x72,0x7d,0xd4,0xbd,0xf2,0xe3,
	0x7b,0x6e,0x56,0x2d,0x25,0xeb,0xeb,0x53,0x4e,0x34,0xaa,0x86,0x5d,0xcb,0xe1,0xd6,
	0x22,0x4d,0x74,0xee,0x37,0xbd,0x8d,0x43,0xf8,0x3b,0xdb,0xf6,0x9a,0xef,0xe9,0x7f,
	0x3d,0x7f,0x74,0xe6,0x25,0xbb,0xf9,0x4a,0xf8,0x20,0x07,0x94,0x30,0x43,0x48,0xab,
	0x0e,0x1d,0x97,0xd6,0x01,0xa1,0x5b,0x9e,0x92,0xa2,0xeb,0xbe,0x22,0xe8,0x2f,0xb0,
	0x31,0x24,0xb4,0xb5,0x2b,0x73,0xf2,0xdd,0x29,0x5b,0xfd,0x1b,0x18,0x3e,0x3a,0xe6,
	0xa3,0x4b,0x0b,0x19,0xe3,0x4c,0x83,0x8b,0xe3,0x5f,0x94,0xd7,0x5a,0x33,0xb3,0x3d,
	0x3c,0x3f,0xf2,0x16,0x39,0x84,0x48,0x6b,0xc4,0x21,0x87,0x68,0xa7,0xe7,0x94,0xb4,
	0x4f,0x36,0x97,0x28,0x9a,0xbd,0xd4,0x5c,0xf5,0x89,0x5a,0x46,0xf4,0x4b,0x1f,0xe9,
	0x5c,0x48,0xae,0x51,0xe5,0x6f,0xb3,0xea,0xe2,0x6e,0x4e,0x72,0x2d,0x87,0x8c,0x5d,
	0x07,0x3e,0xfb,0x1c,0x95,0x88,0x9e,0xde,0xec,0xc2,0xd1,0x7c,0xef,0x6d,0x4e,0x19,
	0x0c,0xbc,0x6f,0x9f,0xd1,0xa0,0x8e,0x71,0xc8,0x13,0xe6,0xc9,0x21,0xcb,0x31,0x77,
	0x13,0x38,0x14,0xe9,0x25,0xea,0x5c,0x35,0x48,0x06,0x2c,0x4d,0xbe,0x53,0x76,0x51,
	0x1d,0x7a,0x88,0x31,0x62,0x30,0x3b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
	0x09,0x14,0x31,0x2e,0x1e,0x2c,0x00,0x54,0x00,0x65,0x00,0x73,0x00,0x74,0x00,0x2d,
	0x00,0x53,0x00,0x69,0x00,0x67,0x00,0x6e,0x00,0x4f,0x00,0x6e,0x00,0x6c,0x00,0x79,
	0x00,0x20,0x00,0x28,0x00,0x53,0x00,0x2f,0x00,0x4d,0x00,0x49,0x00,0x4d,0x00,0x45,
	0x00,0x29,0x30,0x23,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x09,0x15,0x31,
	0x16,0x04,0x14,0x6f,0x7c,0x20,0x36,0xbe,0x29,0x2b,0xca,0x1a,0xbf,0x51,0xb7,0x15,
	0x8a,0xf9,0x7c,0x2b,0x4e,0x04,0xe8,0x30,0x30,0x30,0x21,0x30,0x09,0x06,0x05,0x2b,
	0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14,0x0e,0xb5,0xcf,0xf5,0x4e,0x2b,0x2c,0x5d,
	0x2e,0x43,0xc9,0x60,0xf2,0x16,0x0f,0xd2,0xe6,0x50,0x93,0x0b,0x04,0x08,0xf0,0x18,
	0xb1,0xdb,0x61,0x97,0x53,0xcb,0x02,0x01,0x01
};  
 
/* Test identity (PKCS12 data)
 */
unsigned char Test_p12[2721] = {
	0x30,0x82,0x0a,0x9d,0x02,0x01,0x03,0x30,0x82,0x0a,0x64,0x06,0x09,0x2a,0x86,0x48,
	0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x82,0x0a,0x55,0x04,0x82,0x0a,0x51,0x30,0x82,
	0x0a,0x4d,0x30,0x82,0x04,0xd7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
	0x06,0xa0,0x82,0x04,0xc8,0x30,0x82,0x04,0xc4,0x02,0x01,0x00,0x30,0x82,0x04,0xbd,
	0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x1c,0x06,0x0a,0x2a,
	0x86,0x48,0x86,0xf7,0x0d,0x01,0x0c,0x01,0x06,0x30,0x0e,0x04,0x08,0xba,0x25,0x0b,
	0x36,0xab,0xc2,0xe7,0x34,0x02,0x02,0x08,0x00,0x80,0x82,0x04,0x90,0xe2,0x74,0x80,
	0xf1,0xf9,0xff,0xb5,0x9a,0xa4,0xe2,0x43,0x70,0x41,0xa1,0x90,0x19,0xb2,0xd5,0x8e,
	0x00,0x4b,0xfc,0x07,0xd6,0x72,0x99,0x9c,0x89,0xa8,0x0c,0x97,0x4a,0x9c,0x10,0x30,
	0x11,0x80,0xc1,0x42,0xda,0x56,0xdd,0x1b,0xfa,0x9e,0x5f,0x85,0x72,0x1d,0xde,0xdf,
	0x78,0x8f,0xd4,0x69,0xf0,0x39,0xfb,0xf1,0xf4,0x96,0xc1,0x2d,0x97,0x20,0x98,0xe2,
	0x38,0xd0,0xe1,0xda,0x01,0x59,0x64,0x71,0xd6,0xd9,0xa2,0x46,0x38,0x87,0x54,0x4c,
	0x4d,0x3f,0x8a,0x9b,0x75,0xf4,0x98,0xec,0xf1,0xe4,0x01,0x60,0x8d,0x04,0x54,0x28,
	0x4c,0xbb,0x90,0x08,0x98,0xb1,0x6b,0x61,0xe3,0x03,0xcd,0x00,0x19,0x87,0xa2,0xc2,
	0xb5,0x7b,0x57,0xd4,0x22,0x77,0xd1,0x68,0x9a,0xfe,0xe3,0x43,0xef,0x2b,0xb6,0x11,
	0x7c,0x63,0x9c,0x28,0xab,0x86,0xdf,0x1b,0x95,0x58,0x54,0xa5,0x3d,0x18,0xb0,0xad,
	0x20,0x76,0x92,0xf5,0xef,0x20,0x8a,0x0c,0x21,0xdb,0x83,0x15,0x1e,0xa5,0x6f,0xeb,
	0xd3,0xc8,0x40,0x14,0x7f,0x69,0x46,0x73,0x20,0x60,0x2b,0x3e,0x27,0xd7,0xb9,0x33,
	0x8c,0xe6,0x43,0xc8,0xf6,0xa5,0x53,0xa7,0x36,0x03,0x3d,0xa9,0xdd,0x85,0x59,0xde,
	0x70,0xc2,0x65,0x38,0x06,0x04,0x00,0x01,0xcc,0xed,0xdf,0x1f,0xab,0x83,0xed,0xeb,
	0xc0,0x3d,0x33,0x4e,0x99,0x22,0xcc,0x63,0xc7,0x14,0x9c,0x50,0x60,0x38,0xc3,0xa5,
	0xe2,0xfe,0x78,0x04,0x01,0x0f,0x1d,0xde,0xe0,0x3e,0x86,0x05,0x02,0xfc,0x3c,0x7f,
	0x38,0xf7,0xb0,0xd0,0xbb,0x0c,0xe1,0x1b,0xdc,0x6e,0xb0,0x12,0x7a,0xae,0x13,0x5d,
	0x80,0xd7,0x0e,0xb2,0xe8,0x5d,0x2a,0xbf,0x2e,0x67,0xc3,0xd8,0x8d,0xa1,0x9f,0x2c,
	0xbb,0xc4,0x33,0xca,0xf4,0x43,0x89,0xbd,0x4e,0x19,0xa5,0x71,0x1c,0x5f,0x6b,0x4d,
	0xd4,0xf7,0xdd,0xd3,0xfd,0x13,0xdc,0xde,0x76,0x2c,0x38,0x8e,0xef,0xb2,0x00,0x9c,
	0xfd,0xa5,0x52,0xa0,0xec,0xa3,0xfe,0xcc,0x80,0xee,0x8d,0xed,0x25,0xf9,0xa8,0x30,
	0x99,0x04,0x6f,0x61,0x4e,0x2f,0x08,0x6c,0xa5,0xe2,0x5b,0x15,0xae,0x58,0xbd,0xbd,
	0xa1,0x36,0xa9,0xa1,0xb5,0xed,0x1e,0x95,0xf5,0x90,0x35,0xa2,0x5c,0xc3,0x9b,0x1f,
	0x98,0x5d,0xdd,0xcf,0xd4,0x08,0xd4,0xb7,0x90,0x58,0xb8,0xc7,0x9d,0x60,0x25,0x57,
	0xa1,0x39,0xc3,0x2c,0x75,0x07,0xd9,0x4c,0xdd,0x2f,0xc8,0xf5,0x7a,0xee,0x06,0xcf,
	0xdc,0xc3,0x22,0x89,0x37,0xa0,0x9f,0x9f,0x45,0x46,0x2d,0x98,0xac,0xdb,0x33,0x80,
	0xb3,0x29,0x76,0x6f,0x1b,0x9e,0x71,0xc7,0x41,0x9f,0x12,0x00,0x4e,0x09,0x0c,0xab,
	0xc7,0xda,0x58,0x60,0x6c,0x0a,0x6e,0x09,0xbe,0x2e,0x2f,0x4f,0x0a,0x63,0x38,0x60,
	0xca,0xc9,0xe9,0x67,0x70,0xcb,0x4e,0xed,0xa9,0xd3,0xd4,0xbc,0xa2,0x69,0x32,0xcb,
	0x62,0x69,0xa0,0x32,0x36,0x09,0x96,0x1f,0xdc,0xea,0x73,0xe6,0x84,0x3d,0x84,0xbf,
	0x62,0x82,0x4d,0x23,0xb1,0xc5,0x64,0xa8,0x57,0x07,0x37,0x3c,0x54,0x63,0x61,0xe1,
	0x24,0xeb,0xd9,0xdd,0x2e,0xb8,0x8f,0xbd,0xa9,0x3e,0x55,0xd7,0xea,0xfb,0x5a,0xc9,
	0x68,0xd9,0x9d,0x0e,0x75,0xb1,0x86,0xf0,0xa4,0xb2,0x3f,0xd7,0x77,0x7d,0x5f,0x5f,
	0x87,0x00,0x07,0x24,0x16,0x20,0x0a,0x5b,0x4b,0x52,0xb6,0x1a,0x39,0xd6,0x32,0x43,
	0x7a,0xb4,0xf8,0x81,0x59,0xec,0xbd,0x97,0xb6,0xe7,0x41,0x2b,0x68,0x19,0xb4,0x06,
	0xec,0xbf,0x34,0x36,0xa2,0x9a,0x7f,0xa0,0xa9,0x16,0x9e,0x98,0x40,0x37,0x22,0x21,
	0x3e,0x43,0xe3,0xaf,0x30,0x6e,0x50,0xf5,0xba,0xe4,0x00,0x14,0x25,0x08,0xbf,0xa8,
	0xdf,0x71,0x4b,0x3d,0x27,0x8b,0x44,0xbb,0xed,0x2c,0xcb,0x75,0x6a,0x1d,0xb8,0x8b,
	0xe9,0xe2,0x99,0x0b,0xe5,0xcd,0x0e,0x24,0xa8,0x68,0x91,0xca,0xc9,0x48,0x5c,0xdb,
	0x60,0xa0,0x43,0x52,0x82,0x74,0x17,0xd7,0x47,0x91,0xd7,0x92,0x04,0xba,0x3f,0xe4,
	0x54,0xc9,0x41,0xb9,0xa4,0xcf,0x2f,0x0f,0x7e,0xce,0xa2,0x82,0xe7,0xed,0x3a,0x48,
	0x83,0xdb,0xdb,0x9f,0x1d,0xa2,0x44,0x56,0xf0,0x76,0x7a,0x20,0x6b,0xd7,0x8e,0xc1,
	0x34,0x67,0x28,0xc3,0x1e,0x8d,0x03,0xf0,0x91,0x87,0x83,0xeb,0x26,0xa3,0x38,0xe0,
	0xc6,0xd9,0x1d,0x3a,0xa6,0xe4,0xf0,0x31,0xe9,0x23,0xce,0x6c,0x0a,0xe4,0xab,0x3c,
	0x3c,0xf2,0x68,0x8a,0x41,0xda,0x19,0x5b,0x40,0x9c,0xde,0xc7,0x84,0x0b,0x2b,0xa7,
	0xfd,0x95,0x37,0xf7,0x42,0x17,0xac,0x90,0x6e,0x11,0x53,0xfb,0x75,0x4b,0x37,0x88,
	0xd2,0x1f,0xaa,0x73,0x98,0x0d,0x74,0xb3,0x69,0x54,0x2b,0x9e,0x5f,0xaf,0x93,0x21,
	0x07,0x05,0x60,0xc6,0x61,0x4e,0x5d,0xaf,0x36,0x79,0xca,0x85,0x4a,0x6c,0x58,0xeb,
	0xcf,0xaf,0x99,0xd9,0xb5,0x82,0x46,0xb4,0x73,0x95,0x1a,0xbc,0x78,0xdd,0xb7,0x47,
	0x10,0xeb,0x03,0x50,0x63,0x06,0x73,0xdc,0xc4,0xa1,0xa8,0xa3,0x44,0xc1,0x4d,0xc9,
	0x2c,0x73,0x75,0x0f,0xb0,0xe0,0xa5,0x43,0xd1,0x8a,0x29,0xa9,0x60,0x71,0x4d,0x82,
	0xae,0x5c,0xa5,0x87,0x93,0x4c,0xa2,0xfd,0xb5,0xb3,0xda,0xf4,0x90,0x61,0x87,0x6e,
	0xe8,0x8d,0xfc,0x52,0x17,0x06,0x87,0x32,0x37,0x6a,0xff,0xe7,0x58,0xa2,0x46,0x25,
	0xd0,0x3a,0xd8,0xf7,0xc4,0x1b,0xda,0x58,0x5d,0xb8,0xa2,0x5d,0x4d,0x8b,0x1a,0x90,
	0x20,0x12,0x00,0xf3,0x7f,0xb0,0x53,0x97,0x6d,0xfb,0xa0,0x5c,0x4a,0x6c,0xb5,0xb5,
	0xc3,0xb0,0x3a,0x32,0x71,0xbc,0x61,0xe5,0x37,0x60,0xea,0x4a,0xf5,0xd8,0x05,0xc2,
	0xd4,0x62,0xb2,0x94,0xb0,0x73,0xd6,0x82,0x08,0x60,0x71,0xee,0x7e,0xd5,0xf7,0x30,
	0x89,0xe8,0xb5,0x1a,0x08,0xb8,0xea,0x11,0x57,0x9d,0x99,0x2d,0xef,0xd0,0x5a,0xb7,
	0x24,0xc8,0x1d,0x87,0x81,0x70,0xbb,0xb9,0x88,0xed,0x04,0x32,0xab,0x55,0x7e,0xea,
	0x1a,0x77,0x80,0x7a,0x88,0x08,0xc7,0xa1,0x53,0x05,0xb1,0x85,0x43,0x5a,0x11,0x4f,
	0x2a,0x7e,0xda,0xfe,0x83,0x12,0x47,0xc4,0xd7,0x6b,0xfb,0x8a,0x0c,0x90,0x77,0x84,
	0xc0,0xb3,0xa6,0x60,0x96,0xd3,0x2f,0x5f,0x3f,0x62,0xe4,0xda,0x13,0xf4,0x35,0x50,
	0x20,0x5b,0x1a,0xd0,0xc7,0x39,0x06,0x08,0x6a,0x0d,0x5e,0xb7,0x8b,0x37,0x56,0x1c,
	0x52,0x7c,0x9b,0x6a,0xd6,0x7e,0x8e,0xb0,0x36,0xb7,0x44,0x36,0x30,0xb9,0x0f,0x39,
	0x51,0x48,0xc3,0xa3,0xa1,0x98,0x57,0x6b,0xba,0xf6,0x62,0xaf,0xf4,0x2b,0x6c,0x50,
	0xa1,0x55,0xf4,0x58,0x37,0xc4,0x4a,0xd2,0xcb,0xb6,0x59,0x19,0x82,0x3d,0x5e,0x3d,
	0x38,0xc3,0x74,0xab,0x0c,0xd0,0xb2,0xc5,0xb0,0x87,0x30,0xa2,0xef,0x0a,0x85,0xb0,
	0xe5,0x6c,0x39,0x13,0x8f,0x54,0xfe,0xf4,0x3c,0x16,0x4b,0xfd,0xfa,0x2a,0xef,0x66,
	0xa8,0x2a,0x8d,0xc0,0x7b,0x53,0x55,0x4b,0xba,0x19,0xa3,0xa3,0x5f,0x16,0xb4,0x06,
	0xb2,0x56,0xa7,0xca,0xfa,0x6a,0x1f,0xf2,0x0f,0xe5,0x58,0x8a,0x6d,0x45,0x43,0xb3,
	0xd5,0xd2,0x35,0x4f,0x52,0x75,0x47,0x74,0x6f,0x7c,0x25,0x98,0xb2,0xa9,0xef,0x37,
	0x8e,0xa9,0x89,0xff,0x18,0xb6,0x56,0x75,0x32,0x8e,0x98,0xed,0x35,0x8b,0xca,0xad,
	0x91,0xaf,0xdd,0xd4,0xdf,0xff,0x23,0x99,0x45,0x30,0xad,0x9d,0xec,0xce,0x94,0x4a,
	0x6d,0xaa,0xd7,0x6b,0x73,0xa3,0x33,0x0d,0x8b,0x1d,0xd0,0xde,0xc6,0x30,0x82,0x05,
	0x6e,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x82,0x05,0x5f,
	0x04,0x82,0x05,0x5b,0x30,0x82,0x05,0x57,0x30,0x82,0x05,0x53,0x06,0x0b,0x2a,0x86,
	0x48,0x86,0xf7,0x0d,0x01,0x0c,0x0a,0x01,0x02,0xa0,0x82,0x04,0xee,0x30,0x82,0x04,
	0xea,0x30,0x1c,0x06,0x0a,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x0c,0x01,0x03,0x30,
	0x0e,0x04,0x08,0xe9,0x3c,0x06,0x49,0x97,0xcf,0x08,0xfe,0x02,0x02,0x08,0x00,0x04,
	0x82,0x04,0xc8,0x95,0xff,0x56,0xf1,0x44,0xdd,0xe9,0x3d,0x50,0x22,0xbd,0xda,0x8c,
	0x1d,0x0f,0x6f,0xde,0x2d,0x96,0x46,0x21,0x32,0xc9,0xde,0x6d,0x96,0x45,0xfd,0x05,
	0x67,0xde,0x46,0x22,0x87,0xc3,0xbe,0xb9,0xb1,0x30,0x9d,0x8b,0xb0,0x6b,0x35,0xd9,
	0xa0,0x09,0x49,0x43,0x77,0x93,0x3b,0x6f,0xdd,0xc9,0xba,0xdd,0xa4,0xf9,0x81,0xb0,
	0xc8,0x61,0x2e,0xd8,0xe9,0xd0,0xb4,0xa4,0xe8,0x49,0x5a,0x48,0xe7,0x88,0x21,0xdc,
	0x1d,0x84,0x12,0x08,0x08,0x74,0x52,0x36,0x4a,0x30,0x6b,0xb0,0x57,0x91,0x71,0x0c,
	0x56,0x64,0xc8,0x6d,0x4e,0xfa,0xc6,0xdf,0xec,0xc6,0xc6,0x97,0x76,0xe0,0x5d,0x14,
	0xb7,0x67,0xdc,0xec,0xc9,0x83,0xec,0x8e,0xae,0x3d,0x3d,0x85,0xd2,0x26,0xc9,0x8c,
	0x2a,0xb1,0xf1,0xd7,0xc6,0xe3,0x64,0xf8,0x31,0x59,0xf5,0x6d,0x29,0xd3,0xce,0x29,
	0x8c,0xaa,0x0e,0x3d,0x5d,0x8f,0x9e,0x00,0xb6,0xfd,0xfb,0x7a,0x3a,0x2f,0xaa,0x1e,
	0x01,0x0a,0xd6,0xb5,0xdf,0x34,0x60,0x60,0xe0,0x5a,0x94,0x68,0x6d,0x87,0x26,0x3e,
	0x85,0x83,0x1a,0xb9,0x82,0x71,0xc5,0xb1,0x28,0x67,0x9e,0x2c,0xbe,0x07,0x4a,0x8b,
	0xd2,0xa1,0x2e,0x5c,0xb1,0xff,0x26,0xae,0x2e,0xc9,0xc2,0x3a,0x78,0x12,0x50,0x0b,
	0xbd,0x01,0x48,0x41,0x89,0x1f,0xa1,0x74,0xe8,0xe0,0xc7,0x70,0x88,0xac,0xa2,0x04,
	0x21,0x82,0x4b,0x8f,0x2a,0x81,0x13,0x4a,0xbb,0x80,0x59,0x7c,0xef,0xc4,0x26,0xb8,
	0x9d,0x43,0x76,0xef,0x2e,0x53,0xc3,0x10,0xd8,0xd8,0x76,0x2b,0xf0,0x00,0xca,0xf3,
	0xf7,0xa5,0xff,0x2a,0x7d,0x2b,0x9e,0xec,0x2d,0xf4,0x0c,0x1c,0x0e,0xa5,0xef,0x92,
	0xd5,0x26,0x2d,0x22,0xf8,0x67,0xcf,0x9d,0xc3,0x06,0xd7,0xdf,0x9a,0x91,0x94,0xaa,
	0x73,0x70,0x6b,0xf9,0xa6,0x32,0x21,0xb2,0x8a,0x2a,0xe2,0x6c,0x9b,0x6e,0x8d,0xc7,
	0xa5,0x18,0xa3,0xf4,0x8f,0xaf,0x6e,0xe3,0x4c,0x76,0xe9,0xe6,0x81,0x7f,0xa1,0x3b,
	0x53,0x3f,0xb1,0x0f,0x94,0x5b,0x57,0x23,0xfe,0x19,0x51,0xf8,0xc5,0xd6,0x6d,0xa9,
	0x55,0x53,0xb6,0xf8,0x93,0x29,0xe8,0x4b,0xca,0x1f,0x9c,0xe5,0xdb,0x30,0xa2,0x13,
	0x26,0xed,0x90,0xea,0x5e,0xa5,0xc8,0xf6,0x04,0xf3,0xc0,0xd0,0x0d,0x7c,0x33,0x66,
	0x8d,0xfd,0x69,0x70,0x91,0x96,0xe4,0x9f,0x70,0xfa,0x4b,0xbc,0x07,0xbf,0xf7,0x0e,
	0x9f,0xcc,0x3a,0xef,0x5a,0xc8,0x5f,0xd7,0x17,0x5a,0xaa,0x35,0x68,0x09,0xb7,0x5a,
	0xc9,0xab,0x33,0x40,0x17,0xb7,0xd2,0x66,0xe6,0xea,0x74,0xca,0xd5,0x71,0x89,0x8b,
	0x95,0x07,0x2c,0xbd,0x43,0xc9,0x7a,0xa3,0xb5,0x8b,0x11,0x61,0x95,0x4e,0x39,0xeb,
	0x66,0xfb,0x06,0xfb,0xf2,0xd4,0x56,0xb5,0x2b,0xca,0x93,0xde,0x22,0xbe,0xc2,0x62,
	0xbd,0xbc,0x58,0x0d,0x49,0x4d,0x08,0x82,0x8a,0x63,0x74,0x7c,0x64,0x0d,0xf5,0x36,
	0x82,0xc2,0x14,0x6a,0xa1,0x34,0x34,0x94,0x55,0x74,0xc6,0x69,0xe6,0xd4,0x3c,0x6c,
	0x03,0x0f,0xa5,0xa5,0x23,0x58,0xbb,0x97,0x75,0x97,0x70,0x4e,0x6a,0x94,0x57,0xba,
	0x5a,0xbb,0xab,0x3f,0xfe,0x8f,0x1d,0x5a,0x1f,0x7a,0x6d,0x79,0xaa,0x67,0xd8,0xdc,
	0x03,0x88,0x2f,0x2c,0xa7,0x79,0xc0,0xd7,0x85,0x42,0xf9,0xc3,0x23,0x67,0x09,0x22,
	0x3a,0xb8,0x04,0x5c,0xa9,0x75,0x18,0x35,0x16,0x39,0x7a,0xf2,0x01,0xb7,0x5e,0xe6,
	0xa1,0xc8,0x2b,0x29,0x9c,0x38,0xb1,0x8b,0x50,0xd8,0xe9,0x8b,0x6a,0x38,0x5b,0xe0,
	0xfe,0x88,0x21,0xb6,0xc9,0xf6,0x6a,0x66,0x17,0xe7,0x37,0x42,0xe9,0x62,0x63,0x41,
	0xca,0xa1,0xc7,0x0c,0x5c,0xf6,0xdc,0xf5,0xf4,0x5f,0xc1,0x84,0xc5,0x8f,0xe8,0x87,
	0x5e,0xb2,0xf5,0x0a,0x9f,0x8f,0x8d,0x71,0x25,0x3b,0x54,0xb8,0xd2,0x15,0x3f,0x69,
	0x27,0x9b,0xea,0xf7,0x83,0xf5,0xf2,0x24,0xd9,0xd8,0xd6,0x62,0x13,0x43,0xe5,0x64,
	0xb3,0xf2,0x49,0x70,0x02,0xf4,0x76,0x42,0xae,0xed,0x00,0xbf,0x18,0x5b,0xe0,0x1c,
	0x41,0x37,0x0e,0xbd,0x13,0x2d,0xa1,0x31,0x0c,0x8c,0xd6,0xc4,0x27,0xe4,0x2a,0x74,
	0xa3,0x90,0x63,0x56,0x05,0x59,0x6a,0xdc,0x45,0x9e,0x04,0x14,0xd3,0x32,0x77,0xff,
	0xb2,0x50,0x73,0xba,0x2a,0xd3,0x70,0x69,0xbe,0xec,0xf6,0xee,0xed,0xf9,0x88,0x65,
	0x4e,0x61,0x32,0x09,0x73,0xdc,0x16,0x16,0x8a,0xec,0x09,0x44,0xcb,0x2c,0x03,0x44,
	0xaf,0xd7,0xcd,0x0d,0x91,0x52,0xf1,0xba,0xed,0x64,0x7b,0xd9,0xa1,0x1a,0x40,0xdb,
	0xf8,0x46,0x86,0x74,0x30,0x2d,0x72,0x62,0x2a,0x8c,0xd0,0xa2,0x6f,0xcd,0x21,0x02,
	0xc9,0xc4,0xd0,0x81,0x23,0x1c,0x81,0xd9,0x71,0xc1,0xee,0x70,0x37,0x8e,0x23,0x9d,
	0x2c,0xd6,0x4b,0x2b,0x08,0x92,0x95,0xbb,0xf4,0xae,0x78,0x14,0xa6,0x16,0xdc,0xf7,
	0xba,0xc1,0x18,0x96,0x13,0x5a,0xa4,0x12,0xcd,0x96,0x2b,0xb3,0x21,0x0a,0xd6,0x7e,
	0x25,0xd8,0xe9,0x59,0xd5,0x18,0x91,0x85,0xc1,0xe3,0xee,0xf8,0x9b,0x4f,0x42,0x04,
	0x03,0x7d,0xe8,0xcc,0x2a,0xa3,0x8e,0x95,0x9b,0x47,0xb0,0x89,0x7f,0xd5,0x53,0xbd,
	0x54,0x7b,0x73,0xa2,0x0a,0x62,0x51,0x34,0x3b,0xc5,0x41,0x5d,0xa5,0x5c,0x94,0x69,
	0xd5,0xfd,0x5e,0x71,0xc1,0x6e,0x18,0x80,0x1f,0xab,0x94,0xcd,0x0d,0x44,0x47,0xd4,
	0xa9,0xf3,0x3a,0xfd,0xf8,0x47,0xe4,0x9c,0xd7,0x5d,0x54,0x6f,0x4b,0xea,0xf1,0x8f,
	0x9f,0xca,0x3c,0x24,0xe6,0x8b,0xa5,0x29,0x5b,0x07,0x05,0x60,0x41,0xce,0x77,0x2b,
	0xfe,0xe0,0x4e,0x47,0x92,0x2d,0xca,0x5b,0x6e,0x08,0xcc,0x25,0x8e,0xc8,0x93,0x96,
	0x49,0x6d,0x3f,0x25,0xbf,0x8e,0x37,0xe3,0xdf,0xb9,0xea,0xf0,0x2b,0x56,0xc8,0x30,
	0x7d,0xff,0x32,0xfa,0x9c,0xf1,0x35,0x6b,0x68,0xf2,0xfd,0x1e,0x23,0xf2,0x95,0x81,
	0x68,0xd8,0xec,0x95,0x5b,0x85,0xa8,0x42,0xa6,0xcc,0xf5,0x03,0x95,0xf1,0x3f,0xd2,
	0x86,0x3a,0x1f,0x11,0xd2,0xcf,0x4b,0x32,0xf2,0xb9,0x46,0x3e,0xf5,0xbb,0x0d,0xa0,
	0x5b,0x85,0xea,0xe0,0xbd,0x7c,0x3b,0x75,0x80,0x1c,0x8a,0x6d,0x92,0x39,0x27,0xbf,
	0xc5,0x8e,0xb4,0x5a,0xaf,0xd5,0x8b,0x34,0x53,0x85,0x76,0x60,0xe6,0xd4,0xb8,0xe2,
	0x2f,0x9e,0x66,0x24,0x28,0x66,0x06,0x25,0x62,0x77,0x35,0xce,0x36,0x68,0x2a,0xdc,
	0x82,0x94,0xd8,0x21,0x96,0x7b,0x05,0x10,0x3b,0xcc,0xfb,0x43,0x11,0xd0,0x25,0xfc,
	0x1c,0x5a,0x1c,0xee,0x3d,0x1c,0x75,0xf8,0x41,0xa7,0x10,0x48,0xd7,0xee,0x9e,0xa4,
	0x62,0xb0,0x64,0xaa,0x55,0xd9,0xd7,0xb6,0x4b,0xe9,0x84,0xa8,0x64,0xcc,0xb3,0x3a,
	0xe7,0x83,0xf0,0x8a,0xd3,0xe3,0x86,0xda,0xb5,0xc7,0x8e,0x9c,0x84,0xde,0x06,0x5d,
	0x8f,0x4d,0x68,0x35,0x69,0x88,0xc2,0xd1,0xea,0xab,0x1b,0xa7,0xf0,0x8e,0x05,0x3d,
	0xdb,0x8b,0x27,0x20,0xd2,0xb1,0x20,0xab,0x9a,0xda,0x4d,0x03,0xbd,0xa4,0x17,0xf6,
	0x01,0xb5,0x25,0x62,0x02,0xe5,0x17,0xdd,0x71,0x8a,0xe8,0x2b,0x01,0x56,0x35,0x31,
	0x79,0x6f,0x7f,0x98,0x3f,0x5c,0x3d,0x0d,0x11,0x43,0x44,0x31,0xe0,0x94,0xa0,0x6a,
	0xaa,0x8e,0x24,0x0d,0x8f,0xe2,0x81,0x75,0x0d,0x9f,0x54,0xf8,0x0e,0x23,0x19,0xb9,
	0xa9,0x6e,0x11,0xfc,0x08,0xb4,0x73,0x77,0xda,0x3b,0x00,0x63,0xc4,0xb8,0x79,0xb4,
	0xf9,0xb2,0x41,0x55,0xd5,0xb6,0xd3,0x91,0x4d,0x77,0xeb,0xc9,0xb9,0x42,0xba,0xef,
	0x05,0xae,0x2f,0xc3,0x1a,0x7d,0x9b,0x01,0xef,0xee,0x8f,0x0b,0x2c,0x68,0xab,0xc6,
	0x43,0xb3,0x87,0x1f,0xca,0xba,0xe7,0x30,0xe9,0x7a,0xda,0x55,0xec,0x77,0xd1,0xb6,
	0x44,0xcb,0x91,0x43,0xa9,0x2b,0xc1,0x26,0xed,0x14,0x85,0x31,0x52,0x30,0x2b,0x06,
	0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x09,0x14,0x31,0x1e,0x1e,0x1c,0x00,0x54,
	0x00,0x65,0x00,0x73,0x00,0x74,0x00,0x20,0x00,0x53,0x00,0x53,0x00,0x4c,0x00,0x20,
	0x00,0x55,0x00,0x73,0x00,0x65,0x00,0x72,0x00,0x00,0x30,0x23,0x06,0x09,0x2a,0x86,
	0x48,0x86,0xf7,0x0d,0x01,0x09,0x15,0x31,0x16,0x04,0x14,0xf1,0x1b,0x6e,0xf2,0x3a,
	0xc4,0x3a,0xe1,0xd6,0x4b,0x7d,0x31,0xf3,0x2c,0xd4,0x63,0x06,0x66,0x37,0xe0,0x30,
	0x30,0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14,
	0x85,0xed,0x34,0x3d,0xde,0xa1,0x8a,0x94,0xcd,0x12,0x95,0xf7,0x2d,0xb2,0x60,0xfd,
	0xbd,0x67,0xe9,0x2d,0x04,0x08,0x71,0xfc,0x54,0xf2,0x12,0x3c,0x22,0xf1,0x02,0x01,
	0x01
};

/* Test identity (PKCS12 data), SMIME cert, expired in 2008
 */
unsigned char TestIDSMIME2007_p12[2805] = {	
	0x30,0x82,0x0a,0xf1,0x02,0x01,0x03,0x30,0x82,0x0a,0xb8,0x06,0x09,0x2a,0x86,0x48,
	0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x82,0x0a,0xa9,0x04,0x82,0x0a,0xa5,0x30,0x82,
	0x0a,0xa1,0x30,0x82,0x05,0x17,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
	0x06,0xa0,0x82,0x05,0x08,0x30,0x82,0x05,0x04,0x02,0x01,0x00,0x30,0x82,0x04,0xfd,
	0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x1c,0x06,0x0a,0x2a,
	0x86,0x48,0x86,0xf7,0x0d,0x01,0x0c,0x01,0x06,0x30,0x0e,0x04,0x08,0x3f,0x0b,0xd9,
	0x3c,0x80,0x6d,0x5e,0x7b,0x02,0x02,0x08,0x00,0x80,0x82,0x04,0xd0,0x08,0x25,0x32,
	0xdc,0x7b,0xed,0x8a,0x29,0xf8,0x56,0x84,0x51,0x5c,0x6d,0xe6,0xe6,0x34,0xf8,0x03,
	0xb3,0x80,0xe2,0xf4,0x0e,0x3f,0x1f,0xad,0x12,0x11,0x27,0x56,0xe8,0x89,0x59,0x90,
	0x03,0xf0,0xa7,0xc2,0xde,0xd0,0x70,0xbf,0x2c,0xea,0x01,0xe7,0xbd,0xba,0xaf,0xfc,
	0x07,0x84,0x2f,0xdb,0x65,0xa0,0x7b,0x4b,0x6a,0xab,0xe4,0xbd,0xd0,0xbb,0x31,0xaf,
	0x90,0x8c,0xa8,0x71,0x10,0x23,0x96,0x67,0x44,0xdd,0x02,0x72,0xd2,0x0f,0xca,0xcb,
	0x4f,0xc2,0x14,0x04,0xfa,0xde,0x31,0xa5,0x2f,0x97,0xc0,0x2a,0xdd,0xdd,0x91,0x62,
	0xa7,0xf7,0x9b,0x43,0x57,0x7d,0x4d,0x1c,0xb1,0x92,0xba,0xae,0xa1,0x24,0x6c,0x99,
	0x81,0x49,0x56,0x46,0x8b,0xea,0x7c,0x16,0x19,0x76,0xf7,0x40,0x06,0x82,0xe2,0x5b,
	0x3f,0xd8,0x2c,0x87,0x60,0xf7,0xae,0xaa,0xa5,0xba,0x96,0xbf,0x5c,0x86,0x57,0x81,
	0x8d,0xbf,0x6c,0xe1,0xd1,0xb9,0x20,0x93,0x27,0xfc,0xe6,0x35,0x80,0xaa,0xfb,0xe6,
	0x4b,0xfd,0x4f,0xa4,0x06,0x05,0x46,0x85,0x66,0x15,0xfb,0x83,0x2b,0x42,0x26,0x98,
	0xc8,0x69,0x24,0xa1,0x71,0xb4,0x56,0x38,0x3d,0x5e,0xc2,0x13,0x34,0xab,0x2f,0xb1,
	0x33,0x6e,0xf0,0x07,0x80,0xdd,0x0e,0x6f,0x19,0x01,0xaf,0xff,0x5f,0xc3,0xea,0x24,
	0x5a,0x6d,0xad,0xb3,0x10,0xbb,0x63,0x02,0x14,0x38,0xa9,0x21,0x83,0xb9,0xc3,0x23,
	0xba,0xfc,0x56,0x76,0x4d,0x46,0x43,0xd1,0x09,0x37,0x1f,0x79,0xe5,0x70,0x93,0xb5,
	0x0f,0x21,0xe3,0xef,0x0b,0x4d,0x87,0x0c,0x68,0xf5,0x16,0xc0,0x13,0xee,0x28,0xe8,
	0x49,0xaa,0x60,0x61,0xe5,0x76,0xe6,0x8e,0xd6,0xae,0x52,0x70,0xb2,0x70,0xbf,0xeb,
	0xd2,0xd8,0xb8,0x92,0x71,0x6e,0xb8,0x59,0xdf,0xee,0xad,0xc1,0x55,0x14,0x4b,0x52,
	0x0c,0x20,0x4c,0x79,0x93,0x71,0xe6,0xc5,0xbc,0xf3,0xf3,0x14,0x13,0xd0,0xcd,0x1c,
	0x62,0x21,0xc0,0xcf,0x4e,0xf5,0xda,0x52,0xbf,0x2c,0x86,0x8f,0xb5,0x67,0xf5,0x72,
	0xbb,0xe9,0xb8,0x86,0x17,0xd9,0x35,0x49,0xae,0x0a,0x99,0x94,0xa5,0xaa,0x96,0xf4,
	0x95,0xfe,0x4a,0xe2,0x13,0x46,0xcb,0xd9,0x8b,0x48,0x50,0xff,0x34,0x88,0x12,0xe7,
	0x9b,0x00,0x8d,0x57,0x94,0x44,0xa5,0xe6,0xd1,0x7f,0x34,0xbb,0x33,0x9f,0xc3,0x12,
	0x3b,0xb2,0xba,0xb6,0xb3,0x15,0x9e,0xaf,0x90,0x5e,0x2e,0x61,0x0d,0xe6,0x02,0x25,
	0x41,0x55,0x18,0xc9,0x4a,0x5a,0x0a,0xb2,0xf5,0x99,0x8a,0x27,0xc7,0xd7,0x01,0x96,
	0x9e,0x4c,0x05,0x7f,0x54,0x90,0x08,0x92,0x9c,0xf2,0xbd,0x0d,0x7d,0x37,0x5a,0x57,
	0x1d,0x5b,0xcb,0xce,0xc1,0x58,0x5e,0x50,0x73,0x4d,0x61,0x28,0x18,0x90,0x2d,0xac,
	0x91,0x4b,0x5e,0x5f,0x57,0x29,0x58,0x65,0xba,0xa4,0x11,0x92,0xa8,0xf4,0xac,0xa8,
	0x39,0x1c,0x52,0x14,0x09,0x13,0xdd,0x4e,0xfa,0xef,0xba,0x4f,0x48,0xc3,0x46,0x4e,
	0xb9,0x8d,0xff,0x5e,0x28,0xb8,0xcc,0x99,0x7f,0x3a,0xdc,0xf4,0x90,0x5c,0x41,0x14,
	0x4b,0xbc,0x6b,0xa3,0x01,0x78,0x87,0xc1,0x86,0xd7,0xad,0x98,0xa0,0xc6,0x82,0x35,
	0x76,0x41,0x6f,0xf1,0xee,0x54,0xbd,0xef,0xef,0xfc,0x2b,0x88,0x56,0x61,0xb1,0x93,
	0xa0,0xe5,0x8e,0x1e,0xb4,0xb1,0x39,0xb3,0xd3,0x85,0xe0,0xa2,0x61,0x4b,0xe8,0x24,
	0xc3,0xdd,0x48,0x2a,0xfd,0x5a,0x98,0x7a,0x98,0x2a,0xc7,0x81,0x4c,0x3d,0x3b,0x0c,
	0x42,0x69,0x42,0x87,0xf1,0x5f,0x13,0x47,0xf6,0x89,0xc5,0x5e,0x47,0x84,0x59,0x81,
	0x97,0xef,0x22,0x79,0x16,0x37,0xdc,0x74,0x66,0x30,0x81,0xbc,0x45,0x21,0xe4,0x75,
	0x69,0xe4,0x64,0x2b,0x98,0x97,0x61,0xe1,0x34,0xdf,0x4a,0x37,0x65,0x74,0xdc,0xe1,
	0x71,0x37,0xd6,0x2c,0x54,0x83,0x7a,0x91,0xc4,0xa6,0xfe,0x09,0x12,0xf3,0xf5,0x2b,
	0xec,0xe9,0x63,0xa3,0x25,0x0f,0x6f,0xd1,0xb0,0x95,0x3f,0x7f,0xab,0xa7,0x25,0x9b,
	0x85,0xdb,0xcf,0x6e,0x0e,0xc0,0x8d,0xd3,0xca,0x0e,0xd2,0x98,0xeb,0x77,0x39,0xf4,
	0x1a,0x30,0xe6,0x76,0x6d,0xba,0xc0,0x61,0x55,0x4e,0xbe,0x88,0x32,0xb2,0xae,0x16,
	0x27,0xbd,0x61,0xc5,0x48,0x26,0x0f,0x05,0x1a,0x42,0xa6,0xd9,0x29,0xf8,0x58,0x96,
	0x16,0x1d,0xad,0xf4,0x58,0xc6,0x79,0x46,0xdf,0x1f,0x25,0x43,0xaa,0xf5,0xc3,0x1f,
	0x75,0x36,0x1c,0x17,0xd2,0x4d,0x88,0xf6,0x37,0x35,0x21,0x1f,0x0f,0x45,0x85,0x13,
	0x50,0x85,0x0a,0xa2,0xb4,0x96,0x7a,0xe4,0x0a,0x27,0x74,0x87,0x1b,0x11,0xaa,0x7c,
	0x35,0xf6,0xb6,0x49,0x8d,0x58,0x30,0x16,0xb7,0x36,0xd6,0xd8,0x82,0xe6,0x3d,0xa4,
	0xdf,0xa7,0xc4,0xc7,0xfe,0x81,0x01,0xa6,0xda,0x63,0x10,0x9f,0x2b,0x84,0x14,0x62,
	0xb8,0x37,0x9b,0xb4,0x3f,0x62,0x6b,0x76,0x36,0x39,0xb7,0x41,0xaf,0xb9,0xc9,0xf8,
	0xa5,0x20,0x1f,0x0c,0xfc,0x71,0xca,0x6f,0x56,0x4d,0x6b,0x23,0x5b,0xb2,0x77,0x6f,
	0x83,0xcc,0x8e,0x8c,0x78,0xda,0x4a,0xbf,0x92,0xd4,0x20,0xfe,0x43,0x6a,0xd4,0x7e,
	0xd5,0x6c,0x56,0xdb,0xf8,0x94,0x01,0xc8,0x6f,0xdb,0x00,0x9c,0x0b,0x4c,0x97,0xa5,
	0x2b,0xc1,0x46,0x19,0x91,0x34,0x05,0x9b,0x33,0x20,0xb2,0x79,0xe5,0x00,0x3d,0xb2,
	0x54,0x4f,0xfa,0x23,0xaa,0xfa,0x3d,0x0c,0x83,0xcf,0x81,0xd1,0xd0,0x12,0x03,0x34,
	0xda,0x6b,0xbb,0x63,0xbe,0x1b,0x3c,0x53,0x91,0x2b,0x7e,0xd7,0x76,0x62,0x6e,0xc9,
	0xb1,0x3d,0x74,0x9f,0x96,0xfb,0x66,0xad,0x35,0xba,0x23,0x10,0x9b,0xab,0xc3,0x8a,
	0x87,0xd1,0x0b,0xa2,0x99,0x34,0x8a,0x43,0x90,0xe9,0x65,0xe7,0x69,0x09,0x61,0x5f,
	0xce,0x42,0x58,0x69,0xdf,0x8b,0x0c,0x5a,0xa0,0x6a,0x25,0x33,0x29,0x9e,0x23,0xbb,
	0x77,0xf9,0xa4,0x2f,0x66,0x86,0xc5,0x38,0xf6,0x3d,0xcb,0x03,0xbf,0x94,0x9d,0x56,
	0x73,0x53,0x9d,0xf4,0xc6,0xad,0x22,0x6d,0xff,0x92,0x90,0x63,0x80,0x5b,0xd2,0x4b,
	0x18,0xcd,0xc5,0xe1,0xdb,0x4d,0x96,0xc4,0x29,0x0b,0x0e,0xb8,0x18,0x53,0x66,0x49,
	0x20,0x8e,0xef,0x25,0x93,0x48,0x12,0xe6,0x36,0xd4,0x33,0xcc,0x4d,0x99,0xbd,0x94,
	0x96,0x61,0xb2,0x7a,0x76,0x7f,0xa1,0xd9,0x1b,0x77,0xfc,0xb7,0x54,0xaf,0x6c,0xeb,
	0xec,0x90,0x15,0x21,0x2f,0xe2,0x40,0x05,0x23,0x0c,0x2a,0xe2,0xda,0xa0,0x9b,0x0c,
	0xc7,0x8b,0x31,0xd7,0x8e,0x91,0x95,0x39,0x79,0xd7,0x6d,0xbf,0x86,0x24,0x4d,0xcd,
	0x72,0x43,0x05,0x56,0xc0,0xe1,0x0c,0xed,0x51,0xa3,0xa9,0x85,0x74,0x41,0x20,0xe2,
	0x37,0x66,0x80,0x40,0x02,0xf2,0x4b,0x60,0x36,0x4f,0xcf,0x12,0x5a,0x22,0xbc,0x6c,
	0x21,0xb1,0x2f,0x0c,0x4a,0x26,0xc2,0x14,0x23,0xb3,0x91,0x17,0x48,0x9e,0x27,0x6d,
	0x6a,0x2f,0xaf,0x58,0xe4,0xf7,0x4d,0x40,0x4b,0xd9,0x52,0xa0,0xf6,0x5e,0xc3,0x36,
	0xda,0xa6,0x27,0x81,0x1e,0x7c,0x61,0x45,0x93,0x1a,0xa6,0x9d,0x16,0x61,0x95,0xed,
	0x20,0x2c,0x49,0x6d,0x8f,0x8d,0x1a,0x44,0x89,0x0a,0xce,0x3c,0x00,0x9c,0x76,0x76,
	0xa5,0x0b,0x40,0x52,0xf2,0xb9,0x30,0xae,0xab,0x04,0x41,0xa1,0x30,0x2f,0x43,0x1b,
	0x68,0xdb,0x7c,0x4d,0x6c,0xe6,0x05,0xfc,0xa4,0xab,0xd2,0x0a,0x75,0x0c,0xd9,0x40,
	0x09,0xf1,0xcb,0x5e,0x0a,0x09,0x2c,0x75,0xbc,0x79,0xa5,0xd5,0xb5,0xde,0x07,0xfd,
	0x27,0x31,0x96,0xad,0x66,0xc6,0xa6,0x5e,0x0a,0x57,0x06,0x39,0x03,0xe4,0x84,0x61,
	0xcf,0x25,0x6c,0xcd,0x56,0xf4,0xe7,0xd1,0xff,0x93,0x6c,0x2d,0xd6,0xcf,0x0d,0xe6,
	0x1e,0xe5,0x57,0x37,0xa6,0x6d,0xec,0xa1,0xde,0xe8,0x1f,0x64,0x90,0x5e,0x70,0xe2,
	0xe8,0x05,0x24,0xac,0x36,0xe1,0xea,0x75,0xdf,0x60,0xe2,0xbf,0xc2,0x30,0x82,0x05,
	0x82,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x82,0x05,0x73,
	0x04,0x82,0x05,0x6f,0x30,0x82,0x05,0x6b,0x30,0x82,0x05,0x67,0x06,0x0b,0x2a,0x86,
	0x48,0x86,0xf7,0x0d,0x01,0x0c,0x0a,0x01,0x02,0xa0,0x82,0x04,0xee,0x30,0x82,0x04,
	0xea,0x30,0x1c,0x06,0x0a,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x0c,0x01,0x03,0x30,
	0x0e,0x04,0x08,0xf4,0xa6,0x0f,0xb4,0x2e,0x8e,0x48,0xa6,0x02,0x02,0x08,0x00,0x04,
	0x82,0x04,0xc8,0x0a,0x64,0x3b,0x68,0x4a,0x9a,0xf0,0xf6,0x80,0x65,0x2d,0xca,0xa6,
	0x74,0x33,0x32,0xf3,0x71,0x97,0x27,0x24,0x3c,0xd1,0xaf,0x8b,0xfb,0xee,0x69,0x40,
	0xfc,0xff,0x45,0x32,0x3a,0x1a,0xd1,0x35,0x2d,0xae,0xce,0xd6,0x84,0x5b,0x2b,0x20,
	0x91,0xf8,0x26,0xa6,0x13,0x19,0x21,0x3e,0x8d,0xbb,0x30,0xef,0xdd,0x99,0x58,0x00,
	0x61,0x57,0xe5,0x1b,0xc6,0x96,0xbe,0x7f,0x9e,0x95,0x47,0x7c,0xdf,0xf1,0x09,0x8f,
	0xb9,0xa8,0x99,0x0d,0xf1,0x2a,0xe0,0xfd,0x08,0x92,0xf7,0x56,0x45,0x2e,0xb0,0xf4,
	0x2b,0xf9,0x36,0x43,0xb2,0xbf,0x63,0x82,0x59,0x41,0x25,0x70,0xd6,0x49,0xe8,0x15,
	0x7f,0x77,0x7c,0x7c,0xb3,0xab,0x7e,0xb6,0x16,0xd9,0xf7,0x22,0xa6,0x23,0x00,0x6a,
	0x0e,0x62,0xfa,0xd6,0xe2,0x51,0x13,0x0e,0x99,0x9e,0x12,0x48,0xfa,0x71,0xea,0x47,
	0xeb,0xf7,0xd9,0x9d,0x6f,0xa1,0x77,0x55,0xff,0x30,0xf7,0x68,0x33,0xee,0x26,0x16,
	0xf6,0x43,0x63,0x4e,0xb7,0x16,0x97,0xd3,0x49,0x1c,0xf1,0x9e,0xe0,0xe5,0x77,0x52,
	0xca,0x13,0x48,0x8f,0x11,0x23,0x0d,0x87,0x38,0xa7,0xf3,0x81,0x65,0x96,0xff,0xc7,
	0xb4,0x0f,0x39,0x59,0xff,0x39,0x5a,0x55,0x2b,0x7b,0xab,0x34,0x11,0x42,0x47,0x42,
	0x0c,0xb0,0x71,0x64,0x73,0xa5,0x1d,0x88,0x6e,0xa4,0x61,0x3c,0x67,0x18,0x67,0x2b,
	0x42,0xa1,0x2e,0x60,0xae,0x82,0x3e,0x37,0xc8,0x2e,0x8a,0x80,0x2e,0x9c,0x5d,0xe4,
	0x37,0x58,0xcb,0x6e,0x38,0x75,0x76,0x9a,0xaf,0x25,0xd3,0xb2,0xbe,0xf5,0x36,0x4f,
	0x09,0x05,0xe2,0xe3,0x20,0x03,0x64,0x6f,0x94,0x3b,0xec,0x40,0x8c,0xe1,0x7e,0xed,
	0x94,0xfa,0xed,0x9c,0x4d,0x1d,0xd7,0x31,0x1b,0x9d,0xf3,0xf5,0x1b,0xa0,0xf9,0xc8,
	0xd6,0xf0,0x5e,0xe5,0x26,0x17,0x42,0x18,0xd8,0xe3,0x04,0x65,0xdf,0xa3,0xe6,0x16,
	0x16,0xd5,0xfb,0xbe,0x08,0x1e,0xbf,0xd2,0x0e,0xd5,0x2b,0x4b,0x78,0xb2,0x80,0xf3,
	0x8c,0xe6,0x74,0x89,0xe8,0xce,0xa6,0x2b,0xa5,0x38,0x1f,0x2f,0x87,0x93,0x51,0x35,
	0xe8,0xad,0x6c,0x8d,0x95,0xbd,0xc0,0x24,0xa5,0x14,0x25,0x2d,0xdf,0x4e,0x77,0x32,
	0x68,0xc0,0x91,0xad,0x51,0x95,0x25,0x44,0x7a,0xd7,0x4c,0x75,0xdf,0x73,0xe5,0x2b,
	0xeb,0x1c,0xd3,0xe9,0x42,0xa7,0x5a,0x58,0x85,0x06,0xf0,0xcb,0x38,0x51,0x6d,0x09,
	0x57,0x14,0x6f,0xd8,0x55,0x0c,0x7a,0x77,0x7f,0xb5,0x20,0xe8,0xd0,0xbd,0x88,0x5a,
	0xad,0xe6,0xf5,0x02,0x2c,0x7d,0x0b,0xfb,0xe4,0x07,0xad,0xa2,0xd5,0x0c,0xc5,0xbc,
	0x66,0xc4,0x19,0x48,0xe8,0xa2,0x60,0xdd,0xd2,0xf8,0x03,0x9a,0xd9,0x68,0x4d,0xa9,
	0xd8,0xfa,0xda,0xa3,0x6f,0xcc,0x53,0xea,0x11,0x7e,0xa0,0xa8,0x8f,0xec,0xdb,0xc0,
	0x2a,0x40,0xc6,0x84,0x58,0x4f,0x2a,0x23,0x4c,0xbc,0xfe,0xaa,0x78,0x58,0x9c,0xdd,
	0x6c,0xd5,0x63,0xe9,0xe6,0x78,0xc2,0x73,0x14,0xd5,0x11,0xc3,0x2a,0xf5,0x8a,0x46,
	0x78,0xfc,0x5a,0x59,0xc9,0x9a,0x7f,0xba,0x94,0x44,0xb3,0x45,0x83,0x08,0x94,0x4d,
	0x72,0x0b,0x0f,0xd6,0x89,0x9a,0x75,0x6b,0x31,0xcb,0xeb,0x55,0x85,0x38,0x2c,0x3e,
	0x9b,0x86,0xf0,0x58,0x0f,0x4c,0x93,0x24,0xec,0xd5,0xa3,0x61,0x3a,0x79,0x76,0xab,
	0x37,0x63,0x2d,0x79,0xde,0x6d,0xa3,0x7f,0xf2,0xf0,0x8c,0x45,0xe6,0xce,0x97,0xc6,
	0x88,0xfd,0x93,0xe0,0xf9,0xd0,0x93,0x6a,0x77,0xa4,0x28,0xc3,0x02,0x77,0x87,0xf6,
	0x22,0xfa,0x2b,0x0b,0x31,0xcf,0xe2,0xce,0xaa,0xd9,0x65,0xa6,0x96,0x53,0x8d,0xc7,
	0x67,0xaf,0x0c,0x0f,0xbc,0x51,0xdf,0x0b,0xc4,0xf8,0x06,0x46,0x07,0x12,0x95,0xce,
	0x38,0x8e,0xe7,0x8f,0x8d,0x46,0x68,0xbe,0xa5,0x40,0xdc,0xed,0xab,0x76,0x5c,0x87,
	0xac,0xb3,0x5f,0xb9,0xfd,0x9d,0x79,0x54,0x28,0xc2,0x19,0x2e,0x46,0x3f,0x1f,0x67,
	0xe2,0x58,0x30,0x4e,0x89,0xdd,0x2f,0x44,0x59,0xde,0xe4,0xf4,0x0d,0x4c,0x33,0xe4,
	0x98,0x6d,0xb4,0x1f,0x03,0x6b,0x0f,0x8e,0xde,0x86,0x1b,0x33,0x37,0x74,0x14,0xbe,
	0xa9,0x4a,0xac,0xf4,0x9b,0xa7,0x37,0xe8,0xdd,0x94,0x67,0x25,0x5c,0xb4,0x5b,0x79,
	0xfd,0xd3,0x24,0x21,0x11,0xbe,0x76,0x1f,0x98,0x8b,0x73,0x87,0x0c,0x96,0x82,0x59,
	0x04,0x22,0x8c,0x9b,0x57,0x0c,0xca,0x16,0xb3,0x02,0xc6,0xdc,0x6f,0xd2,0x9c,0xcd,
	0x0f,0x31,0xea,0x97,0x94,0xf7,0x43,0xfe,0xe2,0x8f,0xc7,0x07,0x98,0x57,0x30,0x72,
	0x55,0x43,0xca,0xfa,0xde,0x92,0xf9,0x06,0x9e,0x56,0x73,0x80,0x84,0xbb,0x44,0xe5,
	0x7d,0x04,0xfc,0x49,0x8d,0x28,0xfa,0x91,0xe3,0x50,0x76,0xc2,0xf8,0x87,0x29,0x04,
	0xa4,0xfd,0xfb,0x28,0x20,0xe3,0x07,0xb6,0xf4,0xbf,0xe7,0xc4,0x6a,0x93,0x8c,0x12,
	0xda,0x9d,0x9a,0x5d,0x8c,0x0a,0xd7,0xf5,0x9f,0xbd,0x71,0x00,0xfc,0x22,0xea,0xa4,
	0x45,0x6f,0xd4,0xc6,0x7d,0x7a,0x47,0x38,0x15,0x17,0xc6,0xde,0xb3,0xeb,0x1b,0x9a,
	0xea,0x94,0xc1,0x74,0xd1,0x65,0x25,0xc1,0x11,0x82,0x5d,0xb3,0x66,0x7f,0x05,0xd3,
	0xe1,0x0a,0xfe,0x29,0xcf,0xdd,0x18,0x30,0xff,0x00,0x7f,0xef,0xc1,0x50,0x54,0x7c,
	0x8b,0x89,0x3c,0x6a,0x12,0x9d,0xd4,0x5a,0xcc,0x48,0x76,0xab,0x64,0xd3,0x54,0x36,
	0x70,0x9e,0x04,0x69,0x3d,0x20,0x9d,0x62,0x5d,0xe6,0x55,0x8e,0xd0,0x53,0x5c,0xb4,
	0x54,0x79,0x73,0x69,0x6f,0x56,0xfa,0x60,0x1d,0x61,0xeb,0xeb,0x76,0xb4,0xd5,0x7a,
	0xc9,0x51,0xfc,0xa9,0xed,0x4a,0xfa,0x5c,0x5c,0xb5,0x20,0x6a,0x44,0xf7,0xaa,0xf0,
	0x27,0x90,0x55,0xda,0x2d,0xb4,0x11,0x59,0x21,0x65,0x0e,0x87,0xd2,0x53,0x21,0xd2,
	0x81,0x93,0xf7,0xfe,0x3b,0xec,0x49,0x7e,0x1c,0xdc,0xc2,0x8f,0xdb,0xef,0x3c,0x0a,
	0x40,0x89,0x94,0xf3,0x2d,0x77,0x84,0x15,0x03,0x00,0x29,0xfa,0x1b,0xea,0x55,0x7d,
	0xdc,0xdb,0x69,0x95,0xe5,0x72,0xa5,0x17,0x8f,0xfb,0xfc,0x86,0xfc,0x72,0x91,0x09,
	0x9b,0x32,0x1a,0x06,0x5c,0xa5,0x26,0x4b,0x61,0x40,0x97,0x40,0xce,0x17,0xca,0xe7,
	0x79,0xe6,0xcc,0x6c,0xa3,0x81,0x9c,0x9f,0x36,0x74,0x36,0x9f,0xd9,0x5d,0x3e,0x29,
	0xa0,0xce,0xa1,0x84,0xf6,0xaf,0x33,0x2b,0x8b,0x32,0xb4,0x45,0xb1,0x3d,0x72,0x87,
	0x20,0x8c,0x88,0x02,0x0d,0x93,0x50,0xcc,0x31,0xce,0x03,0xf8,0x85,0x4a,0xdc,0xed,
	0xc0,0xcc,0xb3,0xda,0x06,0xbd,0x12,0xd5,0xfc,0xd2,0xbb,0x75,0x4b,0xca,0xb2,0x77,
	0x18,0xe1,0x5e,0xf5,0x9f,0x0c,0x8c,0xe2,0x17,0x73,0xe5,0xa3,0x80,0x40,0xd8,0x42,
	0xb1,0xf7,0xd0,0x04,0x9f,0x2e,0xc2,0x2b,0x9b,0x5e,0xcb,0xae,0xb4,0x5f,0x95,0x53,
	0xf5,0xc1,0x72,0xf1,0xff,0xa2,0x5a,0xcf,0x1b,0x78,0x5c,0x99,0xdf,0x09,0x24,0xbf,
	0xbf,0x86,0xc3,0x0e,0x65,0x9a,0xe6,0xdc,0xde,0x88,0x28,0x94,0xd7,0xc0,0x6d,0xf6,
	0x93,0x52,0xa6,0x7f,0x74,0x92,0x9b,0x0b,0x62,0xd5,0x2c,0xb4,0xad,0x7c,0xc0,0xc6,
	0x3b,0x1b,0xd2,0xbd,0x89,0xa8,0x64,0x02,0x9c,0x81,0x9a,0xd8,0x51,0x04,0x22,0x10,
	0x62,0x46,0x38,0xaa,0xaa,0x3b,0x00,0x5c,0xe8,0x58,0x09,0x25,0xf7,0x53,0x1d,0x72,
	0xab,0x44,0x80,0xb4,0x33,0x91,0xf8,0x8e,0xe1,0x00,0x5c,0x07,0xdb,0x81,0x71,0x25,
	0x86,0x3b,0xa7,0x8e,0x31,0x02,0x89,0x43,0x8f,0x0a,0xa8,0xac,0x6b,0x2a,0xe3,0xba,
	0x4d,0xdf,0x8c,0x20,0x46,0xea,0xd4,0x98,0x2f,0x47,0x98,0xfb,0x03,0x5e,0xdd,0x92,
	0xc5,0x73,0xa2,0x54,0xf7,0x9f,0x5f,0xda,0xb5,0x1d,0xb5,0xab,0x78,0x2b,0x72,0x43,
	0x07,0x0a,0x34,0x22,0xb6,0x23,0xde,0x90,0x0f,0x85,0x7b,0x31,0x66,0x30,0x3f,0x06,
	0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x09,0x14,0x31,0x32,0x1e,0x30,0x00,0x54,
	0x00,0x65,0x00,0x73,0x00,0x74,0x00,0x20,0x00,0x49,0x00,0x64,0x00,0x65,0x00,0x6e,
	0x00,0x74,0x00,0x69,0x00,0x74,0x00,0x79,0x00,0x20,0x00,0x53,0x00,0x4d,0x00,0x49,
	0x00,0x4d,0x00,0x45,0x00,0x20,0x00,0x32,0x00,0x30,0x00,0x30,0x00,0x37,0x30,0x23,
	0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x09,0x15,0x31,0x16,0x04,0x14,0x69,
	0x6e,0x3e,0x79,0x39,0x9b,0x28,0xf4,0x29,0xd4,0x38,0x78,0xcd,0xbd,0x11,0x46,0xb5,
	0x73,0xec,0x96,0x30,0x30,0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,
	0x05,0x00,0x04,0x14,0x5b,0xc7,0xc7,0x83,0x6c,0xc1,0x23,0xf1,0xeb,0xe8,0xd7,0xc8,
	0x3f,0x4c,0x59,0x18,0x49,0x61,0xdb,0x72,0x04,0x08,0xde,0xab,0x8d,0x3a,0xff,0xf8,
	0x2d,0x69,0x02,0x01,0x01
};

/* Test identity (PKCS12 data), SSL cert, expired in 2008
 */
unsigned char TestIDSSL2007_p12[2753] = {	
	0x30,0x82,0x0a,0xbd,0x02,0x01,0x03,0x30,0x82,0x0a,0x84,0x06,0x09,0x2a,0x86,0x48,
	0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x82,0x0a,0x75,0x04,0x82,0x0a,0x71,0x30,0x82,
	0x0a,0x6d,0x30,0x82,0x04,0xe7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
	0x06,0xa0,0x82,0x04,0xd8,0x30,0x82,0x04,0xd4,0x02,0x01,0x00,0x30,0x82,0x04,0xcd,
	0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x1c,0x06,0x0a,0x2a,
	0x86,0x48,0x86,0xf7,0x0d,0x01,0x0c,0x01,0x06,0x30,0x0e,0x04,0x08,0x7a,0xe7,0xca,
	0x1b,0x57,0x26,0xac,0x5e,0x02,0x02,0x08,0x00,0x80,0x82,0x04,0xa0,0x1a,0x44,0x31,
	0x1c,0x4d,0xa9,0x00,0x7f,0x14,0x71,0x83,0x3b,0x68,0xf8,0xf0,0x6e,0x42,0xd0,0x6a,
	0x8c,0x02,0xbf,0x6e,0x0c,0xcd,0xee,0x7e,0x48,0xab,0x8b,0x7e,0xc7,0xe4,0x66,0x3f,
	0x4d,0x3f,0x05,0xcd,0xa5,0x41,0x5c,0xa2,0x2e,0x59,0x4c,0x62,0x4c,0xa7,0xca,0x31,
	0x10,0xd8,0xc7,0x8c,0xa1,0x6c,0x1d,0x9b,0x27,0x7a,0xa8,0x00,0x7a,0xb9,0xd3,0x4b,
	0x09,0xf0,0xf7,0x75,0xb6,0x53,0xdf,0x54,0xba,0x2e,0x26,0xf5,0x1c,0x49,0x94,0x72,
	0xcb,0x06,0xf3,0xa3,0x28,0xcb,0x48,0xb4,0x70,0x4a,0x0a,0xf8,0xfb,0x82,0xad,0x7f,
	0x50,0x78,0xb7,0x11,0x41,0xd5,0x2b,0x11,0x5c,0x95,0x90,0x0f,0xcb,0xd8,0x95,0xe6,
	0x77,0x74,0x84,0xe5,0x4c,0x24,0xa0,0xd4,0x7a,0x0a,0xd6,0xc8,0x10,0xa4,0x7a,0xcb,
	0x5d,0x81,0x61,0x33,0xb7,0x75,0x6a,0x98,0xbe,0xd4,0xaf,0x3c,0x8c,0x61,0x66,0x43,
	0x6f,0x12,0x4b,0x1e,0x72,0x10,0x76,0xbb,0xc6,0x57,0xbd,0xdb,0x2c,0x99,0xa7,0x53,
	0x1e,0xe5,0x6a,0x42,0x80,0xb9,0x24,0x4f,0x1a,0x2c,0x96,0x0b,0x64,0xd3,0x63,0x36,
	0x6f,0x75,0x74,0x8e,0xd0,0x50,0x5d,0xab,0x4b,0xec,0x59,0x04,0xdb,0x23,0xfb,0x9a,
	0xbf,0xe0,0x88,0x24,0xc6,0x00,0x7e,0xd9,0x12,0x11,0xf0,0xe5,0xe2,0x96,0xb7,0x85,
	0x6b,0x90,0x03,0xab,0x18,0xa4,0x07,0xcc,0xda,0x19,0x76,0x49,0xde,0x41,0x32,0xda,
	0x0f,0x9c,0x8d,0xca,0x96,0xbb,0x39,0xbe,0xeb,0x3d,0xb8,0xe6,0xc1,0xea,0xc5,0xa6,
	0xc3,0x69,0x72,0x96,0x53,0xde,0x36,0x8b,0xee,0x2c,0x6b,0x2e,0x3d,0xad,0xdd,0x9b,
	0x8a,0xd9,0x1c,0xdd,0x92,0xf3,0x38,0xa7,0xec,0x5d,0xa6,0x46,0x54,0x70,0x71,0x0b,
	0xa9,0x1a,0x2a,0x54,0x67,0x6e,0x82,0x8e,0xcb,0x5c,0x2d,0x23,0x2f,0x9b,0x0a,0xc8,
	0xb1,0xf8,0xea,0x9b,0x16,0x72,0xc5,0xf5,0x2c,0x94,0x10,0xdf,0x3f,0xde,0x84,0xa0,
	0x97,0x96,0xfc,0xd7,0x49,0x4e,0xa6,0x37,0x0c,0x2a,0x39,0x08,0x5e,0xbe,0x58,0x9c,
	0x94,0x59,0x98,0x71,0x5b,0x30,0x16,0xcc,0x6f,0x64,0xb5,0xe1,0x1e,0x31,0x34,0x6d,
	0x4a,0xe6,0xb0,0x20,0x31,0x81,0xe4,0x0e,0x48,0x7e,0x4c,0xc4,0xfa,0x9c,0x57,0xf9,
	0xee,0x58,0xfb,0xc2,0x1b,0xd7,0x96,0xdd,0x91,0x0f,0x86,0x40,0xc9,0x45,0x29,0x07,
	0x65,0x48,0xd1,0x1d,0xf8,0x1c,0x6d,0x1d,0x5d,0xce,0x76,0xce,0x70,0x33,0x4f,0x1d,
	0xcc,0x4a,0x87,0xd0,0x9a,0xf3,0xb5,0x40,0xf3,0x35,0xcc,0x89,0x26,0x72,0x94,0x53,
	0x79,0x59,0xbb,0xe6,0xc4,0x24,0x63,0x46,0x83,0x27,0xb7,0xf8,0xff,0x80,0x4c,0x0a,
	0x98,0xee,0xe7,0x4a,0x73,0x11,0x90,0xbf,0x94,0x1c,0x03,0x91,0x78,0xe8,0x01,0x3a,
	0xa1,0xf3,0x53,0xea,0x78,0xb1,0x09,0x4e,0xea,0x2d,0xaa,0xb4,0xce,0xce,0xb1,0xc6,
	0x51,0xb6,0x59,0x52,0x89,0x7e,0xab,0x4c,0xe3,0xd3,0x9b,0x6b,0xa7,0xf2,0xca,0x70,
	0x53,0x95,0x8a,0x13,0xfc,0xc0,0xa2,0x24,0xd2,0x94,0xb5,0xe5,0x95,0x38,0x01,0x39,
	0x0a,0x28,0x1d,0x83,0xd1,0x2a,0x03,0xfa,0xf6,0x6e,0x63,0x80,0x17,0x05,0x18,0x33,
	0x11,0x56,0xe1,0x7e,0x66,0x94,0xbf,0x1b,0x8b,0x11,0xcf,0x41,0xbf,0x71,0xd9,0xa3,
	0x6f,0xbb,0xf5,0xae,0x43,0x1d,0x2f,0xf1,0x88,0x00,0x72,0xca,0x49,0x83,0x3e,0xe3,
	0x87,0x5e,0x0f,0x58,0x97,0xaa,0x2b,0x92,0x40,0xdd,0x8b,0x17,0xce,0xd8,0x11,0x05,
	0xa4,0x03,0x51,0x0b,0xfa,0x35,0x4c,0xde,0x5b,0xda,0x88,0xdd,0x3a,0xe7,0x93,0x60,
	0xca,0xe2,0x8e,0x84,0xcd,0x5b,0x6d,0xb6,0x5c,0x53,0xbc,0x85,0x75,0x96,0xaa,0x00,
	0x06,0x19,0x84,0x66,0x4d,0x41,0x89,0xdd,0x84,0x81,0xbe,0xb6,0xa3,0x69,0x71,0xf4,
	0x3e,0x31,0x89,0xae,0x9e,0x77,0x68,0xff,0x21,0x78,0xa2,0x43,0xc9,0x0e,0x36,0xe0,
	0xa0,0xb6,0xae,0x40,0xf1,0xf4,0xe3,0xc8,0xa9,0x89,0x80,0x32,0x45,0x07,0x37,0xf1,
	0x1d,0xc3,0x1e,0x79,0x0b,0x8b,0x1d,0x7d,0xc9,0xd6,0xa2,0x91,0xc8,0xd8,0x05,0xc0,
	0xc0,0x25,0x27,0x97,0x5f,0x60,0x3f,0xc7,0xc9,0x3e,0xf2,0xac,0x7e,0x4c,0x4b,0x42,
	0x15,0x85,0x1a,0xe0,0xe1,0xfa,0xf9,0x27,0xaf,0x8d,0x6f,0x90,0x52,0x33,0x6c,0x55,
	0xa7,0x9d,0x9c,0x0b,0xc1,0xf8,0xe5,0xa9,0xd7,0x9c,0x81,0xce,0x08,0x49,0x9c,0xb1,
	0x91,0x00,0xdd,0x6f,0xaf,0x17,0xf8,0x01,0xb5,0x9e,0x53,0x2a,0xa0,0xdd,0x47,0x6e,
	0xb3,0x1b,0xd3,0x9d,0xc1,0x8c,0x07,0x9b,0x78,0x8c,0x2e,0xad,0xbb,0x7d,0xe1,0x0a,
	0x11,0x35,0xf7,0xfa,0xf4,0x00,0xf3,0xc2,0xa6,0xf1,0x3f,0xa1,0xdc,0xe1,0xc2,0x2a,
	0x4b,0x22,0x31,0x20,0x45,0x93,0xbb,0x5e,0xfc,0xe5,0xd7,0xcb,0x69,0x1b,0xad,0x3a,
	0x48,0x59,0x9c,0xc7,0x74,0xbb,0x79,0x56,0xb7,0x73,0x92,0x54,0x49,0xc9,0xbc,0x5d,
	0xf2,0x74,0xc8,0x63,0xa8,0x9c,0x99,0x67,0x4d,0x75,0x64,0x10,0x46,0xe7,0x0f,0xf1,
	0xb0,0x4e,0x8b,0x9d,0x4f,0xa7,0x67,0xe9,0xec,0xbf,0x1b,0x0a,0xfd,0xde,0xe4,0xf6,
	0xcd,0xba,0x12,0xce,0x4e,0xb5,0x29,0xbf,0x59,0x0b,0xf7,0xea,0xc7,0x7c,0xfb,0xe4,
	0xe6,0x36,0x86,0x52,0x18,0xf6,0xe5,0x14,0xe1,0x92,0x02,0x98,0x08,0x0f,0xbc,0xd0,
	0x40,0xf3,0xb1,0x87,0xcc,0x6b,0xee,0xee,0x1a,0x8c,0x40,0x13,0x53,0x9e,0x61,0xb3,
	0x17,0x02,0x7e,0x97,0x22,0x90,0x6f,0xf0,0x64,0x75,0x42,0xf4,0xf9,0x8f,0x38,0x46,
	0x27,0x5c,0x14,0x82,0x80,0x71,0xe9,0x7d,0xe9,0xc8,0x32,0xb2,0xae,0xbd,0x90,0x28,
	0xda,0xc0,0xc1,0x6d,0x06,0x03,0x6c,0x83,0x68,0x3b,0xdf,0xb4,0xb4,0x48,0x04,0x0e,
	0xbb,0x6e,0xa8,0xa5,0xa5,0x1b,0x36,0xbe,0xfc,0x40,0xd3,0x97,0xc3,0x62,0xb9,0x34,
	0x94,0xbf,0x01,0xfb,0x21,0xae,0xbb,0xd9,0xdd,0x0d,0xe0,0xf4,0xce,0x25,0x9a,0x7c,
	0xc4,0x10,0xfc,0xac,0x53,0x1d,0x11,0xdc,0x5c,0x4c,0x6e,0x65,0xb3,0x9c,0xca,0x76,
	0x3d,0x5d,0x2d,0x21,0x64,0xa6,0x3c,0xc1,0xa1,0x35,0xe7,0x38,0x8b,0x39,0x9f,0x7f,
	0x93,0x68,0x6f,0xeb,0x96,0x4f,0x7c,0xd3,0x49,0xbe,0x65,0xdb,0x82,0x91,0x2a,0xb4,
	0x62,0x38,0xdd,0x73,0xa7,0x7f,0x66,0x54,0xfa,0x92,0x65,0xbf,0x71,0xc6,0x62,0x38,
	0x96,0xe2,0xf4,0x16,0xc6,0xf7,0x7e,0x9d,0x7a,0x4f,0x35,0x5f,0x0e,0x29,0xe6,0x38,
	0x7b,0x05,0x02,0x61,0xfb,0x16,0xb4,0x43,0xe9,0xb1,0x74,0x3d,0x50,0xe3,0x51,0x5c,
	0x54,0x5e,0x3e,0xe0,0xb1,0xfe,0x20,0x2d,0xe0,0x05,0x25,0x2f,0x1f,0x9a,0x25,0xe9,
	0xec,0xb6,0xb8,0x9a,0xe9,0xff,0x3a,0x7a,0xc8,0x53,0xfd,0xc4,0x61,0xb1,0xa1,0x22,
	0xc6,0x85,0x7a,0x11,0x07,0x84,0xe9,0x58,0x15,0x74,0x33,0x08,0x1f,0x59,0xe9,0x0d,
	0x7f,0x7e,0x38,0xd9,0x77,0x22,0x46,0xb5,0xfc,0xd5,0x3b,0x1d,0x47,0x7a,0x4a,0x16,
	0x35,0xa8,0x67,0x99,0x6d,0x72,0x66,0x0d,0xd4,0xb3,0x3b,0xdf,0xb8,0x9f,0x7f,0x59,
	0x37,0x97,0x65,0xdf,0x79,0x0c,0x15,0xe3,0x14,0x99,0xc0,0x1a,0xcc,0x9a,0x98,0x6a,
	0xb7,0x59,0x35,0x21,0x31,0x3e,0xf4,0xa2,0xce,0xc4,0xca,0x60,0xf8,0xa0,0x43,0xb6,
	0xbe,0x8a,0x0a,0x95,0xea,0xe7,0xa0,0xdb,0x4f,0x36,0x22,0xf8,0xb6,0x60,0xff,0x15,
	0x69,0x45,0x84,0x53,0xad,0x48,0x00,0x0e,0x20,0xb3,0x62,0x07,0xbd,0x02,0x46,0x19,
	0xf6,0x3d,0xb8,0x55,0x4b,0x5f,0xac,0x3a,0x6a,0x86,0xcf,0x07,0x79,0x30,0x82,0x05,
	0x7e,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x82,0x05,0x6f,
	0x04,0x82,0x05,0x6b,0x30,0x82,0x05,0x67,0x30,0x82,0x05,0x63,0x06,0x0b,0x2a,0x86,
	0x48,0x86,0xf7,0x0d,0x01,0x0c,0x0a,0x01,0x02,0xa0,0x82,0x04,0xee,0x30,0x82,0x04,
	0xea,0x30,0x1c,0x06,0x0a,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x0c,0x01,0x03,0x30,
	0x0e,0x04,0x08,0xd3,0x22,0x2a,0xd2,0xd9,0xd0,0xd6,0xd3,0x02,0x02,0x08,0x00,0x04,
	0x82,0x04,0xc8,0x7b,0x88,0x0e,0x83,0x90,0x25,0x3f,0x51,0xab,0x13,0xf1,0x35,0x1f,
	0xec,0x56,0xcb,0xfc,0x31,0x6b,0xd1,0x1a,0x6c,0x35,0x51,0x31,0xb7,0x27,0x2e,0xe6,
	0x8c,0x75,0x7d,0xa6,0x58,0xfd,0x08,0x0b,0xe4,0x39,0x63,0xc6,0x3e,0x2d,0xee,0x2b,
	0xe5,0x58,0x90,0x48,0xb5,0x57,0x38,0x97,0x48,0xf3,0x2c,0xac,0xf1,0xf8,0x10,0x9c,
	0x56,0x02,0xc7,0x9d,0x7f,0x9e,0xe0,0x9c,0x96,0xe7,0x0c,0x9f,0x54,0xab,0x9f,0x26,
	0x17,0xac,0x86,0x88,0x5e,0x4a,0x9c,0xce,0xea,0xc8,0x48,0x83,0x0c,0x2e,0xf0,0xa0,
	0x6c,0x96,0x07,0x26,0x47,0x63,0xc1,0xac,0x27,0xd1,0x1a,0x25,0x88,0x43,0x8e,0x9d,
	0xe0,0x5f,0x80,0xd9,0xd1,0x1a,0x86,0x92,0x12,0x80,0xe1,0x99,0x13,0xc3,0xab,0x53,
	0x97,0xbe,0x51,0x17,0xc4,0x5a,0x9d,0xc0,0xcd,0xe4,0xc5,0xd6,0x44,0x56,0xaa,0x8d,
	0x5b,0x3d,0xc8,0x66,0xaf,0x6c,0xd2,0x96,0xc6,0x83,0x57,0x7a,0x0e,0x66,0x68,0xd6,
	0x30,0xf0,0xaa,0xde,0x13,0x92,0x5e,0x21,0x2c,0x36,0x96,0x77,0x1f,0xd0,0xaa,0x4b,
	0x14,0x9f,0x9f,0xe5,0xa4,0x3f,0xbf,0x7a,0x9b,0x38,0xff,0x91,0x1d,0x0d,0xd4,0x32,
	0x34,0x2b,0x3f,0xd8,0xfb,0x09,0x71,0xdf,0x1b,0x61,0xa3,0x36,0x81,0xaa,0x49,0xa3,
	0xe4,0x5c,0xc4,0x8d,0xc5,0xab,0xc0,0x43,0xbe,0xc1,0x41,0xa2,0xcc,0x28,0x36,0x65,
	0xa6,0xb6,0x73,0x96,0x6a,0x5f,0x1a,0xd9,0xb8,0x48,0x49,0x7b,0x12,0xda,0x2a,0xdb,
	0xaa,0xaf,0x46,0x8b,0x39,0x7e,0xa7,0x78,0x88,0x15,0x95,0x32,0x13,0x76,0xbb,0x2d,
	0xf5,0xd5,0x41,0x6a,0x9b,0xb8,0xe6,0x6d,0x43,0xa6,0xc3,0x53,0xb7,0xc5,0x68,0x9d,
	0xa9,0x84,0x30,0x42,0x59,0x33,0x81,0x79,0x22,0x91,0x1e,0x34,0x31,0x9b,0xd4,0xf3,
	0x2a,0xda,0xe2,0xa3,0x95,0x7a,0x2a,0x9c,0x67,0x57,0xee,0x2b,0x89,0xfc,0x64,0x67,
	0x00,0x98,0x21,0x63,0xc7,0x19,0x95,0x69,0x9b,0x42,0x73,0x5c,0x68,0x59,0xfc,0x64,
	0xe5,0x22,0x57,0x54,0x58,0x06,0xff,0xa3,0x87,0x7d,0x05,0xc8,0xc4,0xfd,0xc7,0x29,
	0x1b,0x1d,0x88,0x0b,0x08,0x96,0x94,0x9b,0xd8,0xee,0x47,0x99,0x06,0xfa,0x64,0x67,
	0xfd,0xb0,0xb1,0xa1,0xf5,0x26,0x7e,0xb1,0x46,0xb1,0x0c,0x82,0x52,0x5f,0xc5,0x94,
	0x23,0x75,0xff,0xb3,0x42,0x18,0xa2,0x9f,0x65,0xfb,0x06,0xb0,0x8a,0x29,0xc1,0x6e,
	0x84,0xd9,0xd4,0x39,0x77,0x02,0x47,0xe3,0x5f,0xf2,0xb4,0x84,0xc0,0x75,0x48,0x4b,
	0x3a,0xef,0x48,0x2e,0x8d,0xa1,0xe5,0xc6,0x86,0x44,0x00,0xd9,0x4d,0x73,0xed,0x68,
	0x8c,0x91,0x56,0x3e,0x2c,0x18,0xd0,0x58,0xd8,0x04,0x15,0xe0,0xd8,0xa8,0xe6,0x46,
	0x36,0x54,0xc5,0x8c,0x2b,0x98,0xa5,0x01,0x73,0xf0,0x67,0x95,0x41,0x4e,0xa3,0xd6,
	0x8d,0x24,0xc4,0xc3,0x8f,0x28,0x7c,0x76,0x76,0x84,0x6c,0x95,0x94,0x22,0xde,0xe2,
	0x9d,0xcb,0x37,0xb6,0x97,0x6b,0xf3,0x58,0x1d,0x5a,0x98,0x88,0xac,0xd9,0xb1,0x59,
	0x16,0x11,0xd8,0x0b,0x68,0xce,0xdf,0x4b,0x1a,0x28,0x3c,0xeb,0x14,0xb2,0x28,0xa7,
	0xad,0x54,0x55,0xa1,0x6b,0x50,0x86,0x55,0x00,0xae,0xf6,0xdf,0x6b,0xb3,0x42,0xb3,
	0x7b,0xbb,0x0d,0x91,0x14,0xdb,0x82,0xea,0xe9,0x08,0x9f,0xf6,0x6f,0xd0,0x10,0xd7,
	0x83,0x1e,0xfc,0x5e,0x58,0xca,0x01,0xdd,0xb4,0xc8,0xbe,0x80,0xe3,0x07,0x71,0x0a,
	0x74,0x01,0xd4,0xf1,0x50,0xe1,0x51,0x22,0xb1,0x43,0x98,0xf1,0x5e,0xdd,0xb4,0x65,
	0x5a,0x18,0x0c,0x8b,0x1b,0x4e,0xe1,0xce,0xb1,0x0e,0x81,0xda,0x6b,0x98,0xc4,0xcb,
	0xd9,0xd2,0xb2,0x1e,0xea,0xac,0x0c,0x08,0x86,0xa4,0x60,0xab,0x84,0x50,0x13,0xf8,
	0x48,0xfb,0x64,0xf3,0x33,0x88,0x83,0x72,0x22,0xe8,0x6a,0x43,0xd3,0xb4,0xc7,0xd2,
	0x04,0xed,0x07,0x75,0x26,0x96,0x2d,0x84,0xb9,0x10,0x02,0xd2,0xda,0xc8,0xc8,0x0b,
	0x95,0xe3,0x69,0x1e,0x57,0x16,0x7a,0xb5,0x1c,0xe7,0x46,0x89,0xfc,0xed,0x49,0x69,
	0x47,0xb8,0x07,0xe4,0xcb,0xd1,0x52,0xd6,0x8c,0x32,0xaa,0x91,0x8d,0x45,0x19,0xf1,
	0x54,0x23,0x3c,0x5f,0xcc,0xc7,0x60,0xfc,0x89,0x00,0x9a,0xa3,0xc2,0xf0,0x48,0xda,
	0xbf,0xe4,0xfd,0x78,0x3b,0x6c,0x2d,0x34,0x91,0x6b,0x0d,0x21,0xb4,0xba,0xe8,0x6d,
	0x80,0xbc,0xfb,0x91,0xcb,0xce,0x77,0x01,0x4e,0xfe,0x7b,0xf2,0x08,0x78,0x2e,0x3f,
	0x16,0xd4,0xfd,0xf0,0x76,0x68,0xce,0x43,0xdc,0xb2,0xe2,0x82,0x64,0x8f,0xc8,0x71,
	0x0f,0x6e,0xc6,0x3b,0x4a,0x6b,0x6a,0xd7,0xf6,0x21,0x46,0xcd,0x05,0xce,0x19,0xab,
	0x28,0x28,0x55,0x19,0x1d,0x07,0xaf,0x38,0xd9,0x9c,0xdf,0xe8,0x91,0x68,0x16,0xdd,
	0x36,0x19,0x71,0x46,0x86,0x08,0x0a,0x08,0x34,0xc5,0x3b,0x53,0xaa,0x35,0x27,0x6e,
	0xe4,0xf3,0xa1,0xd6,0x04,0x78,0xf9,0x63,0xec,0x1e,0xfe,0x30,0x38,0xb3,0xe7,0xd8,
	0x27,0x9f,0x98,0xd5,0xb9,0x4d,0xb9,0x80,0x4f,0xb0,0x81,0xc6,0xaa,0xc2,0xe6,0xbf,
	0x98,0x63,0x05,0xc6,0xab,0x4e,0xc8,0x7e,0xf4,0x37,0x68,0xad,0x63,0x08,0x6e,0x8f,
	0xe5,0xd9,0x62,0x43,0xa3,0x0d,0x61,0x84,0x41,0x02,0xd0,0xc6,0x33,0x19,0x76,0xb8,
	0x31,0xb1,0x27,0x2f,0x81,0x40,0x71,0x35,0x3c,0xf6,0xf2,0xc7,0x9b,0x85,0x9c,0x2e,
	0xa0,0xf6,0xd2,0x3a,0xd9,0x7e,0xdd,0x82,0x56,0xf4,0x61,0x97,0x79,0xdb,0x27,0x5d,
	0xa7,0x5b,0x8d,0x01,0x9d,0x68,0x9b,0x3a,0x4e,0xe1,0x3c,0xaf,0x61,0x0f,0xbf,0xfa,
	0x61,0x12,0x2f,0xde,0x7a,0x71,0x0a,0xdd,0x6e,0x29,0x11,0x8e,0xa4,0x93,0x31,0x85,
	0x2a,0x31,0xa8,0xd7,0x3f,0xfb,0xf4,0xd2,0xd4,0x7f,0x0c,0xb2,0x8d,0x63,0x25,0x47,
	0x18,0x04,0x00,0x28,0x90,0xd3,0xc0,0x7e,0xca,0xfa,0x0d,0xc4,0xab,0xd4,0x7a,0x17,
	0xb7,0xdc,0xce,0x7d,0xc2,0xe8,0x5b,0x68,0x7c,0xa9,0x3c,0xac,0x4e,0x2c,0xde,0x0c,
	0x4a,0x09,0x09,0x03,0x77,0x12,0xb9,0x31,0xc9,0x0d,0x6e,0x2b,0xac,0x96,0x7b,0xb0,
	0x3d,0x37,0x03,0x32,0xc6,0xe1,0x64,0x16,0xc1,0x1b,0xfa,0xa3,0x32,0xe9,0xea,0x25,
	0x0c,0xa1,0xbf,0xae,0xaa,0xba,0xbd,0x24,0xba,0x9d,0x5f,0x15,0x20,0x59,0x2d,0xe5,
	0x09,0xe6,0x71,0x70,0xcd,0xf5,0x44,0x12,0xcf,0x17,0x8b,0x33,0x4b,0x67,0x86,0x53,
	0xd3,0x66,0x80,0x2e,0xfb,0x6b,0x95,0x38,0x35,0x2d,0x39,0xb8,0x19,0xb7,0x01,0xe0,
	0xe2,0x7d,0x29,0xd3,0x89,0xc7,0xc9,0x4f,0xb4,0xf9,0x48,0x20,0x6a,0x40,0xd3,0x71,
	0x28,0xf4,0xdf,0x3a,0xff,0xf0,0xd1,0x7a,0x78,0xbd,0x92,0xe4,0xa2,0x05,0x47,0xf5,
	0xfa,0x25,0x4f,0x22,0x3f,0x8f,0x85,0x72,0xaa,0x0f,0xfa,0x21,0x84,0x63,0xbc,0xb6,
	0xe0,0x49,0x1e,0xdf,0x0a,0xee,0x4b,0xa8,0x96,0xbf,0x2f,0xa7,0x31,0x64,0xc3,0xa1,
	0x19,0xe1,0x2b,0x69,0xbf,0x0f,0xcc,0x76,0x49,0x9f,0xdd,0x4e,0xf0,0x77,0xf0,0xae,
	0x83,0x20,0xe2,0xd6,0x21,0x1a,0x3a,0x1a,0xb4,0xbf,0x57,0x02,0x9c,0xf6,0xb1,0x47,
	0x83,0x59,0x0c,0x43,0xce,0x9a,0x3d,0xb3,0x9b,0x9c,0xd2,0x30,0xcd,0x40,0x58,0xfe,
	0xec,0xa9,0x59,0xa8,0xf6,0x28,0x31,0xbf,0xc3,0xfb,0xad,0x37,0x07,0xd4,0x34,0xe7,
	0x58,0xfa,0xca,0xe7,0xe3,0xbb,0x3d,0xd8,0xf6,0xd7,0x9c,0xf5,0x6f,0xc0,0xbd,0x9e,
	0x3a,0x91,0x30,0x7c,0xe4,0xff,0x8d,0xbe,0x85,0x91,0x27,0x92,0x51,0xdc,0xd6,0x66,
	0x7e,0x5a,0xfb,0xf7,0xbe,0x34,0xce,0x5e,0xa4,0x50,0xf1,0x6d,0xc0,0x32,0x3b,0xaa,
	0x8c,0x52,0x25,0xcc,0x75,0x26,0x2b,0xa8,0x2f,0x6f,0x02,0x81,0x18,0x07,0x5f,0xbe,
	0xc3,0xed,0xa3,0x93,0x73,0xc9,0xd4,0x79,0xec,0x34,0x78,0x31,0x62,0x30,0x3b,0x06,
	0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x09,0x14,0x31,0x2e,0x1e,0x2c,0x00,0x54,
	0x00,0x65,0x00,0x73,0x00,0x74,0x00,0x20,0x00,0x49,0x00,0x64,0x00,0x65,0x00,0x6e,
	0x00,0x74,0x00,0x69,0x00,0x74,0x00,0x79,0x00,0x20,0x00,0x53,0x00,0x53,0x00,0x4c,
	0x00,0x20,0x00,0x32,0x00,0x30,0x00,0x30,0x00,0x37,0x30,0x23,0x06,0x09,0x2a,0x86,
	0x48,0x86,0xf7,0x0d,0x01,0x09,0x15,0x31,0x16,0x04,0x14,0xd0,0xcb,0xd6,0x5c,0xe1,
	0x73,0x7a,0xb8,0xa8,0x2a,0xf8,0xc9,0xe6,0xdc,0xbb,0xc2,0xec,0x00,0x2e,0x6a,0x30,
	0x30,0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14,
	0x47,0x2e,0x9e,0xca,0x71,0x3b,0x36,0xcf,0x34,0x59,0x7e,0x0a,0x6e,0xe0,0xeb,0x79,
	0xcb,0x82,0x47,0x76,0x04,0x08,0xff,0xe9,0xf7,0xee,0x2f,0x48,0xcc,0x24,0x02,0x01,
	0x01
};


static int quiet = 0;
static int debug = 0;
static int verbose = 0;

#define MAXNAMELEN MAXPATHLEN
#define MAXITEMS INT32_MAX

#pragma mark -- Utility Functions --


void PrintTestResult(char *testStr, OSStatus status, OSStatus expected)
{
	if (verbose) {
		fprintf(stdout, "%s: %s (result=%d, expected=%d)\n", testStr,
				(status==expected) ? "OK" : "FAILED",
				(int)status, (int)expected);
	}
	if (debug) {
		fprintf(stdout, "\n");
	}
	fflush(stdout);
}


void PrintStringToMatch(CFStringRef nameStr)
{
	char *buf = (char*)malloc(MAXNAMELEN);
	if (buf) {
		if (CFStringGetCString(nameStr, buf, (CFIndex)MAXNAMELEN, kCFStringEncodingUTF8)) {
			fprintf(stdout, "### String to match is \"%s\"\n", buf);
			fflush(stdout);
		}
		free(buf);
	}
}


void PrintSecCertificate(SecCertificateRef certificate)
{
	CFStringRef nameStr;
	OSStatus status = SecCertificateCopyCommonName(certificate, &nameStr);
	if (status) {
		fprintf(stderr, "### SecCertificateCopyCommonName error %d\n", (int)status);
	}
	else {
		char *buf = (char*)malloc(MAXNAMELEN);
		if (buf) {
			if (CFStringGetCString(nameStr, buf, (CFIndex)MAXNAMELEN, kCFStringEncodingUTF8)) {
				fprintf(stdout, "### Found certificate name: \"%s\"\n", buf);
			}
			free(buf);
		}
		CFRelease(nameStr);
	}
}


void PrintSecIdentity(SecIdentityRef identity)
{
	SecCertificateRef certRef;
	OSStatus status = SecIdentityCopyCertificate(identity, &certRef);
	if (status) {
		fprintf(stderr, "### SecIdentityCopyCertificate error %d\n", (int)status);
	}
	else {
		PrintSecCertificate(certRef);
		CFRelease(certRef);
	}
}


void PrintCFStringWithFormat(const char *formatStr, CFStringRef inStr)
{
	char *buf = (char*)malloc(MAXNAMELEN);
	if (buf) {
		if (CFStringGetCString(inStr, buf, (CFIndex)MAXNAMELEN, kCFStringEncodingUTF8)) {
			fprintf(stdout, formatStr, buf);
			fflush(stdout);
		}
		free(buf);
	}
}


void PrintCFThing(CFTypeRef thing)
{
	fprintf(stderr, "### Results: %p\n", (void*)thing);

	CFTypeID thingID = (thing) ? CFGetTypeID(thing) : 0;
	if (thingID == SecCertificateGetTypeID()) {
		// print a SecCertificateRef
		PrintSecCertificate((SecCertificateRef)thing);
	}
	else if (thingID == SecIdentityGetTypeID()) {
		// print a SecIdentityRef
		PrintSecIdentity((SecIdentityRef)thing);
	}
	else if (thingID == SecKeychainItemGetTypeID() ||
		thingID == SecIdentityGetTypeID() ||
		thingID == CFDictionaryGetTypeID() ||
		thingID == CFArrayGetTypeID() ||
		thingID == CFStringGetTypeID() ||
		thingID == CFDataGetTypeID()) {
		CFShow(thing);
	}
	else {
		fprintf(stderr, "### ERROR: result is not a supported CFType! (%ld)\n",
			thingID);
	}
}

//%%% FIXME need to break this up into separate functions
int TestAddItems()
{
	SecCertificateRef certs[5];
	SecKeychainRef keychain;
	CFDataRef tmpData;
	OSStatus status;

#if AUTO_TEST
	/* the regression suite environment does not have a keychain; must create one */
	status = SecKeychainCreate("SecItemTest.keychain", 4, "test", FALSE, NULL, &keychain);
#else
	status = SecKeychainCopyDefault(&keychain);
#endif
	if (status) {
		fprintf(stderr, "Unable to get default keychain: error %d\n", (int)status);
		goto error_exit;
	}

	/* add test leaf */
	tmpData = CFDataCreateWithBytesNoCopy(NULL, LEAF_CERT, sizeof(LEAF_CERT), kCFAllocatorNull);
	certs[0] = SecCertificateCreateWithData(NULL, tmpData);
	CFRelease(tmpData);
// will add this below using SecItemAdd instead of SecCertificateAddToKeychain
#if 0
	status = SecCertificateAddToKeychain(certs[0], keychain);
	if (status && status != errSecDuplicateItem) { // ignore error if duplicate
		fprintf(stderr, "Unable to add test leaf certificate: error %d\n", (int)status);
		goto error_exit;
	}
#endif
	/* add test intermediate */
	tmpData = CFDataCreateWithBytesNoCopy(NULL, INTERMEDIATE_CERT, sizeof(INTERMEDIATE_CERT), kCFAllocatorNull);
	certs[1] = SecCertificateCreateWithData(NULL, tmpData);
	CFRelease(tmpData);
// will add this below using SecItemAdd instead of SecCertificateAddToKeychain
#if 0
	status = SecCertificateAddToKeychain(certs[1], keychain);
	if (status && status != errSecDuplicateItem) { // ignore error if duplicate
		fprintf(stderr, "Unable to add test intermediate certificate: error %d\n", (int)status);
		goto error_exit;
	}
#endif
	/* add test root */
	tmpData = CFDataCreateWithBytesNoCopy(NULL, ROOT_CERT, sizeof(ROOT_CERT), kCFAllocatorNull);
	certs[2] = SecCertificateCreateWithData(NULL, tmpData);
	CFRelease(tmpData);
// will add this below using SecItemAdd instead of SecCertificateAddToKeychain
#if 0
	status = SecCertificateAddToKeychain(certs[2], keychain);
	if (status && status != errSecDuplicateItem) { // ignore error if duplicate
		fprintf(stderr, "Unable to add test root certificate: error %d\n", (int)status);
		goto error_exit;
	}
#endif

	/* use SecItemAdd to add an array containing certs 1-3 */
	CFArrayRef certArray = CFArrayCreate(NULL, (const void**) certs, 3, &kCFTypeArrayCallBacks);
	CFMutableDictionaryRef attrs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	CFDictionaryAddValue(attrs, kSecClass, kSecClassCertificate); // we are adding certificates
	CFDictionaryAddValue(attrs, kSecUseItemList, certArray); // add these items (to default keychain, since we aren't specifying one)
	status = SecItemAdd(attrs, NULL);
	CFRelease(attrs);
	CFRelease(certArray);
	if (status && status != errSecDuplicateItem) { // ignore error if duplicate
		fprintf(stderr, "Unable to add 3 test certificates: error %d\n", (int)status);
		goto error_exit;
	}


	/* add test cert for S/MIME policy (encrypt only, no sign) */
	tmpData = CFDataCreateWithBytesNoCopy(NULL, Test_smime_encryptonly, sizeof(Test_smime_encryptonly), kCFAllocatorNull);
	certs[3] = SecCertificateCreateWithData(NULL, tmpData);
	CFRelease(tmpData);
	status = SecCertificateAddToKeychain(certs[3], keychain);
	if (status && status != errSecDuplicateItem) { // ignore error if duplicate
		fprintf(stderr, "Unable to add test S/MIME certificate: error %d\n", (int)status);
		goto error_exit;
	}

	/* add test cert for Code Signing policy */
	tmpData = CFDataCreateWithBytesNoCopy(NULL, Test_codesign, sizeof(Test_codesign), kCFAllocatorNull);
	certs[4] = SecCertificateCreateWithData(NULL, tmpData);
	CFRelease(tmpData);
	status = SecCertificateAddToKeychain(certs[4], keychain);
	if (status && status != errSecDuplicateItem) { // ignore error if duplicate
		fprintf(stderr, "Unable to add test Code Signing certificate: error %d\n", (int)status);
		goto error_exit;
	}

	/* import test SSL identity */
	{
		CFDataRef p12DataRef = CFDataCreateWithBytesNoCopy(NULL, Test_p12, (CFIndex)sizeof(Test_p12), kCFAllocatorNull);
		SecExternalFormat format = kSecFormatPKCS12;
		SecExternalItemType itemType = kSecItemTypeAggregate;
		SecItemImportExportFlags flags = 0;
	#if 0
		/* deprecated method, using CDSA constants */
		SecKeyImportExportParameters keyParams = {
			SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION,	// uint32_t version
			0,				// SecKeyImportExportFlags flags
			CFSTR("test"),	// CFTypeRef passphrase
			CFSTR("title"),	// CFStringRef alertTitle
			CFSTR("pw:"),	// CFStringRef alertPrompt
			NULL,			// SecAccessRef accessRef (unspecified, use default)
			CSSM_KEYUSE_SIGN,				// CSSM_KEYUSE keyUsage (0=unspecified)
			CSSM_KEYATTR_PERMANENT			// CSSM_KEYATTR_FLAGS keyAttributes
		};
		status = SecKeychainItemImport(p12DataRef,
			NULL, &format, &itemType, flags, &keyParams, keychain, NULL);
	#else
		CFTypeRef keyUsages[1] = { kSecAttrCanSign };
		CFArrayRef keyUsagesArray = CFArrayCreate(NULL, keyUsages, 1, &kCFTypeArrayCallBacks);
		CFTypeRef keyAttrs[1] = { kSecAttrIsPermanent };
		CFArrayRef keyAttrsArray = CFArrayCreate(NULL, keyAttrs, 1, &kCFTypeArrayCallBacks);
		SecItemImportExportKeyParameters keyParams = {
			SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION,	// uint32_t version
			0,				// SecKeyImportExportFlags flags
			CFSTR("test"),	// CFTypeRef passphrase
			CFSTR("title"),	// CFStringRef alertTitle
			CFSTR("pw:"),	// CFStringRef alertPrompt
			NULL,			// SecAccessRef accessRef (unspecified, use default)
			keyUsagesArray,	// CFArrayRef keyUsages
			keyAttrsArray	// CFArrayRef keyAttributes
		};
		status = SecItemImport(p12DataRef,
			NULL, &format, &itemType, flags, &keyParams, keychain, NULL);
		CFRelease(keyUsagesArray);
		CFRelease(keyAttrsArray);
	#endif
		if (status && status != errSecDuplicateItem) { // ignore error if duplicate
			fprintf(stderr, "Unable to import test SSL identity: error %d\n", (int)status);
			goto error_exit;
		}
	}

	/* import test S/MIME signing identity */
	{
		CFDataRef p12DataRef = CFDataCreateWithBytesNoCopy(NULL, Test_smime_signonly_p12, (CFIndex)sizeof(Test_smime_signonly_p12), kCFAllocatorNull);
		SecExternalFormat format = kSecFormatPKCS12;
		SecExternalItemType itemType = kSecItemTypeAggregate;
		SecItemImportExportFlags flags = 0;
	#if 0
		/* deprecated method, using CDSA constants */
		SecKeyImportExportParameters keyParams = {
			SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION,	// uint32_t version
			0,				// SecKeyImportExportFlags flags
			CFSTR("test"),	// CFTypeRef passphrase
			CFSTR("title"),	// CFStringRef alertTitle
			CFSTR("pw:"),	// CFStringRef alertPrompt
			NULL,			// SecAccessRef accessRef (unspecified, use default)
			CSSM_KEYUSE_SIGN,				// CSSM_KEYUSE keyUsage (0=unspecified)
			CSSM_KEYATTR_PERMANENT			// CSSM_KEYATTR_FLAGS keyAttributes
		};
		status = SecKeychainItemImport(p12DataRef,
			NULL, &format, &itemType, flags, &keyParams, keychain, NULL);
	#else
		CFTypeRef keyUsages[1] = { kSecAttrCanSign };
		CFArrayRef keyUsagesArray = CFArrayCreate(NULL, keyUsages, 1, &kCFTypeArrayCallBacks);
		CFTypeRef keyAttrs[1] = { kSecAttrIsPermanent };
		CFArrayRef keyAttrsArray = CFArrayCreate(NULL, keyAttrs, 1, &kCFTypeArrayCallBacks);
		SecItemImportExportKeyParameters keyParams = {
			SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION,	// uint32_t version
			0,				// SecKeyImportExportFlags flags
			CFSTR("test"),	// CFTypeRef passphrase
			CFSTR("title"),	// CFStringRef alertTitle
			CFSTR("pw:"),	// CFStringRef alertPrompt
			NULL,			// SecAccessRef accessRef (unspecified, use default)
			keyUsagesArray,	// CFArrayRef keyUsages
			keyAttrsArray	// CFArrayRef keyAttributes
		};
		status = SecItemImport(p12DataRef,
			NULL, &format, &itemType, flags, &keyParams, keychain, NULL);
		CFRelease(keyUsagesArray);
		CFRelease(keyAttrsArray);
	#endif
		if (status && status != errSecDuplicateItem) { // ignore error if duplicate
			fprintf(stderr, "Unable to import test S/MIME identity: error %d\n", (int)status);
			goto error_exit;
		}
	}
	
	/* import expired SSL identity */
	{
		CFDataRef p12DataRef = CFDataCreateWithBytesNoCopy(NULL, TestIDSSL2007_p12, (CFIndex)sizeof(TestIDSSL2007_p12), kCFAllocatorNull);
		SecExternalFormat format = kSecFormatPKCS12;
		SecExternalItemType itemType = kSecItemTypeAggregate;
		SecItemImportExportFlags flags = 0;
		CFTypeRef keyUsages[1] = { kSecAttrCanSign };
		CFArrayRef keyUsagesArray = CFArrayCreate(NULL, keyUsages, 1, &kCFTypeArrayCallBacks);
		CFTypeRef keyAttrs[1] = { kSecAttrIsPermanent };
		CFArrayRef keyAttrsArray = CFArrayCreate(NULL, keyAttrs, 1, &kCFTypeArrayCallBacks);
		SecItemImportExportKeyParameters keyParams = {
			SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION,	// uint32_t version
			0,				// SecKeyImportExportFlags flags
			CFSTR("test"),	// CFTypeRef passphrase
			CFSTR("title"),	// CFStringRef alertTitle
			CFSTR("pw:"),	// CFStringRef alertPrompt
			NULL,			// SecAccessRef accessRef (unspecified, use default)
			keyUsagesArray,	// CFArrayRef keyUsages
			keyAttrsArray	// CFArrayRef keyAttributes
		};
		status = SecItemImport(p12DataRef,
			NULL, &format, &itemType, flags, &keyParams, keychain, NULL);
		CFRelease(keyUsagesArray);
		CFRelease(keyAttrsArray);
		if (status && status != errSecDuplicateItem) { // ignore error if duplicate
			fprintf(stderr, "Unable to import TestIDSSL2007_p12 identity: error %d\n", (int)status);
			goto error_exit;
		}
	}

	/* import expired S/MIME identity */
	{
		CFDataRef p12DataRef = CFDataCreateWithBytesNoCopy(NULL, TestIDSMIME2007_p12, (CFIndex)sizeof(TestIDSMIME2007_p12), kCFAllocatorNull);
		SecExternalFormat format = kSecFormatPKCS12;
		SecExternalItemType itemType = kSecItemTypeAggregate;
		SecItemImportExportFlags flags = 0;
		CFTypeRef keyUsages[1] = { kSecAttrCanSign };
		CFArrayRef keyUsagesArray = CFArrayCreate(NULL, keyUsages, 1, &kCFTypeArrayCallBacks);
		CFTypeRef keyAttrs[1] = { kSecAttrIsPermanent };
		CFArrayRef keyAttrsArray = CFArrayCreate(NULL, keyAttrs, 1, &kCFTypeArrayCallBacks);
		SecItemImportExportKeyParameters keyParams = {
			SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION,	// uint32_t version
			0,				// SecKeyImportExportFlags flags
			CFSTR("test"),	// CFTypeRef passphrase
			CFSTR("title"),	// CFStringRef alertTitle
			CFSTR("pw:"),	// CFStringRef alertPrompt
			NULL,			// SecAccessRef accessRef (unspecified, use default)
			keyUsagesArray,	// CFArrayRef keyUsages
			keyAttrsArray	// CFArrayRef keyAttributes
		};
		status = SecItemImport(p12DataRef,
			NULL, &format, &itemType, flags, &keyParams, keychain, NULL);
		CFRelease(keyUsagesArray);
		CFRelease(keyAttrsArray);
		if (status && status != errSecDuplicateItem) { // ignore error if duplicate
			fprintf(stderr, "Unable to import TestIDSMIME2007_p12 identity: error %d\n", (int)status);
			goto error_exit;
		}
	}
	
	/* add generic password items */
	status = SecKeychainAddGenericPassword(keychain,
		strlen("Test Service 42"), "Test Service 42",
		strlen("nobody"), "nobody",
		strlen("weakpass"), "weakpass",
		NULL);
	if (status && status != errSecDuplicateItem) { // ignore error if duplicate
		fprintf(stderr, "Unable to add \"Test Service 42\" generic password: error %d\n", (int)status);
		goto error_exit;
	}
	status = SecKeychainAddGenericPassword(keychain,
		strlen("Test Service 69"), "Test Service 69",
		strlen("nobody"), "nobody",
		strlen("weakpass"), "weakpass",
		NULL);
	if (status && status != errSecDuplicateItem) { // ignore error if duplicate
		fprintf(stderr, "Unable to add \"Test Service 69\" generic password: error %d\n", (int)status);
		goto error_exit;
	}
	
	/* add internet password items */
	status = SecKeychainAddInternetPassword(keychain,
		strlen("test1.subdomain.apple.com"), "test1.subdomain.apple.com",
		0, NULL,
		strlen("nobody"), "nobody",
		0, NULL,
		80, kSecProtocolTypeHTTP, kSecAuthenticationTypeDefault,
		strlen("weakpass"), "weakpass",
		NULL);
	if (status && status != errSecDuplicateItem) { // ignore error if duplicate
		fprintf(stderr, "Unable to add \"test1.subdomain.apple.com\" internet password: error %d\n", (int)status);
		goto error_exit;
	}
	status = SecKeychainAddInternetPassword(keychain,
		strlen("test2.subdomain.apple.com"), "test2.subdomain.apple.com",
		0, NULL,
		strlen("nobody"), "nobody",
		0, NULL,
		443, kSecProtocolTypeHTTPS, kSecAuthenticationTypeDefault,
		strlen("weakpass"), "weakpass",
		NULL);
	if (status && status != errSecDuplicateItem) { // ignore error if duplicate
		fprintf(stderr, "Unable to add \"test2.subdomain.apple.com\" internet password: error %d\n", (int)status);
		goto error_exit;
	}

	/* add a Mail password */
	status = SecKeychainAddInternetPassword(keychain,
		strlen("mail.apple.com"), "mail.apple.com",
		0, NULL,
		strlen("testacct"), "testacct",
		0, NULL,
		143, kSecProtocolTypeIMAP, kSecAuthenticationTypeDefault,
		strlen("testpass"), "testpass",
		NULL);
	if (status && status != errSecDuplicateItem) { // ignore error if duplicate
		fprintf(stderr, "Unable to add \"mail.apple.com\" internet password: error %d\n", (int)status);
		goto error_exit;
	}

	/* if an item was already in the keychain from a previous run, we can ignore the error */
	if (status == errSecDuplicateItem)
		status = noErr;

error_exit:

	if (keychain) CFRelease(keychain);
	PrintTestResult("TestAddItems", status, noErr);
	
	return (int)status;
}


int CheckResults(CFTypeRef results, CFIndex minMatchesExpected, CFIndex maxMatchesExpected)
{
	OSStatus status = noErr;
	if (debug) {
		PrintCFThing(results);
	}
	if (minMatchesExpected > 0) {
		CFIndex matchesFound;
		if (CFGetTypeID(results) == CFArrayGetTypeID()) {
			// multiple items returned as an array
			matchesFound = CFArrayGetCount(results);
		}
		else {
			// single item returned as either a dictionary or an item reference
			matchesFound = (results) ? 1 : 0;
		}
		if (debug) {
			fprintf(stdout, "### Items matched: %d (minimum expected: %d",
					(int)matchesFound, (int)minMatchesExpected);
			if (maxMatchesExpected < MAXITEMS)
				fprintf(stdout, ", maximum expected: %d", (int)minMatchesExpected);
			fprintf(stdout, ")\n");
			fflush(stdout);
		}
		if (matchesFound < minMatchesExpected ||
			matchesFound > maxMatchesExpected) {
			/* should not happen, unless SecItemCopyMatching has a bug */
			status = errSecInternalError;
		}
	}
	return (int)status;
}


#pragma mark -- Individual Test Cases --


int FindCertificateByEmail(CFStringRef emailStr,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);

	/* set up the query */
	CFDictionaryAddValue( query, kSecClass, kSecClassCertificate );
	CFDictionaryAddValue( query, kSecMatchEmailAddressIfPresent, emailStr );
	CFDictionaryAddValue( query, kSecMatchLimit, matchLimit );
	CFDictionaryAddValue( query, returnType, kCFBooleanTrue );

	CFTypeRef results = NULL;
	if (debug) {
		PrintStringToMatch(emailStr);
	}

	OSStatus status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);

	PrintTestResult("FindCertificateByEmail", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindCertificateByLabel(CFStringRef labelStr,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	CFIndex maxMatchesExpected,
	OSStatus expected)
{
	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);

	/* set up the query */
	CFDictionaryAddValue( query, kSecClass, kSecClassCertificate );
	CFDictionaryAddValue( query, kSecAttrLabel, labelStr );
	CFDictionaryAddValue( query, kSecMatchLimit, matchLimit );
	CFDictionaryAddValue( query, returnType, kCFBooleanTrue );

	CFTypeRef results = NULL;
	if (debug) {
		PrintStringToMatch(labelStr);
	}

	OSStatus status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, maxMatchesExpected);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);
	
	PrintTestResult("FindCertificateByLabel", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindCertificateByNameInSubject(CFStringRef nameStr,
	CFTypeRef matchType,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);

	/* set up the query */
	CFDictionaryAddValue( query, kSecClass, kSecClassCertificate );
	CFDictionaryAddValue( query, matchType, nameStr );
	CFDictionaryAddValue( query, kSecMatchLimit, matchLimit );
	CFDictionaryAddValue( query, returnType, kCFBooleanTrue );

	CFTypeRef results = NULL;
	if (debug) {
		PrintStringToMatch(nameStr);
	}

	OSStatus status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);

	PrintTestResult("FindCertificateByNameInSubject", status, expected);

	return (status==expected) ? (int)noErr : (int)status;
}


int FindCertificateByNameAndPolicy(CFStringRef nameStr,
	CFTypeRef policyIdentifier,
	Boolean isClientPolicy,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	/* given the policy OID, create a SecPolicyRef */
	SecPolicyRef policy = SecPolicyCreateWithOID(policyIdentifier);
	if (policy == NULL)
		return errSecPolicyNotFound;
	if (isClientPolicy == TRUE) {
		/* specify the kSecPolicyClient property key for this policy */
		const void *keys[] = { kSecPolicyClient };
		const void *values[] = { kCFBooleanTrue };
		CFDictionaryRef properties = CFDictionaryCreate(NULL, keys, values,
			sizeof(keys) / sizeof(*keys),
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);
		SecPolicySetProperties(policy, properties);
	}

	const void *keys[] = {
		kSecClass,
		kSecMatchSubjectContains,
		kSecMatchPolicy,
		kSecMatchLimit,
		returnType
	};
	const void *values[] = {
		kSecClassCertificate,
		nameStr,
		policy,
		matchLimit,
		kCFBooleanTrue
	};

	OSStatus status = noErr;
	CFTypeRef results = NULL;
	CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
		sizeof(keys) / sizeof(*keys),
		&kCFTypeDictionaryKeyCallBacks,
		&kCFTypeDictionaryValueCallBacks);

	if (debug) {
		PrintStringToMatch(nameStr);
		PrintStringToMatch(CFCopyDescription(policyIdentifier));
	}

	status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);
	if (policy)
		CFRelease(policy);
	
	PrintTestResult("FindCertificateByNameAndPolicy", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindCertificateByNameAndValidDate(CFStringRef nameStr,
	CFTypeRef validOnDate,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);

	/* set up the query */
	CFDictionaryAddValue( query, kSecClass, kSecClassCertificate );
	CFDictionaryAddValue( query, kSecMatchSubjectContains, nameStr );
	CFDictionaryAddValue( query, kSecMatchValidOnDate, validOnDate ); // value may be a CFDateRef or a CFNullRef
	CFDictionaryAddValue( query, kSecMatchLimit, matchLimit );
	CFDictionaryAddValue( query, returnType, kCFBooleanTrue );

	CFTypeRef results = NULL;
	if (debug) {
		PrintStringToMatch(nameStr);
		PrintStringToMatch(CFCopyDescription(validOnDate));
	}

	OSStatus status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);
	
	PrintTestResult("FindCertificateByNameAndValidDate", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindCertificateForSMIMEEncryption(CFStringRef emailAddr,
	CFTypeRef validOnDate,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	/* create a SecPolicyRef for S/MIME */
	SecPolicyRef policy = SecPolicyCreateWithOID(kSecPolicyAppleSMIME);
	if (policy == NULL)
		return errSecPolicyNotFound;

	CFMutableDictionaryRef properties = CFDictionaryCreateMutable(NULL, 0,
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);

	/* property 1: must match email address */
	CFDictionaryAddValue( properties, kSecPolicyName, emailAddr );
	/* property 2: must have "key encipherment" key usage to be used for encryption */
	CFDictionaryAddValue( properties, kSecPolicyKU_KeyEncipherment, kCFBooleanTrue );

	SecPolicySetProperties(policy, properties);

	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);

	/* set up the query */
	CFDictionaryAddValue( query, kSecClass, kSecClassCertificate );
	CFDictionaryAddValue( query, kSecMatchPolicy, policy );
	CFDictionaryAddValue( query, kSecMatchValidOnDate, validOnDate );
	CFDictionaryAddValue( query, kSecMatchLimit, matchLimit );
	CFDictionaryAddValue( query, returnType, kCFBooleanTrue );

	CFTypeRef results = NULL;
	if (debug) {
		PrintStringToMatch(emailAddr);
		PrintStringToMatch(CFCopyDescription(kSecPolicyAppleSMIME));
		PrintStringToMatch(CFCopyDescription(validOnDate));
	}

	OSStatus status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);
	if (policy)
		CFRelease(policy);
	if (properties)
		CFRelease(properties);
	
	PrintTestResult("FindCertificateForSMIMEEncryption", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindPreferredCertificateForSMIMEEncryption(CFStringRef emailAddr,
	CFTypeRef validOnDate)
{
	// Note: this function assumes that a preferred certificate has been set up
	// previously for the given email address. This is handled in the calling
	// function.

	OSStatus status = noErr;
	SecCertificateRef preferredCertificate = NULL;
	SecCertificateRef validatedCertificate = NULL;

	// Pass an explicit key usage value to SecCertificateCopyPreferred to test <rdar://8192797>
	CFArrayRef keyUsage = CFArrayCreate(kCFAllocatorDefault, (const void **)&kSecAttrCanEncrypt, 1, &kCFTypeArrayCallBacks);

	preferredCertificate = SecCertificateCopyPreferred(emailAddr, keyUsage);
	if (!preferredCertificate)
		status = errSecItemNotFound; // our test expects a preferred certificate to exist, so we return an error
	if (keyUsage)
		CFRelease(keyUsage);

	if (!status && preferredCertificate) {
		// We found a preferred certificate, but it may have expired.
		// Verify the preferred certificate by looking up all certificates which
		// are valid for SMIME encryption, and using the kSecMatchItemList query
		// parameter to filter out everything but our preferred certificate. If
		// we end up with 0 results, the preferred certificate wasn't valid.

		// set up the S/MIME policy first to check for the Key Encipherment key usage (needed for encryption)
		SecPolicyRef policy = SecPolicyCreateWithOID(kSecPolicyAppleSMIME);
		CFDictionaryRef properties = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&kSecPolicyKU_KeyEncipherment, (const void **)&kCFBooleanTrue, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
		status = SecPolicySetProperties(policy, properties);
		CFRelease(properties);
		
		// set up an item list consisting of just our preferred certificate
		CFArrayRef itemList = CFArrayCreate(kCFAllocatorDefault, (const void **)&preferredCertificate, 1, &kCFTypeArrayCallBacks);

		// set up the query
		CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
		CFDictionaryAddValue( query, kSecClass, kSecClassCertificate );
		CFDictionaryAddValue( query, kSecMatchPolicy, policy );
		CFDictionaryAddValue( query, kSecMatchValidOnDate, validOnDate );
		CFDictionaryAddValue( query, kSecMatchItemList, itemList );
		CFDictionaryAddValue( query, kSecMatchLimit, kSecMatchLimitOne ); // only need to match one item!
		CFDictionaryAddValue( query, kSecReturnRef, kCFBooleanTrue );

		if (debug) {
			PrintStringToMatch(emailAddr);
			PrintStringToMatch(CFCopyDescription(validOnDate));
		}

		status = SecItemCopyMatching(query, (CFTypeRef*)&validatedCertificate);

		if (!status && validatedCertificate) {
			status = CheckResults(validatedCertificate, 1, 1); // expect exactly 1 result
			CFRelease(validatedCertificate);
		}
		if (query)
			CFRelease(query);
		if (policy)
			CFRelease(policy);
		if (itemList)
			CFRelease(itemList);
	}
	else if (!quiet)
		fprintf(stderr, "FindPreferredCertificateForSMIMEEncryption: unexpected error %d\n", (int)status);

	if (preferredCertificate)
		CFRelease(preferredCertificate);
	
	PrintTestResult("FindPreferredCertificateForSMIMEEncryption", status, noErr);
	
	return (status==noErr) ? (int)noErr : (int)status;
}


int SetPreferredCertificateForSMIMEEncryption(CFStringRef nameStr,
	CFStringRef emailAddr)
{
	// find the certificate exactly matching the given common name
	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);

	CFDictionaryAddValue( query, kSecClass, kSecClassCertificate );
	CFDictionaryAddValue( query, kSecMatchSubjectWholeString, nameStr );
	CFDictionaryAddValue( query, kSecMatchLimit, kSecMatchLimitOne );
	CFDictionaryAddValue( query, kSecReturnRef, kCFBooleanTrue );

	CFTypeRef results = NULL;
	OSStatus status = SecItemCopyMatching(query, &results);
	
	if (!quiet && status)
		fprintf(stderr, "SetPreferredCertificateForSMIMEEncryption: SecItemCopyMatching error %d\n", (int)status);
	
	if (!status && results) {
		// since we asked for kSecMatchLimitOne, the result is a single item
		SecCertificateRef certificate = (SecCertificateRef) results;
		if (SecCertificateGetTypeID() != CFGetTypeID(certificate)) {
			fprintf(stderr, "SetPreferredCertificateForSMIMEEncryption: unexpected result type!\n");
		}
		else {
			// Pass an explicit key usage value to SecCertificateSetPreferred to test <rdar://8192797>
			CFArrayRef keyUsage = CFArrayCreate(kCFAllocatorDefault, (const void **)&kSecAttrCanEncrypt, 1, &kCFTypeArrayCallBacks);
			status = SecCertificateSetPreferred(certificate, emailAddr, keyUsage);
			if (!quiet && status)
				fprintf(stderr, "SetPreferredCertificateForSMIMEEncryption: SecCertificateSetPreferred error %d\n", (int)status);
			if (keyUsage)
				CFRelease(keyUsage);
		}
		CFRelease(results);
	}
	if (query)
		CFRelease(query);

	return (status==noErr) ? (int)noErr : (int)status;
}


int FindIdentityByName(CFStringRef nameStr,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	const void *keys[] = {
		kSecClass,
		kSecMatchSubjectContains,
		kSecMatchLimit,
		returnType
	};
	const void *values[] = {
		kSecClassIdentity,
		nameStr,
		matchLimit,
		kCFBooleanTrue
	};

	OSStatus status = noErr;
	CFTypeRef results = NULL;
	CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
		sizeof(keys) / sizeof(*keys),
		&kCFTypeDictionaryKeyCallBacks,
		&kCFTypeDictionaryValueCallBacks);

	if (debug) PrintStringToMatch(nameStr);

	status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);

	PrintTestResult("FindIdentityByName", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindIdentityByPolicy(CFTypeRef policyIdentifier,
	Boolean isClientPolicy,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	/* given the policy OID, create a SecPolicyRef */
	SecPolicyRef policy = SecPolicyCreateWithOID(policyIdentifier);
	if (policy == NULL)
		return errSecPolicyNotFound;
	if (isClientPolicy == TRUE) {
		/* specify the kSecPolicyClient property key for this policy */
		const void *keys[] = { kSecPolicyClient };
		const void *values[] = { kCFBooleanTrue };
		CFDictionaryRef properties = CFDictionaryCreate(NULL, keys, values,
			sizeof(keys) / sizeof(*keys),
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);
		SecPolicySetProperties(policy, properties);
	}

	const void *keys[] = {
		kSecClass,
		kSecMatchPolicy,
		kSecMatchLimit,
		returnType
	};
	const void *values[] = {
		kSecClassIdentity,
		policy,
		matchLimit,
		kCFBooleanTrue
	};

	OSStatus status = noErr;
	CFTypeRef results = NULL;
	CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
		sizeof(keys) / sizeof(*keys),
		&kCFTypeDictionaryKeyCallBacks,
		&kCFTypeDictionaryValueCallBacks);

	if (debug) PrintStringToMatch(CFCopyDescription(policyIdentifier));

	status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);
	if (policy)
		CFRelease(policy);
	
	PrintTestResult("FindIdentityByPolicy", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindIdentityByPolicyAndValidDate(CFTypeRef policyIdentifier,
	Boolean isClientPolicy,
	CFTypeRef validOnDate,
	CFStringRef forbidStr,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	/* given the policy OID, create a SecPolicyRef */
	SecPolicyRef policy = SecPolicyCreateWithOID(policyIdentifier);
	if (policy == NULL)
		return errSecPolicyNotFound;
	if (isClientPolicy == TRUE) {
		/* specify the kSecPolicyClient property key for this policy */
		const void *keys[] = { kSecPolicyClient };
		const void *values[] = { kCFBooleanTrue };
		CFDictionaryRef properties = CFDictionaryCreate(NULL, keys, values,
			sizeof(keys) / sizeof(*keys),
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);
		SecPolicySetProperties(policy, properties);
	}

	const void *keys[] = {
		kSecClass,
		kSecMatchPolicy,
		kSecMatchValidOnDate,
		kSecMatchLimit,
		returnType
	};
	const void *values[] = {
		kSecClassIdentity,
		policy,
		validOnDate,
		matchLimit,
		kCFBooleanTrue
	};

	OSStatus status = noErr;
	CFTypeRef results = NULL;
	CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
		sizeof(keys) / sizeof(*keys),
		&kCFTypeDictionaryKeyCallBacks,
		&kCFTypeDictionaryValueCallBacks);

	if (debug) PrintStringToMatch(CFCopyDescription(policyIdentifier));

	status = SecItemCopyMatching(query, &results);
	
	// check returned items for forbidStr as a substring in the label attribute;
	// return errSecInternalError if found
	if (!status && results && forbidStr) {
		if (CFArrayGetTypeID() == CFGetTypeID(results)) {
			CFArrayRef items = (CFArrayRef) results;
			CFIndex ix, count = CFArrayGetCount(results);
			for (ix=0; ix<count; ix++) {
				CFTypeRef anItem = (CFTypeRef) CFArrayGetValueAtIndex(items, ix);
				if (anItem && CFDictionaryGetTypeID() == CFGetTypeID(anItem)) {
					CFDictionaryRef item = (CFDictionaryRef) anItem;
					CFStringRef label = NULL;
					if (CFDictionaryGetValueIfPresent(item, kSecAttrLabel, (const void **)&label) && label) {
						CFRange range = CFStringFind(label, forbidStr, 0);
						if (!(range.length < 1)) {
							status = errSecInternalError; // shouldn't have found this, but we did.
							break;
						} // found forbidStr
					} // found label attribute
				} // item is a dictionary
			} // item for-loop
		} // result is an array
	} // check forbidStr


	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);
	if (policy)
		CFRelease(policy);
	
	PrintTestResult("FindIdentityByPolicyAndValidDate", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindIdentityByNameAndValidDate(CFStringRef nameStr,
	CFTypeRef validOnDate,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);

	/* set up the query */
	CFDictionaryAddValue( query, kSecClass, kSecClassIdentity );
	CFDictionaryAddValue( query, kSecMatchSubjectContains, nameStr );
	CFDictionaryAddValue( query, kSecMatchValidOnDate, validOnDate ); // value may be a CFDateRef or a CFNullRef
	CFDictionaryAddValue( query, kSecMatchLimit, matchLimit );
	CFDictionaryAddValue( query, returnType, kCFBooleanTrue );

	CFTypeRef results = NULL;
	if (debug) {
		PrintStringToMatch(nameStr);
		PrintStringToMatch(CFCopyDescription(validOnDate));
	}

	OSStatus status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);
	
	PrintTestResult("FindIdentityByNameAndValidDate", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindPreferredIdentityForSMIMESigning(CFStringRef emailAddr,
	CFTypeRef validOnDate)
{
	// Note: this function assumes that a preferred identity has been set up
	// previously for the given email address. This is handled in the calling
	// function.

	OSStatus status = noErr;
	SecIdentityRef preferredIdentity = NULL;
	SecIdentityRef validatedIdentity = NULL;
	
	// Pass an explicit key usage value to SecIdentityCopyPreferred to test <rdar://8192797>
	CFArrayRef keyUsage = CFArrayCreate(kCFAllocatorDefault, (const void **)&kSecAttrCanSign, 1, &kCFTypeArrayCallBacks);
	
	preferredIdentity = SecIdentityCopyPreferred(emailAddr, keyUsage, NULL);
	if (!preferredIdentity)
		status = errSecItemNotFound; // our test expects a preferred identity to exist, so we return an error
	if (keyUsage)
		CFRelease(keyUsage);

	if (!status && preferredIdentity) {
		// We found a preferred identity, but it may have expired.
		// Verify the preferred identity by looking up all identities which
		// are valid for SMIME signing, and using the kSecMatchItemList query
		// parameter to filter out everything but our preferred identity. If
		// we end up with 0 results, the preferred identity wasn't valid.

		// set up the S/MIME policy first to check for Digital Signature key usage
		SecPolicyRef policy = SecPolicyCreateWithOID(kSecPolicyAppleSMIME);
		CFDictionaryRef properties = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&kSecPolicyKU_DigitalSignature, (const void **)&kCFBooleanTrue, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
		status = SecPolicySetProperties(policy, properties);
		CFRelease(properties);
		
		// set up an item list consisting of just our preferred identity
		CFArrayRef itemList = CFArrayCreate(kCFAllocatorDefault, (const void **)&preferredIdentity, 1, &kCFTypeArrayCallBacks);

		// set up the query
		CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
		CFDictionaryAddValue( query, kSecClass, kSecClassIdentity );
		CFDictionaryAddValue( query, kSecMatchPolicy, policy );
		CFDictionaryAddValue( query, kSecMatchValidOnDate, validOnDate );
		CFDictionaryAddValue( query, kSecMatchItemList, itemList );
		CFDictionaryAddValue( query, kSecMatchLimit, kSecMatchLimitOne ); // only need to match one item!
		CFDictionaryAddValue( query, kSecReturnRef, kCFBooleanTrue );

		if (debug) {
			PrintStringToMatch(emailAddr);
			PrintStringToMatch(CFCopyDescription(validOnDate));
		}

		status = SecItemCopyMatching(query, (CFTypeRef*)&validatedIdentity);

		if (!status && validatedIdentity) {
			status = CheckResults(validatedIdentity, 1, 1); // expect exactly 1 result
			CFRelease(validatedIdentity);
		}
		if (query)
			CFRelease(query);
		if (policy)
			CFRelease(policy);
		if (itemList)
			CFRelease(itemList);
	}
	else if (!quiet)
		fprintf(stderr, "FindPreferredIdentityForSMIMESigning: unexpected error %d\n", (int)status);

	if (preferredIdentity)
		CFRelease(preferredIdentity);
	
	PrintTestResult("FindPreferredIdentityForSMIMESigning", status, noErr);
	
	return (status==noErr) ? (int)noErr : (int)status;
}


int SetPreferredIdentityForSMIMESigning(CFStringRef nameStr,
	CFStringRef emailAddr)
{
	// find the identity exactly matching the given common name
	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);

	CFDictionaryAddValue( query, kSecClass, kSecClassIdentity );
	CFDictionaryAddValue( query, kSecMatchSubjectWholeString, nameStr );
	CFDictionaryAddValue( query, kSecMatchLimit, kSecMatchLimitOne );
	CFDictionaryAddValue( query, kSecReturnRef, kCFBooleanTrue );

	CFTypeRef results = NULL;
	OSStatus status = SecItemCopyMatching(query, &results);
	
	if (!quiet && status)
		fprintf(stderr, "SetPreferredIdentityForSMIMESigning: SecItemCopyMatching error %d\n", (int)status);
	
	if (!status && results) {
		// since we asked for kSecMatchLimitOne, the result is a single SecIdentityRef
		SecIdentityRef identity = (SecIdentityRef) results;
		if (SecIdentityGetTypeID() != CFGetTypeID(identity)) {
			fprintf(stderr, "SetPreferredCertificateForSMIMEEncryption: unexpected result type!\n");
		}
		else {
			// Pass an explicit key usage value to SecIdentitySetPreferred to test <rdar://8192797>
			CFArrayRef keyUsage = CFArrayCreate(kCFAllocatorDefault, (const void **)&kSecAttrCanSign, 1, &kCFTypeArrayCallBacks);
			status = SecIdentitySetPreferred(identity, emailAddr, keyUsage);
			if (!quiet && status)
				fprintf(stderr, "SetPreferredIdentityForSMIMESigning: SecIdentitySetPreferred error %d\n", (int)status);
			if (keyUsage)
				CFRelease(keyUsage);
		}
		CFRelease(results);
	}
	if (query)
		CFRelease(query);

	return (status==noErr) ? (int)noErr : (int)status;
}


int FindGenericPasswordByAccount(CFStringRef accountStr,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	const void *keys[] = {
		kSecClass,
		kSecAttrAccount,
		kSecMatchLimit,
		returnType
	};
	const void *values[] = {
		kSecClassGenericPassword,
		accountStr,
		matchLimit,
		kCFBooleanTrue
	};

	OSStatus status = noErr;
	CFTypeRef results = NULL;
	CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
		sizeof(keys) / sizeof(*keys),
		&kCFTypeDictionaryKeyCallBacks,
		&kCFTypeDictionaryValueCallBacks);

	if (debug) PrintStringToMatch(accountStr);

	status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);

	PrintTestResult("FindGenericPasswordByAccount", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindGenericPasswordByAccountAndService(CFStringRef accountStr,
	CFStringRef serviceStr,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	const void *keys[] = {
		kSecClass,
		kSecAttrAccount,
		kSecAttrService,
		kSecMatchLimit,
		returnType
	};
	const void *values[] = {
		kSecClassGenericPassword,
		accountStr,
		serviceStr,
		matchLimit,
		kCFBooleanTrue
	};

	OSStatus status = noErr;
	CFTypeRef results = NULL;
	CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
		sizeof(keys) / sizeof(*keys),
		&kCFTypeDictionaryKeyCallBacks,
		&kCFTypeDictionaryValueCallBacks);

	if (debug) {
		PrintStringToMatch(accountStr);
		PrintStringToMatch(serviceStr);
	}
	status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);

	PrintTestResult("FindGenericPasswordByAccountAndService", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindInternetPasswordByAccount(CFStringRef accountStr,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	const void *keys[] = {
		kSecClass,
		kSecAttrAccount,
		kSecMatchLimit,
		returnType
	};
	const void *values[] = {
		kSecClassInternetPassword,
		accountStr,
		matchLimit,
		kCFBooleanTrue
	};

	OSStatus status = noErr;
	CFTypeRef results = NULL;
	CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
		sizeof(keys) / sizeof(*keys),
		&kCFTypeDictionaryKeyCallBacks,
		&kCFTypeDictionaryValueCallBacks);

	if (debug) PrintStringToMatch(accountStr);

	status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);

	PrintTestResult("FindInternetPasswordByAccount", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindInternetPasswordByAccountAndServer(CFStringRef accountStr,
	CFStringRef serverStr,
	CFTypeRef returnType,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
	const void *keys[] = {
		kSecClass,
		kSecAttrAccount,
		kSecAttrServer,
		kSecMatchLimit,
		returnType
	};
	const void *values[] = {
		kSecClassInternetPassword,
		accountStr,
		serverStr,
		matchLimit,
		kCFBooleanTrue
	};

	OSStatus status = noErr;
	CFTypeRef results = NULL;
	CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
		sizeof(keys) / sizeof(*keys),
		&kCFTypeDictionaryKeyCallBacks,
		&kCFTypeDictionaryValueCallBacks);

	if (debug) {
		PrintStringToMatch(accountStr);
		PrintStringToMatch(serverStr);
	}
	status = SecItemCopyMatching(query, &results);

	if (!status && results) {
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	if (query)
		CFRelease(query);

	PrintTestResult("FindInternetPasswordByAccountAndServer", status, expected);
	
	return (status==expected) ? (int)noErr : (int)status;
}


int FindMailPassword(
	CFStringRef account,
	CFStringRef server)
{
	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);
	
	SInt16 port = 143;
	CFNumberRef portNumber = CFNumberCreate(NULL, kCFNumberSInt16Type, &port);
	
	// set up query for a Mail password (IMAP, port 143) for given account and server
	CFDictionaryAddValue( query, kSecClass, kSecClassInternetPassword );
	CFDictionaryAddValue( query, kSecAttrAccount, account );
	CFDictionaryAddValue( query, kSecAttrServer, server );
	CFDictionaryAddValue( query, kSecAttrProtocol, kSecAttrProtocolIMAP );
	CFDictionaryAddValue( query, kSecAttrPort, portNumber );
	CFDictionaryAddValue( query, kSecMatchLimit, kSecMatchLimitOne );
	CFDictionaryAddValue( query, kSecReturnData, kCFBooleanTrue );

	CFTypeRef results = NULL;
	OSStatus status = SecItemCopyMatching(query, &results);
	
	if (!quiet && status)
		fprintf(stderr, "FindMailPassword: SecItemCopyMatching error %d\n", (int)status);
	
	if (!status && results) {
		// since we asked for kSecMatchLimitOne w/kSecReturnData, the result is the found password
		CFDataRef password = (CFDataRef) results;
		if (CFDataGetTypeID() != CFGetTypeID(password)) {
			fprintf(stderr, "FindMailPassword: unexpected result type!\n");
		}
		else {
			if (debug) CFShow(password);
		}
		CFRelease(results);
	}
	if (query)
		CFRelease(query);
	if (portNumber)
		CFRelease(portNumber);

	return (status==noErr) ? (int)noErr : (int)status;
}



const CFStringRef gPrefix = CFSTR("Test Key");
const CFStringRef gLabel = CFSTR("Test AES Encryption Key");
const CFStringRef gUUID = CFSTR("550e8400-e29b-41d4-a716-446655441234");

// CreateSymmetricKey will create a new AES-128 symmetric encryption key
// with the provided label, application label, and application tag.
// Each of those attributes is optional, but only the latter two
// (application label and application tag) are considered part of the
// key's "unique" attribute set. Previously, if you attempted to create a
// key which differs only in the label attribute (but not in the other two)
// then the attempt would fail and leave a "turd" key with no label in your
// keychain: <rdar://8289559>, fixed in 11A268a.

int CreateSymmetricKey(
	CFStringRef keyLabel,
	CFStringRef keyAppLabel,
	CFStringRef keyAppTag,
	OSStatus expected)
{
    OSStatus status;
	int keySizeValue = 128;
	CFNumberRef keySize = CFNumberCreate(NULL, kCFNumberIntType, &keySizeValue);

	// get a SecKeychainRef for the keychain in which we want the key to be created
	// (this step is optional, but if omitted, the key is NOT saved in any keychain!)
    SecKeychainRef keychain = NULL;
    status = SecKeychainCopyDefault(&keychain);

	// create a SecAccessRef to set up the initial access control settings for this key
	// (this step is optional; if omitted, the creating application has access to the key)
	// note: the access descriptor should be the same string as will be used for the item's label,
	// since it's the string that is displayed by the access confirmation dialog to describe the item.
	SecAccessRef access = NULL;
	status = SecAccessCreate(gLabel, NULL, &access);

	// create a dictionary of parameters describing the key we want to create
	CFMutableDictionaryRef params = CFDictionaryCreateMutable(NULL, 0,
										&kCFTypeDictionaryKeyCallBacks,
										&kCFTypeDictionaryValueCallBacks);

	CFDictionaryAddValue( params, kSecClass, kSecClassKey );
	CFDictionaryAddValue( params, kSecUseKeychain, keychain );
	CFDictionaryAddValue( params, kSecAttrAccess, access );
	CFDictionaryAddValue( params, kSecAttrKeyClass, kSecAttrKeyClassSymmetric );
	CFDictionaryAddValue( params, kSecAttrKeyType, kSecAttrKeyTypeAES );
	CFDictionaryAddValue( params, kSecAttrKeySizeInBits, keySize );
	CFDictionaryAddValue( params, kSecAttrIsPermanent, kCFBooleanTrue );
	CFDictionaryAddValue( params, kSecAttrCanEncrypt, kCFBooleanTrue );
	CFDictionaryAddValue( params, kSecAttrCanDecrypt, kCFBooleanTrue );
	CFDictionaryAddValue( params, kSecAttrCanWrap, kCFBooleanFalse );
	CFDictionaryAddValue( params, kSecAttrCanUnwrap, kCFBooleanFalse );
	if (keyLabel)
		CFDictionaryAddValue( params, kSecAttrLabel, keyLabel );
	if (keyAppLabel)
		CFDictionaryAddValue( params, kSecAttrApplicationLabel, keyAppLabel );
	if (keyAppTag)
		CFDictionaryAddValue( params, kSecAttrApplicationTag, keyAppTag );

	// generate the key
	CFErrorRef error = NULL;
    SecKeyRef key = SecKeyGenerateSymmetric(params, &error);

	// print result and clean up
	if (debug) {
		if (key == NULL) {
			CFStringRef desc = (error) ? CFErrorCopyDescription(error) : CFRetain(CFSTR("(no result!"));
			PrintCFStringWithFormat("SecKeyGenerateSymmetric failed: %s\n", desc);
			CFRelease(desc);
		}
		else {
			CFStringRef desc = CFCopyDescription(key);
			PrintCFStringWithFormat("SecKeyGenerateSymmetric succeeded: %s\n", desc);
			CFRelease(desc);
		}
	}
	status = (error) ? (OSStatus) CFErrorGetCode(error) : noErr;
//	if (status == errSecDuplicateItem)
//		status = noErr; // it's OK if the key already exists
	
	if (key) CFRelease(key);
	if (error) CFRelease(error);
	if (params) CFRelease(params);
	if (keychain) CFRelease(keychain);
	if (access) CFRelease(access);
	
	PrintTestResult("CreateSymmetricKey", status, expected);
	
	return status;
}


int FindSymmetricKey(
	CFStringRef keyLabel,
	CFStringRef keyAppLabel,
	CFStringRef keyAppTag,
	OSStatus expected)
{
	// create a dictionary of parameters describing the key we want to find,
	// and how we want the result to be returned
	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
										&kCFTypeDictionaryKeyCallBacks,
										&kCFTypeDictionaryValueCallBacks);

	CFDictionaryAddValue( query, kSecClass, kSecClassKey );
	CFDictionaryAddValue( query, kSecAttrKeyClass, kSecAttrKeyClassSymmetric );
	CFDictionaryAddValue( query, kSecMatchLimit, kSecMatchLimitOne ); // we only want the first match
	CFDictionaryAddValue( query, kSecReturnRef, kCFBooleanTrue ); // we want the result as a SecKeyRef
	CFDictionaryAddValue( query, kSecReturnAttributes, kCFBooleanTrue ); // we also want the found item's attributes
	if (keyLabel)
		CFDictionaryAddValue( query, kSecAttrLabel, keyLabel );
	if (keyAppLabel)
		CFDictionaryAddValue( query, kSecAttrApplicationLabel, keyAppLabel );
	if (keyAppTag)
		CFDictionaryAddValue( query, kSecAttrApplicationLabel, keyAppTag );

    CFTypeRef result = NULL;
    OSStatus status = SecItemCopyMatching(query, &result);

	// print result and clean up
	if (debug) {
		if (status == noErr) {
			fprintf(stdout, "SecItemCopyMatching succeeded; found key\n");
			PrintCFThing(result);
		}
		else if (status == errSecItemNotFound) {
			fprintf(stdout, "SecItemCopyMatching: item not found\n");
		}
		else {
			fprintf(stdout, "SecItemCopyMatching: failed! (error %d)\n", (int)status);
		}
	}

	SecKeyRef key = NULL;
	if (result) {
		// since we asked for both the item reference and the item attributes,
		// we expect a dictionary to be returned...
		if (CFDictionaryGetTypeID() == CFGetTypeID(result)) {
			if (CFDictionaryGetValueIfPresent(result, kSecValueRef, (CFTypeRef*)&key))
				CFRetain(key);
		}
		CFRelease(result); // all done with result dictionary
	}

	if (key) CFRelease(key);
	if (query) CFRelease(query);
	
	PrintTestResult("FindSymmetricKey", status, expected);
	
	return status;
}


int FindAndDeleteItemsByName(
	CFStringRef nameStr,
	CFStringRef accountStr,
	CFTypeRef itemClass,
	CFTypeRef matchLimit,
	CFIndex minMatchesExpected,
	OSStatus expected)
{
 	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
			&kCFTypeDictionaryKeyCallBacks,
			&kCFTypeDictionaryValueCallBacks);

	CFTypeRef nameMatchKey;
	if (CFEqual(itemClass, kSecClassCertificate) ||
		CFEqual(itemClass, kSecClassIdentity)) {
		nameMatchKey = kSecMatchSubjectStartsWith; /* must start with nameStr */
	}
	else {
		nameMatchKey = kSecAttrLabel; /* nameStr must exactly match label */
	}

	/* set up the query */
	CFDictionaryAddValue( query, kSecClass, itemClass );
	CFDictionaryAddValue( query, nameMatchKey, nameStr);
	CFDictionaryAddValue( query, kSecMatchLimit, matchLimit);
	if (accountStr) {
		CFDictionaryAddValue( query, kSecAttrAccount, accountStr);
	}

	CFTypeRef results = NULL;
	if (debug) {
		PrintStringToMatch(nameStr);
	}

	OSStatus status = SecItemCopyMatching(query, &results);

	if (!status) {
		/* Make sure that we found the items we expected to find */
		status = CheckResults(results, minMatchesExpected, MAXITEMS);
		CFRelease(results);
	}
	
	if (!status) {
		/* OK, now the real reason we're here... the same query must work for SecItemDelete */
		status = SecItemDelete(query);

		PrintTestResult("FindAndDeleteItemsByName: deleting items", status, expected);
	}

	if (!status) {
		/* re-run the same query... should find no matching items this time */
		status = SecItemCopyMatching(query, &results);
		if (!status) {
			/* oops... we still found matches using this query */
			int count = (int)CFArrayGetCount(results);
			fprintf(stderr, "### still found %d items, expected 0\n", count);
			CFRelease(results);
		}
		PrintTestResult("FindAndDeleteItemsByName: find after delete", status, errSecItemNotFound);
		
		status = (status == errSecItemNotFound) ? expected : errSecInternalError;
	}

	if (query)
		CFRelease(query);
		
	return (status==expected) ? (int)noErr : (int)status;
}


#pragma mark -- Test Functions --


int TestIdentityLookup()
{
	int result = 0;

	// look up identity by name, want first result as a SecIdentityRef
	result += FindIdentityByName(CFSTR("Test SSL User"), kSecReturnRef, kSecMatchLimitOne, 1, noErr);

	// look up existing non-identity certificate by name, expect errSecItemNotFound error
	result += FindIdentityByName(CFSTR("Test-5685316-LEAF"), kSecReturnRef, kSecMatchLimitOne, 0, errSecItemNotFound);

	// look up non-existent identity by name, expect errSecItemNotFound error
	result += FindIdentityByName(CFSTR("myxlpytk"), kSecReturnRef, kSecMatchLimitOne, 0, errSecItemNotFound);
	
	// look up identity by policy, want first result as a SecIdentityRef (should find "Test SSL User" identity)
	result += FindIdentityByPolicy(kSecPolicyAppleSSL, TRUE, kSecReturnRef, kSecMatchLimitOne, 1, noErr);

	// look up identity by policy, want first result as a CFDictionary of attributes (should find "Test SSL User" identity)
	result += FindIdentityByPolicy(kSecPolicyAppleSSL, TRUE, kSecReturnAttributes, kSecMatchLimitOne, 1, noErr);
	
	// look up identity by policy, expect errSecItemNotFound error (this assumes no code signing identity is present!)
	result += FindIdentityByPolicy(kSecPolicyAppleCodeSigning, FALSE, kSecReturnRef, kSecMatchLimitOne, 0, errSecItemNotFound);

	// -------------------------
	// test kSecMatchValidOnDate
	// -------------------------

	// make a valid date which will match at least some identities we used to populate the keychain
	CFGregorianDate aCurrentGDate = { 2010, 7, 20, 12, 0, 0 }; // Jul 20 2010 12:00 PM
	CFDateRef aCurrentDate = CFDateCreate(kCFAllocatorDefault, CFGregorianDateGetAbsoluteTime(aCurrentGDate, NULL));
	if (FindIdentityByNameAndValidDate(CFSTR("Test SSL User"), aCurrentDate, kSecReturnRef, kSecMatchLimitAll, 1, noErr))
		++result;
	if(aCurrentDate) CFRelease(aCurrentDate);
	
	// make a date in the past which should NOT match any identities (expect errSecItemNotFound)
	CFGregorianDate aPastGDate = { 1984, 7, 20, 12, 0, 0 }; // Jul 20 1984 12:00 PM
	CFDateRef aPastDate = CFDateCreate(kCFAllocatorDefault, CFGregorianDateGetAbsoluteTime(aPastGDate, NULL));
	if (FindIdentityByNameAndValidDate(CFSTR("Test SSL User"), aPastDate, kSecReturnRef, kSecMatchLimitAll, 0, errSecItemNotFound))
		++result;
	if(aPastDate) CFRelease(aPastDate);

	// make a date in the future which should NOT match any identities yet (expect errSecItemNotFound)
	CFGregorianDate aFutureGDate = { 2034, 7, 20, 12, 0, 0 }; // Jul 20 2034 12:00 PM
	CFDateRef aFutureDate = CFDateCreate(kCFAllocatorDefault, CFGregorianDateGetAbsoluteTime(aFutureGDate, NULL));
	if (FindIdentityByNameAndValidDate(CFSTR("Test SSL User"), aFutureDate, kSecReturnRef, kSecMatchLimitAll, 0, errSecItemNotFound))
		++result;
	if(aFutureDate) CFRelease(aFutureDate);

	// make a date in the past which SHOULD match 2 identities we used to populate the keychain
	CFGregorianDate aPastValidGDate = { 2007, 12, 20, 12, 0, 0 }; // Dec 20 2007 12:00 PM
	CFDateRef aPastValidDate = CFDateCreate(kCFAllocatorDefault, CFGregorianDateGetAbsoluteTime(aPastValidGDate, NULL));
	if (FindIdentityByNameAndValidDate(CFSTR(" 2007"), aPastValidDate, kSecReturnRef, kSecMatchLimitAll, 0, noErr))
		++result;

	// test the ability of kCFNull to denote "currently valid" (should not find anything, since the " 2007" certs are expired)
	if (FindIdentityByNameAndValidDate(CFSTR(" 2007"), kCFNull, kSecReturnRef, kSecMatchLimitAll, 0, errSecItemNotFound))
		++result;
		
	// test Ian's bug: <rdar://8197632>; the 4th argument is a string which should NOT be present in any found items
	if (FindIdentityByPolicyAndValidDate(kSecPolicyAppleSMIME, FALSE, kCFNull, CFSTR(" 2007"), kSecReturnAttributes, kSecMatchLimitAll, 0, noErr))
		++result;
		
	return result;
}


int TestCertificateLookup()
{
	int result = 0;
	
	//======================================================================
	// item attribute tests (kSecItemAttr* keys)
	//======================================================================
	
	// %%%TBA: need to flesh out this section with all certificate attributes

	// ------------------------------------------
	// test kSecAttrIssuer & kSecAttrSerialNumber
	// ------------------------------------------

	// look up cert by issuer & serial
	// %%%TBA -- underlying support was added in <rdar://8131491>; need to implement these keys
	//CFDictionarySetValue(query, (const void *)kSecAttrIssuer, (const void *)nameStr);
	//CFDictionarySetValue(query, (const void *)kSecAttrSerialNumber, (const void *)nameStr);

	// -------------------------
	// test kSecAttrSubjectKeyID
	// -------------------------

	// look up cert by subject key ID
	// %%%TBA -- can we get the subject key ID from SecCertificateCopyValues??
	//CFDictionarySetValue(query, (const void *)kSecAttrSubjectKeyID, (const void *)nameStr);

	// ------------------
	// test kSecAttrLabel
	// ------------------

	// look up cert by label, want array of all results (expect only 1) as SecCertificateRef
	result += FindCertificateByLabel(CFSTR("com.apple.kerberos.kdc"),
			kSecReturnRef, kSecMatchLimitAll, 1, 1, noErr);


	//======================================================================
	// search attribute tests (kSecMatch* keys)
	//======================================================================

	// -----------------------------------
	// test kSecMatchEmailAddressIfPresent
	// -----------------------------------
	
	// look up cert by email, want first result as a SecCertificateRef
	result += FindCertificateByEmail(CFSTR("security-dev@group.apple.com"),
			kSecReturnRef, kSecMatchLimitOne, 0, noErr);

	// look up cert by email, want first result as a CFDictionaryRef of attributes
	result += FindCertificateByEmail(CFSTR("security-dev@group.apple.com"),
			kSecReturnAttributes, kSecMatchLimitOne, 0, noErr);

	// -----------------------------
	// test kSecMatchSubjectContains
	// -----------------------------

	// look up cert containing name, want array of all results (expect at least 3) as SecCertificateRef 
	result += FindCertificateByNameInSubject(CFSTR("Test-5685316"),
			kSecMatchSubjectContains, kSecReturnRef, kSecMatchLimitAll, 3, noErr);

	// look up non-existent cert by name, expect errSecItemNotFound error
	result += FindCertificateByNameInSubject(CFSTR("myxlpytk"),
			kSecMatchSubjectContains, kSecReturnRef, kSecMatchLimitOne, 0, errSecItemNotFound);

	// look up cert by name, want array of all results (expect at least 2) as CFDataRef
	result += FindCertificateByNameInSubject(CFSTR("Test-5685316"),
			kSecMatchSubjectContains, kSecReturnData, kSecMatchLimitAll, 2, noErr);

	// look up cert by name, want array of all results (expect at least 2) as CFDictionaryRef of attributes
	result += FindCertificateByNameInSubject(CFSTR("Test-5685316"),
			kSecMatchSubjectContains, kSecReturnAttributes, kSecMatchLimitAll, 2, noErr);

	// -------------------------------
	// test kSecMatchSubjectStartsWith
	// -------------------------------

	// look up cert starting with name, want array of all results (expect at least 3) as SecCertificateRef 
	result += FindCertificateByNameInSubject(CFSTR("Test-568"),
			kSecMatchSubjectStartsWith, kSecReturnRef, kSecMatchLimitAll, 3, noErr);

	// look up cert starting with a name which isn't at start, expect errSecItemNotFound error
	result += FindCertificateByNameInSubject(CFSTR("5685316"),
			kSecMatchSubjectStartsWith, kSecReturnRef, kSecMatchLimitOne, 0, errSecItemNotFound);

	// -----------------------------
	// test kSecMatchSubjectEndsWith
	// -----------------------------

	// look up cert ending with name, want array of all results (expect at least 1) as SecCertificateRef 
	result += FindCertificateByNameInSubject(CFSTR("LEAF"),
			kSecMatchSubjectEndsWith, kSecReturnRef, kSecMatchLimitAll, 1, noErr);

	// look up cert ending with a name which isn't at end, expect errSecItemNotFound error
	result += FindCertificateByNameInSubject(CFSTR("Test-"),
			kSecMatchSubjectEndsWith, kSecReturnRef, kSecMatchLimitOne, 0, errSecItemNotFound);

	// --------------------------------
	// test kSecMatchSubjectWholeString
	// --------------------------------

	// look up cert by whole name, want first result (expecting 1) as a SecCertificateRef
	result += FindCertificateByNameInSubject(CFSTR("Test-5685316-LEAF"),
			kSecMatchSubjectWholeString, kSecReturnRef, kSecMatchLimitOne, 1, noErr);

	// look up cert by whole name (which is a substring in other certs), expect errSecItemNotFound error
	result += FindCertificateByNameInSubject(CFSTR("Test-568"),
			kSecMatchSubjectWholeString, kSecReturnRef, kSecMatchLimitOne, 0, errSecItemNotFound);

	// --------------------
	// test kSecMatchPolicy
	// --------------------

	// look up cert by name and policy (Code Signing), want first result as a SecCertificateRef
	result += FindCertificateByNameAndPolicy(CFSTR("Test-7875801"),
			kSecPolicyAppleCodeSigning, FALSE,
			kSecReturnRef, kSecMatchLimitOne, 0, noErr);

	// look up cert by name and policy (S/MIME), want first result as a SecCertificateRef
	result += FindCertificateByNameAndPolicy(CFSTR("Test-"),
			kSecPolicyAppleSMIME, FALSE,
			kSecReturnRef, kSecMatchLimitOne, 0, noErr);

	// look up cert by name and policy, want array of all results as SecCertificateRef
	// (note that we expect an error here, since if all went well, there will be only 1 cert
	// matching both name and policy parameters, but we asked for a minimum of 2 matches.)
	result += FindCertificateByNameAndPolicy(CFSTR("Test-7875801"),
			kSecPolicyAppleCodeSigning, FALSE,
			kSecReturnAttributes, kSecMatchLimitAll, 2, errSecInternalError);
	
	// look up cert by email address for SMIME encryption, date valid today, want array of all results as SecCertificateRef
	// (note that a date value of kCFNull is interpreted as the current date)
	result += FindCertificateForSMIMEEncryption(CFSTR("smime-test@apple.com"), kCFNull,
			kSecReturnRef, kSecMatchLimitAll, 1, noErr);

	// -------------------------
	// test kSecMatchValidOnDate
	// -------------------------

	// make a valid date which will match at least 2 certificates we used to populate the keychain
	CFGregorianDate aCurrentGDate = { 2010, 7, 20, 12, 0, 0 }; // Jul 20 2010 12:00 PM
	CFDateRef aCurrentDate = CFDateCreate(kCFAllocatorDefault, CFGregorianDateGetAbsoluteTime(aCurrentGDate, NULL));
	if (FindCertificateByNameAndValidDate(CFSTR("Test-"), aCurrentDate, kSecReturnRef, kSecMatchLimitAll, 2, noErr))
		++result;
	if(aCurrentDate) CFRelease(aCurrentDate);
	
	// make a date in the past which should NOT match any certificates (expect errSecItemNotFound)
	CFGregorianDate aPastGDate = { 1984, 7, 20, 12, 0, 0 }; // Jul 20 1984 12:00 PM
	CFDateRef aPastDate = CFDateCreate(kCFAllocatorDefault, CFGregorianDateGetAbsoluteTime(aPastGDate, NULL));
	if (FindCertificateByNameAndValidDate(CFSTR("Test-"), aPastDate, kSecReturnRef, kSecMatchLimitAll, 2, errSecItemNotFound))
		++result;
	if(aPastDate) CFRelease(aPastDate);

	// make a date in the future which should NOT match any certificates yet (expect errSecItemNotFound)
	CFGregorianDate aFutureGDate = { 2034, 7, 20, 12, 0, 0 }; // Jul 20 2034 12:00 PM
	CFDateRef aFutureDate = CFDateCreate(kCFAllocatorDefault, CFGregorianDateGetAbsoluteTime(aFutureGDate, NULL));
	if (FindCertificateByNameAndValidDate(CFSTR("Test-"), aFutureDate, kSecReturnRef, kSecMatchLimitAll, 2, errSecItemNotFound))
		++result;
	if(aFutureDate) CFRelease(aFutureDate);

	return result;
}


int TestPreferredIdentityLookup()
{
	int result = 0;
	
	// set a preferred identity first
	if (SetPreferredIdentityForSMIMESigning(CFSTR("Test-SignOnly (S/MIME)"), CFSTR("smime-test@apple.com")))
		++result;
	
	// define a valid date for this preferred identity (typically this would just be kCFNull in a real program, meaning "now")
	CFGregorianDate aCurrentGDate = { 2010, 7, 27, 21, 0, 0 }; // Jul 27 2010 9:00 PM
	CFDateRef aCurrentDate = CFDateCreate(kCFAllocatorDefault, CFGregorianDateGetAbsoluteTime(aCurrentGDate, NULL));
	if (FindPreferredIdentityForSMIMESigning(CFSTR("smime-test@apple.com"), aCurrentDate))
		++result;
	if(aCurrentDate) CFRelease(aCurrentDate);

	// delete identity preference(s) for this email address by setting a NULL identity
	if (SecIdentitySetPreferred(NULL, CFSTR("smime-test@apple.com"), 0) != noErr)
		++result;
	
	return result;
}


int TestPreferredCertificateLookup()
{
	int result = 0;
	
	// set a preferred certificate first
	if (SetPreferredCertificateForSMIMEEncryption(CFSTR("Test-Encryption (S/MIME)"), CFSTR("smime-test@apple.com")))
		++result;
	
	// define a valid date for this preferred certificate (typically this would just be kCFNull in a real program, meaning "now")
	CFGregorianDate aCurrentGDate = { 2010, 7, 27, 21, 0, 0 }; // Jul 27 2010 9:00 PM
	CFDateRef aCurrentDate = CFDateCreate(kCFAllocatorDefault, CFGregorianDateGetAbsoluteTime(aCurrentGDate, NULL));
	if (FindPreferredCertificateForSMIMEEncryption(CFSTR("smime-test@apple.com"), aCurrentDate))
		++result;
	if(aCurrentDate) CFRelease(aCurrentDate);

	// delete certificate preference(s) for this email address by setting a NULL identity
	if (SecCertificateSetPreferred(NULL, CFSTR("smime-test@apple.com"), 0) != noErr)
		++result;

	return result;
}


int TestSymmetricKeyLookup()
{
	int result = 0;

	// look up our symmetric key by label and UUID (it might not exist yet)
	if (FindSymmetricKey(gLabel, gUUID, NULL, errSecItemNotFound) != errSecSuccess) {
		// create test key (unique by UUID only)
		if (CreateSymmetricKey(gLabel, gUUID, NULL, errSecSuccess) != errSecSuccess)
			++result;
		// look it up again (it should exist now!)
		if (FindSymmetricKey(gLabel, gUUID, NULL, errSecSuccess) != errSecSuccess)
			++result;
	}
	
	// now look up a key whose name is derived from today's date
	// (so we can make sure on a daily basis that SecKeyGenerateSymmetric is still working)
	CFGregorianDate curGDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), NULL);
	CFStringRef curDateLabel = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%4d-%02d-%02d)"),
		gPrefix, curGDate.year, curGDate.month, curGDate.day);
	//
	//%%% FIXME Creating a symmetric key with attributes that would duplicate an existing
	// key item currently results in a broken <unknown> key which can't be found: <rdar://8289559>
	//
	//CFStringRef curAppTag = curDateLabel; // i.e. make sure it will be unique, for now
	CFStringRef curAppTag = CFSTR("SecItemFind");

	// look up our date-based symmetric key by label, UUID, and tag (it might not exist yet)
	if (FindSymmetricKey(curDateLabel, gUUID, curAppTag, errSecItemNotFound) != errSecSuccess) {
		// create test key (unique by combination of UUID and application tag)
		if (CreateSymmetricKey(curDateLabel, gUUID, curAppTag, errSecSuccess) != errSecSuccess)
			++result;
		// look it up again (it should exist now!)
		if (FindSymmetricKey(curDateLabel, gUUID, curAppTag, errSecSuccess) != errSecSuccess)
			++result;
	}

	// test handling of duplicate symmetric key items (<rdar://8289559>)
	if (CreateSymmetricKey(curDateLabel, gUUID, curAppTag, errSecDuplicateItem) != errSecDuplicateItem)
		++result;

	CFRelease(curDateLabel);

	return result;
}


int TestInternetPasswordLookup()
{
	int result = 0;

	// look up internet password by account and server, want first result as data
	if (FindInternetPasswordByAccountAndServer(CFSTR("nobody"),
			CFSTR("test2.subdomain.apple.com"), kSecReturnData, kSecMatchLimitOne, 1, noErr))
		++result;

	// look up internet password by account and server, want dictionary of the item's attributes
	if (FindInternetPasswordByAccountAndServer(CFSTR("nobody"),
			CFSTR("test2.subdomain.apple.com"), kSecReturnAttributes, kSecMatchLimitOne, 1, noErr))
		++result;

	// look up internet passwords by account, want array of SecKeychainItemRef results
	if (FindInternetPasswordByAccount(CFSTR("nobody"),
			kSecReturnRef, kSecMatchLimitAll, 1, noErr))
		++result;
	
	// look up a Mail password for an IMAP account, replacing SecKeychainFindInternetPassword
	// (see <rdar://8347516>)
	if (FindMailPassword(CFSTR("testacct"), CFSTR("mail.apple.com")))
		++result;

	return result;
}


int TestGenericPasswordLookup()
{
	int result = 0;

	// look up generic password by account and service, want first result as data
	if (FindGenericPasswordByAccountAndService(CFSTR("nobody"),
			CFSTR("Test Service 42"), kSecReturnData, kSecMatchLimitOne, 1, noErr))
		++result;

	// look up generic password by account and service, dictionary of the item's attributes
	if (FindGenericPasswordByAccountAndService(CFSTR("nobody"),
			CFSTR("Test Service 42"), kSecReturnAttributes, kSecMatchLimitOne, 1, noErr))
		++result;

	// look up generic passwords by account, want array of SecKeychainItemRef results
	if (FindGenericPasswordByAccount(CFSTR("nobody"),
			kSecReturnRef, kSecMatchLimitAll, 1, noErr))
		++result;

	return result;
}


int TestUpdateItems()
{
	int result = 0;

	// test for <rdar://8658820>
	// create a new 1024-bit RSA key pair
	SecKeyRef publicKey = NULL;
	SecKeyRef privateKey = NULL;
	CFMutableDictionaryRef params = CFDictionaryCreateMutable(NULL, 0,
		&kCFTypeDictionaryKeyCallBacks,
		&kCFTypeDictionaryValueCallBacks);
	int keySizeValue = 1024;
	CFNumberRef keySize = CFNumberCreate(NULL, kCFNumberIntType, &keySizeValue);
	CFStringRef keyLabel = CFSTR("AppleID 8658820 test key");
	CFDictionaryAddValue( params, kSecAttrKeyType, kSecAttrKeyTypeRSA );
	CFDictionaryAddValue( params, kSecAttrKeySizeInBits, keySize );
	CFDictionaryAddValue( params, kSecAttrLabel, keyLabel );
//	CFDictionaryAddValue( params, kSecUseKeychain, keychain );
//	CFDictionaryAddValue( params, kSecAttrAccess, access );
// %%% note that SecKeyGeneratePair will create the key pair in the default keychain
// if a keychain is not given via the kSecUseKeychain parameter.
	OSStatus status = SecKeyGeneratePair(params, &publicKey, &privateKey);
	if (status != noErr) {
		++result;
	}
	PrintTestResult("TestUpdateItems: generating key pair", status, noErr);
	
	// create a query which will match just the private key item (based on its known reference)
	CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0,
		&kCFTypeDictionaryKeyCallBacks,
		&kCFTypeDictionaryValueCallBacks);
	CFArrayRef itemList = CFArrayCreate(NULL, (const void**) &privateKey, 1, &kCFTypeArrayCallBacks);
// %%% note that kSecClass seems to be a required query parameter even though
// kSecMatchItemList is provided; that looks like it could be a bug...
	CFDictionaryAddValue( query, kSecClass, kSecClassKey );
//	CFDictionaryAddValue( query, kSecAttrKeyClass, kSecAttrKeyClassPrivate );
	CFDictionaryAddValue( query, kSecMatchItemList, itemList );

	// create dictionary of changed attributes for the private key
	CFMutableDictionaryRef attrs = CFDictionaryCreateMutable(NULL, 0,
		&kCFTypeDictionaryKeyCallBacks,
		&kCFTypeDictionaryValueCallBacks);
	SecAccessRef access = NULL;
	CFStringRef newLabel = CFSTR("AppleID 8658820 test PRIVATE key");
	status = SecAccessCreate(newLabel, NULL, &access);
	if (status != noErr) {
		++result;
	}
	PrintTestResult("TestUpdateItems: creating access", status, noErr);
//%%% note that changing the access for this key causes a dialog,
// so leave this out for the moment (uncomment to test that access change works).
// Normally the desired access should be passed into the SecKeyGeneratePair function.
// so there is no need for a dialog later.
//	CFDictionaryAddValue( attrs, kSecAttrAccess, access );
	CFDictionaryAddValue( attrs, kSecAttrLabel, newLabel );

	// update the private key with the new attributes
	status = SecItemUpdate( query, attrs );
	if (status != noErr) {
		++result;
	}
	PrintTestResult("TestUpdateItems: updating item", status, noErr);

	if (publicKey)
		CFRelease(publicKey);
	if (privateKey)
		CFRelease(privateKey);
	if (access)
		CFRelease(access);

	if (params)
		CFRelease(params);
	if (query)
		CFRelease(query);
	if (attrs)
		CFRelease(attrs);

	return result;
}


int TestDeleteItems()
{
	int result = 0;
	
	// delete our 3 test certificates that start with "Test-5685316-"
	if (FindAndDeleteItemsByName(CFSTR("Test-5685316-"), NULL, kSecClassCertificate, kSecMatchLimitAll, 3, noErr))
		++result;
	
	// delete our 2 test identities that start with "Test Identity S" (fixed by <rdar://8317856>)
	if (FindAndDeleteItemsByName(CFSTR("Test Identity S"), NULL, kSecClassIdentity, kSecMatchLimitAll, 2, noErr))
		++result;

	// delete the "Test-SignOnly (S/MIME)" identity
	if (FindAndDeleteItemsByName(CFSTR("Test-SignOnly (S/MIME)"), NULL, kSecClassIdentity, kSecMatchLimitAll, 1, noErr))
		++result;

	// delete the "Test-Encryption (S/MIME)" certificate
	if (FindAndDeleteItemsByName(CFSTR("Test-Encryption (S/MIME)"), NULL, kSecClassCertificate, kSecMatchLimitAll, 1, noErr))
		++result;

	// delete the "Test-7875801 (Code Signing)" certificate
	if (FindAndDeleteItemsByName(CFSTR("Test-7875801 (Code Signing)"), NULL, kSecClassCertificate, kSecMatchLimitAll, 1, noErr))
		++result;
	
	// delete our test passwords (no partial string matching for password items! need an ER Radar...)
	if (FindAndDeleteItemsByName(CFSTR("Test Service 42"), NULL, kSecClassGenericPassword, kSecMatchLimitAll, 1, noErr))
		++result;
	if (FindAndDeleteItemsByName(CFSTR("Test Service 69"), NULL, kSecClassGenericPassword, kSecMatchLimitAll, 1, noErr))
		++result;
	if (FindAndDeleteItemsByName(CFSTR("test1.subdomain.apple.com"), NULL, kSecClassInternetPassword, kSecMatchLimitAll, 1, noErr))
		++result;
	if (FindAndDeleteItemsByName(CFSTR("test2.subdomain.apple.com"), NULL, kSecClassInternetPassword, kSecMatchLimitAll, 1, noErr))
		++result;
	if (FindAndDeleteItemsByName(CFSTR("mail.apple.com"), CFSTR("testacct"), kSecClassInternetPassword, kSecMatchLimitAll, 1, noErr))
		++result;

	// delete our test symmetric keys (no partial string matching for key items! need an ER Radar...)
	if (FindAndDeleteItemsByName(gLabel, NULL, kSecClassKey, kSecMatchLimitAll, 1, noErr))
		++result;
	CFGregorianDate curGDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), NULL);
	CFStringRef curDateLabel = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%4d-%02d-%02d)"),
		gPrefix, curGDate.year, curGDate.month, curGDate.day);
	if (FindAndDeleteItemsByName(curDateLabel, NULL, kSecClassKey, kSecMatchLimitAll, 1, noErr))
		++result;
	CFRelease(curDateLabel);

	// delete our test asymmetric key pair (remember we renamed the private key...)
	if (FindAndDeleteItemsByName(CFSTR("AppleID 8658820 test key"), NULL, kSecClassKey, kSecMatchLimitAll, 1, noErr))
		++result;
	if (FindAndDeleteItemsByName(CFSTR("AppleID 8658820 test PRIVATE key"), NULL, kSecClassKey, kSecMatchLimitAll, 1, noErr))
		++result;

	return result;
}


void usage(const char *arg0)
{
	fprintf(stdout, "Usage: %s [-q] [-d]\n", arg0);
	fprintf(stdout, "Options:\n");
	fprintf(stdout, "  -q : (quiet) suppress output of pass/fail lines\n");
	fprintf(stdout, "  -d : (debug) show debug output\n");
}


int main (int argc, const char * argv[])
{
    int n, i, c, e;
	
	/* validate arguments */
	if (argc > 3)
	{
        usage(argv[0]);
		exit(1);
	}
	
	for (i=1; i<argc; i++)
	{
		if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "q"))
			quiet = 1;
		else if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "d"))
			debug = 1;
		else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "v"))
			verbose = 1;
		else {
			usage(argv[0]);
			exit(1);
		}
	}
	if (!quiet && !debug && !verbose) {
		fprintf(stdout, "Note: use -d and -v option flags to show debug output and verbose results\n");
	}
	
	c = 0; /* count */
	e = 0; /* errors */
	
	n = 10; /* number of tests we are doing below */
	
	plan_tests(n);
	tests_begin(argc, (char * const *) argv);

	/* run tests */
	if (!quiet) {
		fprintf(stdout, "=== Starting SecItem tests\n");
	}
	#define TEST(FUNC, NAME) { \
		if (!quiet) fprintf(stdout,"=== TEST %d: %s\n", ++c, NAME); \
		int r=FUNC; if(r) ++e; ok(!r, NAME); \
	}

	TEST( TestAddItems(), "TestAddItems" );
	TEST( TestGenericPasswordLookup(), "TestGenericPasswordLookup" );
	TEST( TestInternetPasswordLookup(), "TestInternetPasswordLookup" );
	TEST( TestSymmetricKeyLookup(), "TestSymmetricKeyLookup" );
	TEST( TestIdentityLookup(), "TestIdentityLookup" );
	TEST( TestCertificateLookup(), "TestCertificateLookup" );
	TEST( TestPreferredIdentityLookup(), "TestPreferredIdentityLookup" );
	TEST( TestPreferredCertificateLookup(), "TestPreferredCertificateLookup" );
	TEST( TestUpdateItems(), "TestUpdateItems" );
	TEST( TestDeleteItems(), "TestDeleteItems" );

	if (!quiet) {
		fprintf(stdout, "=== %d of %d tests succeeded ===\n", c-e, c);
	}
	fflush(stdout);

	tests_end(1);
	
	return (e) ? 1 : 0; 	
}