[CRYPT32_WINETEST]
[reactos.git] / rostests / winetests / crypt32 / chain.c
index a59a95a..2d209f9 100644 (file)
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
-#include <assert.h>
+
 #include <stdio.h>
-#include <stdarg.h>
+//#include <stdarg.h>
+
 #include <windef.h>
 #include <winbase.h>
-#include <winerror.h>
+//#include <winerror.h>
 #include <wincrypt.h>
+#include <wininet.h>
 
-#include "wine/test.h"
+#include <wine/test.h>
 
 static const BYTE selfSignedCert[] = {
  0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
@@ -139,175 +141,6 @@ static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
  0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
  0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
  0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
-static const BYTE iTunesCert0[] = {
-0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
-0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75,
-0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
-0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
-0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
-0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,
-0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,
-0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,
-0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,
-0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30,
-0x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,
-0x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,
-0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,
-0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
-0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b,
-0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,
-0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,
-0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,
-0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,
-0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,
-0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,
-0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,
-0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69,
-0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,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,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10,
-0x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee,
-0x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51,
-0x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24,
-0xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22,
-0x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25,
-0x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd,
-0xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63,
-0xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47,
-0x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20,
-0xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c,
-0x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d,
-0xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd,
-0x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e,
-0x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53,
-0x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70,
-0x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44,
-0x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c,
-0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
-0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,
-0x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,
-0x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
-0x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,
-0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,
-0x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24,
-0xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,
-0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,
-0x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16,
-0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b,
-0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
-0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48,
-0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06,
-0x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30,
-0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43,
-0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55,
-0x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,
-0x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06,
-0x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31,
-0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,
-0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
-0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,
-0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c,
-0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,
-0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,
-0x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6,
-0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
-0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8,
-0x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c,
-0x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68,
-0xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96,
-0xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00,
-0xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0,
-0xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3,
-0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88,
-0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f,
-0x5e,0xf6,0x7a,0xb5 };
-static const BYTE iTunesCert1[] = {
-0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
-0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6,
-0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
-0x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
-0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,
-0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,
-0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
-0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,
-0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,
-0x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,
-0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
-0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,
-0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,
-0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,
-0x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,
-0x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30,
-0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32,
-0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,
-0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
-0x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12,
-0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,
-0x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41,
-0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20,
-0x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35,
-0x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73,
-0x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
-0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64,
-0x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,
-0x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,
-0x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06,
-0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
-0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84,
-0xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49,
-0xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35,
-0x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57,
-0x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07,
-0xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd,
-0xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d,
-0x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55,
-0xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c,
-0x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30,
-0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55,
-0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03,
-0x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f,
-0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,
-0x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,
-0x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63,
-0x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39,
-0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a,
-0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68,
-0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,
-0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06,
-0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
-0x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
-0x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
-0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,
-0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06,
-0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70,
-0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,
-0x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,
-0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63,
-0x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
-0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78,
-0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,
-0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06,
-0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00,
-0x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
-0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64,
-0xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10,
-0xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35,
-0x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03,
-0x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3,
-0xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76,
-0xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40,
-0xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4,
-0xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b,
-0x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c,
-0x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d,
-0x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5,
-0x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9,
-0x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13,
-0xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64,
-0xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5,
-0xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52,
-0x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a };
 static const BYTE verisignCA[] = {
 0x30,0x82,0x02,0x3c,0x30,0x82,0x01,0xa5,0x02,0x10,0x70,0xba,0xe4,0x1d,0x10,
 0xd9,0x29,0x34,0xb6,0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,
@@ -404,6 +237,314 @@ static const BYTE google[] = {
 0xd1,0xbd,0xd7,0x95,0x22,0x43,0x7a,0x06,0x7b,0x4e,0xf6,0x37,0x8e,0xa2,0xb9,
 0xcf,0x1f,0xa5,0xd2,0xbd,0x3b,0x04,0x97,0x39,0xb3,0x0f,0xfa,0x38,0xb5,0xaf,
 0x55,0x20,0x88,0x60,0x93,0xf2,0xde,0xdb,0xff,0xdf };
+/* *.winehq.org cert */
+static const BYTE winehq_org[] = {
+0x30,0x82,0x05,0x2a,0x30,0x82,0x04,0x12,0xa0,0x03,0x02,0x01,0x02,0x02,0x03,
+0x0c,0x35,0xd0,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
+0x05,0x05,0x00,0x30,0x3c,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,
+0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x47,
+0x65,0x6f,0x54,0x72,0x75,0x73,0x74,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x14,
+0x30,0x12,0x06,0x03,0x55,0x04,0x03,0x13,0x0b,0x52,0x61,0x70,0x69,0x64,0x53,
+0x53,0x4c,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x31,0x33,0x30,0x35,0x32,0x32,
+0x30,0x33,0x35,0x36,0x30,0x39,0x5a,0x17,0x0d,0x31,0x34,0x30,0x35,0x32,0x35,
+0x30,0x37,0x33,0x34,0x31,0x34,0x5a,0x30,0x81,0xbb,0x31,0x29,0x30,0x27,0x06,
+0x03,0x55,0x04,0x05,0x13,0x20,0x30,0x6d,0x4a,0x75,0x76,0x31,0x74,0x2d,0x31,
+0x43,0x46,0x79,0x70,0x51,0x6b,0x79,0x54,0x5a,0x77,0x66,0x76,0x6a,0x48,0x48,
+0x42,0x41,0x62,0x6e,0x55,0x6e,0x64,0x47,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
+0x04,0x0b,0x13,0x0a,0x47,0x54,0x39,0x38,0x33,0x38,0x30,0x30,0x31,0x31,0x31,
+0x31,0x30,0x2f,0x06,0x03,0x55,0x04,0x0b,0x13,0x28,0x53,0x65,0x65,0x20,0x77,
+0x77,0x77,0x2e,0x72,0x61,0x70,0x69,0x64,0x73,0x73,0x6c,0x2e,0x63,0x6f,0x6d,
+0x2f,0x72,0x65,0x73,0x6f,0x75,0x72,0x63,0x65,0x73,0x2f,0x63,0x70,0x73,0x20,
+0x28,0x63,0x29,0x31,0x33,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55,0x04,0x0b,0x13,
+0x26,0x44,0x6f,0x6d,0x61,0x69,0x6e,0x20,0x43,0x6f,0x6e,0x74,0x72,0x6f,0x6c,
+0x20,0x56,0x61,0x6c,0x69,0x64,0x61,0x74,0x65,0x64,0x20,0x2d,0x20,0x52,0x61,
+0x70,0x69,0x64,0x53,0x53,0x4c,0x28,0x52,0x29,0x31,0x15,0x30,0x13,0x06,0x03,
+0x55,0x04,0x03,0x0c,0x0c,0x2a,0x2e,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,
+0x72,0x67,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,0xc2,0x91,0x35,0xc7,0x67,0x32,0xf1,0x66,0x12,0x38,
+0x79,0xdb,0x02,0x11,0x95,0x89,0x1b,0x4a,0x6a,0x63,0x45,0x35,0x58,0x1b,0x57,
+0x8d,0xec,0x19,0x88,0xf5,0xa3,0x9e,0x6b,0xdb,0x07,0xfb,0x6e,0x29,0xe9,0xa9,
+0x14,0x07,0x8c,0x3a,0xc1,0xd7,0x88,0xcc,0xe4,0x55,0x79,0x6e,0x97,0xe9,0x93,
+0x88,0x9a,0x89,0xf9,0x31,0x0f,0x91,0x61,0xc2,0x9c,0xae,0x59,0x25,0x93,0x9a,
+0xc8,0xf9,0x28,0x7a,0x0f,0x0f,0x89,0x9a,0xda,0x46,0xbe,0xb2,0xdc,0x90,0x5b,
+0xd8,0x87,0xda,0xda,0xce,0x70,0x70,0x95,0x43,0x51,0xa0,0x21,0x22,0x54,0xab,
+0xa7,0x09,0xe1,0x81,0x09,0x8c,0x00,0x15,0x30,0x5a,0xa7,0x61,0x77,0xba,0x48,
+0x91,0xc6,0x94,0x90,0xdd,0x1a,0xf4,0x3f,0xa6,0x8a,0xb4,0x2f,0x98,0x16,0x0d,
+0x96,0x9f,0x0c,0x96,0x01,0x15,0xbc,0x74,0x7e,0x5c,0x4e,0xe3,0x95,0xae,0x00,
+0xf5,0x5b,0x88,0x0f,0xef,0x7c,0x1f,0xab,0x22,0xfe,0x95,0x42,0x1a,0xbd,0xee,
+0x23,0xca,0x5b,0x7f,0x4a,0xb0,0xbe,0x15,0x65,0xe2,0xce,0x02,0xc4,0xf6,0xb8,
+0xf3,0xd6,0x7e,0x75,0x5e,0x63,0x47,0x5d,0xc1,0xca,0xc3,0xc4,0x4a,0xf5,0x4d,
+0x66,0x34,0x03,0xf8,0xf4,0x54,0x7d,0x6b,0x54,0x2f,0x17,0x7c,0x39,0x13,0x78,
+0x09,0x9e,0xd0,0x9c,0x51,0x02,0x11,0x9d,0xa7,0x53,0x60,0xdd,0x62,0x2b,0xee,
+0xb0,0xd1,0xf2,0x1a,0x5c,0xdc,0xa7,0x58,0xc2,0xfa,0x29,0xcf,0xf3,0xc9,0xe9,
+0xae,0xe8,0x70,0x60,0x99,0xc7,0x30,0xdd,0x1c,0xda,0x32,0xc0,0x45,0xa5,0x48,
+0xc5,0x22,0x29,0x0c,0x74,0x25,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xb3,
+0x30,0x82,0x01,0xaf,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,
+0x80,0x14,0x6b,0x69,0x3d,0x6a,0x18,0x42,0x4a,0xdd,0x8f,0x02,0x65,0x39,0xfd,
+0x35,0x24,0x86,0x78,0x91,0x16,0x30,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
+0x01,0xff,0x04,0x04,0x03,0x02,0x05,0xa0,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,
+0x04,0x16,0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x06,
+0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x23,0x06,0x03,0x55,0x1d,
+0x11,0x04,0x1c,0x30,0x1a,0x82,0x0c,0x2a,0x2e,0x77,0x69,0x6e,0x65,0x68,0x71,
+0x2e,0x6f,0x72,0x67,0x82,0x0a,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
+0x67,0x30,0x43,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3c,0x30,0x3a,0x30,0x38,0xa0,
+0x36,0xa0,0x34,0x86,0x32,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x72,0x61,0x70,
+0x69,0x64,0x73,0x73,0x6c,0x2d,0x63,0x72,0x6c,0x2e,0x67,0x65,0x6f,0x74,0x72,
+0x75,0x73,0x74,0x2e,0x63,0x6f,0x6d,0x2f,0x63,0x72,0x6c,0x73,0x2f,0x72,0x61,
+0x70,0x69,0x64,0x73,0x73,0x6c,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,
+0x1d,0x0e,0x04,0x16,0x04,0x14,0xff,0x4c,0x0f,0x46,0xb8,0x3c,0x5b,0x72,0xe4,
+0x10,0x96,0xbb,0xa7,0xbc,0x91,0xa2,0x63,0xf6,0x81,0x0a,0x30,0x0c,0x06,0x03,
+0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x02,0x30,0x00,0x30,0x78,0x06,0x08,0x2b,
+0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x6c,0x30,0x6a,0x30,0x2d,0x06,0x08,
+0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x21,0x68,0x74,0x74,0x70,0x3a,
+0x2f,0x2f,0x72,0x61,0x70,0x69,0x64,0x73,0x73,0x6c,0x2d,0x6f,0x63,0x73,0x70,
+0x2e,0x67,0x65,0x6f,0x74,0x72,0x75,0x73,0x74,0x2e,0x63,0x6f,0x6d,0x30,0x39,
+0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x2d,0x68,0x74,0x74,
+0x70,0x3a,0x2f,0x2f,0x72,0x61,0x70,0x69,0x64,0x73,0x73,0x6c,0x2d,0x61,0x69,
+0x61,0x2e,0x67,0x65,0x6f,0x74,0x72,0x75,0x73,0x74,0x2e,0x63,0x6f,0x6d,0x2f,
+0x72,0x61,0x70,0x69,0x64,0x73,0x73,0x6c,0x2e,0x63,0x72,0x74,0x30,0x4c,0x06,
+0x03,0x55,0x1d,0x20,0x04,0x45,0x30,0x43,0x30,0x41,0x06,0x0a,0x60,0x86,0x48,
+0x01,0x86,0xf8,0x45,0x01,0x07,0x36,0x30,0x33,0x30,0x31,0x06,0x08,0x2b,0x06,
+0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x25,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
+0x77,0x77,0x77,0x2e,0x67,0x65,0x6f,0x74,0x72,0x75,0x73,0x74,0x2e,0x63,0x6f,
+0x6d,0x2f,0x72,0x65,0x73,0x6f,0x75,0x72,0x63,0x65,0x73,0x2f,0x63,0x70,0x73,
+0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
+0x03,0x82,0x01,0x01,0x00,0x1b,0xa8,0x34,0xc1,0xb7,0xf3,0xbe,0xb6,0xed,0x12,
+0x85,0x58,0xe1,0x69,0x35,0x0c,0xb8,0x7e,0x38,0x11,0xb3,0xd2,0xe2,0x2e,0x52,
+0xcf,0xa6,0x39,0xe1,0x25,0x73,0xf0,0x1d,0xc9,0x54,0xa1,0xc2,0x50,0x19,0xea,
+0x68,0xeb,0x1a,0x21,0xdb,0x86,0x14,0x55,0x73,0x02,0x28,0x56,0x14,0xf7,0xf1,
+0x48,0x43,0xfb,0xd7,0xbf,0xcf,0xbb,0x20,0xc4,0x1e,0x4e,0x9a,0x7c,0xf1,0xe8,
+0x28,0x76,0xce,0xf9,0xb3,0xf0,0x6f,0x93,0x70,0x51,0xcd,0xed,0x28,0x1b,0xdd,
+0x66,0x38,0x40,0x5e,0x0b,0x13,0xaf,0x21,0xff,0x23,0xf1,0x5b,0xcd,0x32,0x43,
+0x00,0x87,0x3d,0x10,0xc6,0x6e,0xe5,0x67,0xdc,0x9f,0x44,0x12,0x94,0xb4,0x76,
+0xbd,0xd9,0x4c,0x53,0x12,0x1c,0x2e,0x2c,0x09,0x66,0x41,0x83,0x6c,0xee,0x68,
+0x98,0x38,0xd2,0xc8,0x32,0xa3,0x42,0xcf,0x1c,0xfd,0x60,0x6c,0x5d,0x4b,0x4b,
+0x6c,0xb8,0xf3,0x7e,0xc8,0x93,0x0a,0x68,0x66,0x14,0x3b,0x39,0x73,0x82,0xfe,
+0x86,0x3c,0x3d,0xb3,0xb5,0x42,0xec,0x4c,0xc6,0xe6,0xdd,0x7e,0xd7,0xb4,0x5d,
+0xeb,0x6d,0x8c,0x9e,0x29,0x95,0x99,0xb6,0x95,0x5b,0xc0,0xdd,0x46,0xdf,0xdc,
+0xf2,0x1c,0x3d,0x80,0xeb,0x14,0x3d,0xd9,0x4a,0xb4,0x6f,0x3e,0x79,0xca,0x7f,
+0xbc,0x27,0x47,0x90,0x86,0x55,0xfa,0x27,0xf5,0x35,0x3d,0x1d,0xc4,0xa8,0x55,
+0x31,0x8f,0x3a,0x76,0x8d,0x98,0x50,0xa3,0x11,0x91,0x1c,0xb0,0xa8,0x06,0xf9,
+0x22,0xb1,0xca,0x20,0x49,0xaa,0xe1,0x4d,0x41,0xf1,0x21,0xcc,0x25,0x45,0x33,
+0x4f,0x2f,0x3a,0x48,0x70,0xbb };
+/* Battle.Net's cert */
+static const BYTE battlenet[] = {
+0x30,0x82,0x03,0xd8,0x30,0x82,0x02,0xc0,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
+0x1e,0x4c,0xc1,0xf1,0xac,0xbd,0xf3,0xf5,0x96,0x05,0xbd,0x5f,0xbb,0x3f,0x75,
+0x6b,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
+0x00,0x30,0x3c,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
+0x53,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0a,0x13,0x0c,0x54,0x68,0x61,
+0x77,0x74,0x65,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x16,0x30,0x14,0x06,0x03,
+0x55,0x04,0x03,0x13,0x0d,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x53,0x53,0x4c,
+0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x31,0x30,0x30,0x38,0x32,0x36,0x30,0x30,
+0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x32,0x30,0x39,0x32,0x34,0x32,0x33,
+0x35,0x39,0x35,0x39,0x5a,0x30,0x71,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,
+0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0c,
+0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x0f,0x30,0x0d,
+0x06,0x03,0x55,0x04,0x07,0x0c,0x06,0x49,0x72,0x76,0x69,0x6e,0x65,0x31,0x25,
+0x30,0x23,0x06,0x03,0x55,0x04,0x0a,0x0c,0x1c,0x42,0x6c,0x69,0x7a,0x7a,0x61,
+0x72,0x64,0x20,0x45,0x6e,0x74,0x65,0x72,0x74,0x61,0x69,0x6e,0x6d,0x65,0x6e,
+0x74,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,
+0x03,0x0c,0x0c,0x2a,0x2e,0x62,0x61,0x74,0x74,0x6c,0x65,0x2e,0x6e,0x65,0x74,
+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,0xa8,0x27,0x24,0x42,0x24,0xc8,0xe4,0x4e,0xfa,0x12,0x53,0x78,
+0x14,0xa9,0xec,0x20,0x2d,0x79,0x07,0x55,0x36,0xad,0x04,0x8b,0xbc,0xd9,0x3b,
+0xcc,0x3e,0xae,0xa0,0x3b,0xa1,0x79,0xf9,0x03,0x20,0x3e,0xa6,0x6a,0xeb,0x8c,
+0xb1,0x45,0xcb,0x00,0x43,0x76,0x35,0x1b,0x3d,0xc9,0x4b,0xa9,0xc0,0xb6,0x32,
+0x88,0xaa,0x4c,0x2c,0x53,0xf8,0xc4,0xcf,0xee,0xee,0xef,0x28,0xdf,0x44,0xfa,
+0xa9,0x26,0xf6,0x99,0x7b,0xa4,0x7f,0xe8,0x5c,0x7f,0x59,0x51,0xe1,0x2c,0x57,
+0x2f,0x8f,0xb3,0xad,0x7b,0x88,0x50,0xbc,0x76,0xfe,0x03,0xbd,0xfd,0x11,0x5d,
+0x6e,0xbc,0x13,0x5b,0xd9,0x2e,0x38,0xc7,0x56,0x89,0x93,0x08,0xa2,0x24,0xbd,
+0x1d,0x48,0xd9,0x48,0xce,0x6e,0x12,0x4f,0x10,0x60,0x94,0x54,0xb7,0x6b,0x51,
+0xd0,0xdf,0x04,0xa8,0x16,0x39,0xcb,0xa5,0xd9,0xe7,0xb5,0xa9,0x02,0xfa,0xd3,
+0xca,0x52,0xe7,0xc8,0x45,0xf8,0x4d,0xbb,0x70,0x1a,0xfd,0xb3,0x7d,0x9c,0x77,
+0x8b,0x34,0xbe,0xd2,0xad,0xe7,0x17,0xb0,0x55,0xfa,0x1b,0x3e,0x51,0xcf,0x37,
+0xbd,0x29,0x94,0x9f,0x56,0x28,0xd1,0x9d,0xe5,0x56,0xce,0x78,0x61,0x6e,0x8b,
+0xae,0x95,0x44,0x3c,0xc8,0x54,0x48,0x78,0x1e,0x4c,0x72,0xff,0x0e,0xb9,0x14,
+0x78,0xdc,0x7c,0x2e,0x50,0x05,0xd9,0xd0,0xa5,0x97,0xf7,0xb9,0x45,0x3f,0x7e,
+0xdc,0xc6,0x4e,0x64,0x93,0x82,0xb7,0x97,0xcf,0xb1,0x7a,0x04,0xc1,0x1d,0x70,
+0xf8,0x6b,0x43,0xc4,0xd0,0xa7,0x03,0x4e,0xc9,0x14,0x90,0x4f,0x05,0xb5,0x11,
+0x36,0xc0,0xc2,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xa0,0x30,0x81,0x9d,
+0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x02,0x30,0x00,0x30,
+0x3a,0x06,0x03,0x55,0x1d,0x1f,0x04,0x33,0x30,0x31,0x30,0x2f,0xa0,0x2d,0xa0,
+0x2b,0x86,0x29,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x76,0x72,0x2d,0x6f,
+0x76,0x2d,0x63,0x72,0x6c,0x2e,0x74,0x68,0x61,0x77,0x74,0x65,0x2e,0x63,0x6f,
+0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x4f,0x56,0x2e,0x63,0x72,0x6c,0x30,
+0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16,0x30,0x14,0x06,0x08,0x2b,0x06,0x01,
+0x05,0x05,0x07,0x03,0x01,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,
+0x30,0x32,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x26,0x30,
+0x24,0x30,0x22,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x16,
+0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x74,0x68,0x61,
+0x77,0x74,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,0x5c,0x44,0xe2,
+0x2f,0x50,0x41,0xc8,0x54,0x0a,0xdd,0x2a,0xa2,0xa7,0x62,0x2d,0xc9,0xe8,0xa8,
+0xf7,0x53,0x14,0xe1,0x88,0x89,0x81,0x22,0x1b,0x82,0xb5,0xa1,0x75,0xcc,0x91,
+0x76,0x30,0x71,0xae,0x56,0x68,0xa9,0x75,0x65,0x7f,0xd8,0xc7,0xae,0x3b,0x68,
+0x66,0xd6,0x2d,0x92,0xb7,0x9b,0x28,0x59,0x98,0x89,0x29,0xf9,0x69,0xff,0xff,
+0xfa,0x4f,0x04,0x6b,0x96,0x78,0x1d,0xfe,0x67,0x78,0x33,0xd3,0xd5,0x91,0xee,
+0xa7,0x36,0xcd,0x86,0x4c,0xc6,0x08,0xf4,0x12,0x4b,0x2b,0xd2,0x95,0x6a,0x87,
+0xcd,0xe6,0x2d,0xf3,0xe0,0x8d,0x0c,0x77,0x9d,0xa0,0x2e,0xdc,0xf2,0xc1,0x06,
+0xc5,0xb0,0xd5,0xa0,0x00,0xe5,0x0e,0x53,0xad,0x04,0xc4,0xf6,0x6e,0x6b,0x7e,
+0x04,0xc2,0xea,0xaa,0xdf,0xe1,0x26,0x4a,0x14,0x33,0x03,0x77,0x15,0x5b,0x3e,
+0x41,0x22,0x5d,0xb7,0xaf,0x65,0x2f,0x46,0xbc,0x24,0xd7,0x30,0xe6,0x82,0x7d,
+0x2a,0x3b,0x81,0x04,0xa7,0xd5,0x0b,0x61,0x57,0xe0,0x91,0x04,0x6c,0xc6,0x08,
+0xbc,0xc0,0x1b,0x26,0x7f,0x69,0x22,0x69,0xd3,0x41,0x4c,0x9d,0x61,0xe0,0xfe,
+0x2b,0xd8,0x2e,0xe9,0x2d,0x72,0x30,0x68,0x81,0xa1,0x37,0x06,0xb5,0xdc,0xd3,
+0x48,0x65,0x16,0x74,0xfb,0x3c,0xb2,0x70,0xef,0x3d,0xee,0x63,0xea,0x62,0xf5,
+0xd2,0xc7,0x48,0x6a,0xb8,0x53,0xcb,0xbe,0x9a,0xeb,0xc1,0x77,0xfb,0x9b,0xec,
+0xb8,0x06,0x04,0xaa,0x23,0x2c,0x6d,0x17,0x9e,0xb9,0x6e,0xc9,0xa4,0xde,0x7e,
+0x61,0xc4,0xa7,0x45,0x68,0xf6,0x2a,0x57,0xaa,0xad,0xca,0x84,0x03 };
+static const BYTE thawte_primary_ca[] = {
+0x30,0x82,0x04,0x20,0x30,0x82,0x03,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
+0x34,0x4e,0xd5,0x57,0x20,0xd5,0xed,0xec,0x49,0xf4,0x2f,0xce,0x37,0xdb,0x2b,
+0x6d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
+0x00,0x30,0x81,0xa9,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
+0x55,0x53,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0a,0x13,0x0c,0x74,0x68,
+0x61,0x77,0x74,0x65,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x28,0x30,0x26,0x06,
+0x03,0x55,0x04,0x0b,0x13,0x1f,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
+0x74,0x69,0x6f,0x6e,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x44,
+0x69,0x76,0x69,0x73,0x69,0x6f,0x6e,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,
+0x0b,0x13,0x2f,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x74,0x68,0x61,
+0x77,0x74,0x65,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x20,0x2d,0x20,0x46,0x6f,0x72,
+0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64,0x20,0x75,0x73,0x65,
+0x20,0x6f,0x6e,0x6c,0x79,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,
+0x16,0x74,0x68,0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,
+0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x31,
+0x31,0x31,0x37,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x33,0x36,0x30,
+0x37,0x31,0x36,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xa9,0x31,0x0b,
+0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,
+0x06,0x03,0x55,0x04,0x0a,0x13,0x0c,0x74,0x68,0x61,0x77,0x74,0x65,0x2c,0x20,
+0x49,0x6e,0x63,0x2e,0x31,0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x0b,0x13,0x1f,
+0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x53,
+0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x44,0x69,0x76,0x69,0x73,0x69,0x6f,
+0x6e,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x0b,0x13,0x2f,0x28,0x63,0x29,
+0x20,0x32,0x30,0x30,0x36,0x20,0x74,0x68,0x61,0x77,0x74,0x65,0x2c,0x20,0x49,
+0x6e,0x63,0x2e,0x20,0x2d,0x20,0x46,0x6f,0x72,0x20,0x61,0x75,0x74,0x68,0x6f,
+0x72,0x69,0x7a,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6f,0x6e,0x6c,0x79,0x31,
+0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,0x16,0x74,0x68,0x61,0x77,0x74,
+0x65,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x52,0x6f,0x6f,0x74,0x20,
+0x43,0x41,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,0xac,0xa0,0xf0,0xfb,0x80,0x59,0xd4,0x9c,0xc7,0xa4,
+0xcf,0x9d,0xa1,0x59,0x73,0x09,0x10,0x45,0x0c,0x0d,0x2c,0x6e,0x68,0xf1,0x6c,
+0x5b,0x48,0x68,0x49,0x59,0x37,0xfc,0x0b,0x33,0x19,0xc2,0x77,0x7f,0xcc,0x10,
+0x2d,0x95,0x34,0x1c,0xe6,0xeb,0x4d,0x09,0xa7,0x1c,0xd2,0xb8,0xc9,0x97,0x36,
+0x02,0xb7,0x89,0xd4,0x24,0x5f,0x06,0xc0,0xcc,0x44,0x94,0x94,0x8d,0x02,0x62,
+0x6f,0xeb,0x5a,0xdd,0x11,0x8d,0x28,0x9a,0x5c,0x84,0x90,0x10,0x7a,0x0d,0xbd,
+0x74,0x66,0x2f,0x6a,0x38,0xa0,0xe2,0xd5,0x54,0x44,0xeb,0x1d,0x07,0x9f,0x07,
+0xba,0x6f,0xee,0xe9,0xfd,0x4e,0x0b,0x29,0xf5,0x3e,0x84,0xa0,0x01,0xf1,0x9c,
+0xab,0xf8,0x1c,0x7e,0x89,0xa4,0xe8,0xa1,0xd8,0x71,0x65,0x0d,0xa3,0x51,0x7b,
+0xee,0xbc,0xd2,0x22,0x60,0x0d,0xb9,0x5b,0x9d,0xdf,0xba,0xfc,0x51,0x5b,0x0b,
+0xaf,0x98,0xb2,0xe9,0x2e,0xe9,0x04,0xe8,0x62,0x87,0xde,0x2b,0xc8,0xd7,0x4e,
+0xc1,0x4c,0x64,0x1e,0xdd,0xcf,0x87,0x58,0xba,0x4a,0x4f,0xca,0x68,0x07,0x1d,
+0x1c,0x9d,0x4a,0xc6,0xd5,0x2f,0x91,0xcc,0x7c,0x71,0x72,0x1c,0xc5,0xc0,0x67,
+0xeb,0x32,0xfd,0xc9,0x92,0x5c,0x94,0xda,0x85,0xc0,0x9b,0xbf,0x53,0x7d,0x2b,
+0x09,0xf4,0x8c,0x9d,0x91,0x1f,0x97,0x6a,0x52,0xcb,0xde,0x09,0x36,0xa4,0x77,
+0xd8,0x7b,0x87,0x50,0x44,0xd5,0x3e,0x6e,0x29,0x69,0xfb,0x39,0x49,0x26,0x1e,
+0x09,0xa5,0x80,0x7b,0x40,0x2d,0xeb,0xe8,0x27,0x85,0xc9,0xfe,0x61,0xfd,0x7e,
+0xe6,0x7c,0x97,0x1d,0xd5,0x9d,0x02,0x03,0x01,0x00,0x01,0xa3,0x42,0x30,0x40,
+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,0x01,0x06,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0x7b,
+0x5b,0x45,0xcf,0xaf,0xce,0xcb,0x7a,0xfd,0x31,0x92,0x1a,0x6a,0xb6,0xf3,0x46,
+0xeb,0x57,0x48,0x50,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
+0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x79,0x11,0xc0,0x4b,0xb3,0x91,
+0xb6,0xfc,0xf0,0xe9,0x67,0xd4,0x0d,0x6e,0x45,0xbe,0x55,0xe8,0x93,0xd2,0xce,
+0x03,0x3f,0xed,0xda,0x25,0xb0,0x1d,0x57,0xcb,0x1e,0x3a,0x76,0xa0,0x4c,0xec,
+0x50,0x76,0xe8,0x64,0x72,0x0c,0xa4,0xa9,0xf1,0xb8,0x8b,0xd6,0xd6,0x87,0x84,
+0xbb,0x32,0xe5,0x41,0x11,0xc0,0x77,0xd9,0xb3,0x60,0x9d,0xeb,0x1b,0xd5,0xd1,
+0x6e,0x44,0x44,0xa9,0xa6,0x01,0xec,0x55,0x62,0x1d,0x77,0xb8,0x5c,0x8e,0x48,
+0x49,0x7c,0x9c,0x3b,0x57,0x11,0xac,0xad,0x73,0x37,0x8e,0x2f,0x78,0x5c,0x90,
+0x68,0x47,0xd9,0x60,0x60,0xe6,0xfc,0x07,0x3d,0x22,0x20,0x17,0xc4,0xf7,0x16,
+0xe9,0xc4,0xd8,0x72,0xf9,0xc8,0x73,0x7c,0xdf,0x16,0x2f,0x15,0xa9,0x3e,0xfd,
+0x6a,0x27,0xb6,0xa1,0xeb,0x5a,0xba,0x98,0x1f,0xd5,0xe3,0x4d,0x64,0x0a,0x9d,
+0x13,0xc8,0x61,0xba,0xf5,0x39,0x1c,0x87,0xba,0xb8,0xbd,0x7b,0x22,0x7f,0xf6,
+0xfe,0xac,0x40,0x79,0xe5,0xac,0x10,0x6f,0x3d,0x8f,0x1b,0x79,0x76,0x8b,0xc4,
+0x37,0xb3,0x21,0x18,0x84,0xe5,0x36,0x00,0xeb,0x63,0x20,0x99,0xb9,0xe9,0xfe,
+0x33,0x04,0xbb,0x41,0xc8,0xc1,0x02,0xf9,0x44,0x63,0x20,0x9e,0x81,0xce,0x42,
+0xd3,0xd6,0x3f,0x2c,0x76,0xd3,0x63,0x9c,0x59,0xdd,0x8f,0xa6,0xe1,0x0e,0xa0,
+0x2e,0x41,0xf7,0x2e,0x95,0x47,0xcf,0xbc,0xfd,0x33,0xf3,0xf6,0x0b,0x61,0x7e,
+0x7e,0x91,0x2b,0x81,0x47,0xc2,0x27,0x30,0xee,0xa7,0x10,0x5d,0x37,0x8f,0x5c,
+0x39,0x2b,0xe4,0x04,0xf0,0x7b,0x8d,0x56,0x8c,0x68 };
+static const BYTE thawte_ssl_ca[] = {
+0x30,0x82,0x04,0x6c,0x30,0x82,0x03,0x54,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
+0x4d,0x5f,0x2c,0x34,0x08,0xb2,0x4c,0x20,0xcd,0x6d,0x50,0x7e,0x24,0x4d,0xc9,
+0xec,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
+0x00,0x30,0x81,0xa9,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
+0x55,0x53,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0a,0x13,0x0c,0x74,0x68,
+0x61,0x77,0x74,0x65,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x28,0x30,0x26,0x06,
+0x03,0x55,0x04,0x0b,0x13,0x1f,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,
+0x74,0x69,0x6f,0x6e,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x44,
+0x69,0x76,0x69,0x73,0x69,0x6f,0x6e,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,
+0x0b,0x13,0x2f,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x74,0x68,0x61,
+0x77,0x74,0x65,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x20,0x2d,0x20,0x46,0x6f,0x72,
+0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64,0x20,0x75,0x73,0x65,
+0x20,0x6f,0x6e,0x6c,0x79,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,
+0x16,0x74,0x68,0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,
+0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x31,0x30,0x30,
+0x32,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x32,0x30,0x30,
+0x32,0x30,0x37,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x3c,0x31,0x0b,0x30,
+0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06,
+0x03,0x55,0x04,0x0a,0x13,0x0c,0x54,0x68,0x61,0x77,0x74,0x65,0x2c,0x20,0x49,
+0x6e,0x63,0x2e,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x03,0x13,0x0d,0x54,
+0x68,0x61,0x77,0x74,0x65,0x20,0x53,0x53,0x4c,0x20,0x43,0x41,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,
+0x99,0xe4,0x85,0x5b,0x76,0x49,0x7d,0x2f,0x05,0xd8,0xc5,0xac,0xc8,0xc8,0xa9,
+0xd3,0xdc,0x98,0xe6,0xd7,0x34,0xa6,0x2f,0x0c,0xf2,0x22,0x26,0xd8,0xa3,0xc9,
+0x14,0x4c,0x8f,0x05,0xa4,0x45,0xe8,0x14,0x0c,0x58,0x90,0x05,0x1a,0xb7,0xc5,
+0xc1,0x06,0xa5,0x80,0xaf,0xbb,0x1d,0x49,0x6b,0x52,0x34,0x88,0xc3,0x59,0xe7,
+0xef,0x6b,0xc4,0x27,0x41,0x8c,0x2b,0x66,0x1d,0xd0,0xe0,0xa3,0x97,0x98,0x19,
+0x34,0x4b,0x41,0xd5,0x98,0xd5,0xc7,0x05,0xad,0xa2,0xe4,0xd7,0xed,0x0c,0xad,
+0x4f,0xc1,0xb5,0xb0,0x21,0xfd,0x3e,0x50,0x53,0xb2,0xc4,0x90,0xd0,0xd4,0x30,
+0x67,0x6c,0x9a,0xf1,0x0e,0x74,0xc4,0xc2,0xdc,0x8a,0xe8,0x97,0xff,0xc9,0x92,
+0xae,0x01,0x8a,0x56,0x0a,0x98,0x32,0xb0,0x00,0x23,0xec,0x90,0x1a,0x60,0xc3,
+0xed,0xbb,0x3a,0xcb,0x0f,0x63,0x9f,0x0d,0x44,0xc9,0x52,0xe1,0x25,0x96,0xbf,
+0xed,0x50,0x95,0x89,0x7f,0x56,0x14,0xb1,0xb7,0x61,0x1d,0x1c,0x07,0x8c,0x3a,
+0x2c,0xf7,0xff,0x80,0xde,0x39,0x45,0xd5,0xaf,0x1a,0xd1,0x78,0xd8,0xc7,0x71,
+0x6a,0xa3,0x19,0xa7,0x32,0x50,0x21,0xe9,0xf2,0x0e,0xa1,0xc6,0x13,0x03,0x44,
+0x48,0xd1,0x66,0xa8,0x52,0x57,0xd7,0x11,0xb4,0x93,0x8b,0xe5,0x99,0x9f,0x5d,
+0xe7,0x78,0x51,0xe5,0x4d,0xf6,0xb7,0x59,0xb4,0x76,0xb5,0x09,0x37,0x4d,0x06,
+0x38,0x13,0x7a,0x1c,0x08,0x98,0x5c,0xc4,0x48,0x4a,0xcb,0x52,0xa0,0xa9,0xf8,
+0xb1,0x9d,0x8e,0x7b,0x79,0xb0,0x20,0x2f,0x3c,0x96,0xa8,0x11,0x62,0x47,0xbb,
+0x11,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xfb,0x30,0x81,0xf8,0x30,0x32,0x06,
+0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x26,0x30,0x24,0x30,0x22,
+0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x16,0x68,0x74,0x74,
+0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x74,0x68,0x61,0x77,0x74,0x65,
+0x2e,0x63,0x6f,0x6d,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
+0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x00,0x30,0x34,0x06,0x03,0x55,0x1d,
+0x1f,0x04,0x2d,0x30,0x2b,0x30,0x29,0xa0,0x27,0xa0,0x25,0x86,0x23,0x68,0x74,
+0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,0x74,0x68,0x61,0x77,0x74,0x65,
+0x2e,0x63,0x6f,0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x50,0x43,0x41,0x2e,
+0x63,0x72,0x6c,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,
+0x03,0x02,0x01,0x06,0x30,0x28,0x06,0x03,0x55,0x1d,0x11,0x04,0x21,0x30,0x1f,
+0xa4,0x1d,0x30,0x1b,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,
+0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x4d,0x50,0x4b,0x49,0x2d,0x32,0x2d,
+0x39,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0xa7,0xa2,0x83,
+0xbb,0x34,0x45,0x40,0x3d,0xfc,0xd5,0x30,0x4f,0x12,0xb9,0x3e,0xa1,0x01,0x9f,
+0xf6,0xdb,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
+0x7b,0x5b,0x45,0xcf,0xaf,0xce,0xcb,0x7a,0xfd,0x31,0x92,0x1a,0x6a,0xb6,0xf3,
+0x46,0xeb,0x57,0x48,0x50,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
+0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x80,0x22,0x80,0xe0,0x6c,
+0xc8,0x95,0x16,0xd7,0x57,0x26,0x87,0xf3,0x72,0x34,0xdb,0xc6,0x72,0x56,0x27,
+0x3e,0xd3,0x96,0xf6,0x2e,0x25,0x91,0xa5,0x3e,0x33,0x97,0xa7,0x4b,0xe5,0x2f,
+0xfb,0x25,0x7d,0x2f,0x07,0x61,0xfa,0x6f,0x83,0x74,0x4c,0x4c,0x53,0x72,0x20,
+0xa4,0x7a,0xcf,0x51,0x51,0x56,0x81,0x88,0xb0,0x6d,0x1f,0x36,0x2c,0xc8,0x2b,
+0xb1,0x88,0x99,0xc1,0xfe,0x44,0xab,0x48,0x51,0x7c,0xd8,0xf2,0x44,0x64,0x2a,
+0xd8,0x71,0xa7,0xfb,0x1a,0x2f,0xf9,0x19,0x8d,0x34,0xb2,0x23,0xbf,0xc4,0x4c,
+0x55,0x1d,0x8e,0x44,0xe8,0xaa,0x5d,0x9a,0xdd,0x9f,0xfd,0x03,0xc7,0xba,0x24,
+0x43,0x8d,0x2d,0x47,0x44,0xdb,0xf6,0xd8,0x98,0xc8,0xb2,0xf9,0xda,0xef,0xed,
+0x29,0x5c,0x69,0x12,0xfa,0xd1,0x23,0x96,0x0f,0xbf,0x9c,0x0d,0xf2,0x79,0x45,
+0x53,0x37,0x9a,0x56,0x2f,0xe8,0x57,0x10,0x70,0xf6,0xee,0x89,0x0c,0x49,0x89,
+0x9a,0xc1,0x23,0xf5,0xc2,0x2a,0xcc,0x41,0xcf,0x22,0xab,0x65,0x6e,0xb7,0x94,
+0x82,0x6d,0x2f,0x40,0x5f,0x58,0xde,0xeb,0x95,0x2b,0xa6,0x72,0x68,0x52,0x19,
+0x91,0x2a,0xae,0x75,0x9d,0x4e,0x92,0xe6,0xca,0xde,0x54,0xea,0x18,0xab,0x25,
+0x3c,0xe6,0x64,0xa6,0x79,0x1f,0x26,0x7d,0x61,0xed,0x7d,0xd2,0xe5,0x71,0x55,
+0xd8,0x93,0x17,0x7c,0x14,0x38,0x30,0x3c,0xdf,0x86,0xe3,0x4c,0xad,0x49,0xe3,
+0x97,0x59,0xce,0x1b,0x9b,0x2b,0xce,0xdc,0x65,0xd4,0x0b,0x28,0x6b,0x4e,0x84,
+0x46,0x51,0x44,0xf7,0x33,0x08,0x2d,0x58,0x97,0x21,0xae };
 static const BYTE thawte_sgc_ca[] = {
 0x30,0x82,0x03,0x23,0x30,0x82,0x02,0x8c,0xa0,0x03,0x02,0x01,0x02,0x02,0x04,
 0x30,0x00,0x00,0x02,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
@@ -1273,7 +1414,7 @@ static const BYTE chain5_1[] = {
  * A chain whose end certificate is a CA.
  */
 /* chain0_0 -> chain 7_1:
- * A chain with a bad critical extension.
+ * A chain whose end cert has a bad critical extension.
  */
 static const BYTE chain7_1[] = {
 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
@@ -2503,6 +2644,103 @@ static const BYTE chain29_1[] = {
 0x3a,0xe9,0x27,0xa4,0x57,0x27,0x34,0xa7,0x42,0xde,0x78,0x1a,0x71,0x80,0x23,
 0xd6,0xd7,0x22,0xf0,0x24,0x0d,0x71,0xf1,0x2b,0xd0,0xd8,0x76,0x3d,0xef,0x4c,
 0xce,0x1c,0x3b,0x83,0x1b,0x63,0x10,0x6c,0x63,0xe5,0x69 };
+/* chain0_0 -> chain30_1 -> chain30_2
+ * A chain whose intermediate certificate has an unsupported critical
+ * extension.
+ */
+static const BYTE chain30_1[] = {
+0x30,0x82,0x01,0xc0,0x30,0x82,0x01,0x2b,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,
+0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30,
+0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,
+0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30,0x30,0x30,
+0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30,0x30,0x30,
+0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,
+0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a,
+0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
+0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,0x0e,0x67,0x5f,
+0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,0xb6,0x17,0x8e,
+0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,0x9f,0x6e,0xfe,
+0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,0xd1,0x57,0x71,
+0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,0x72,0xa7,0x87,
+0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,0x80,0x83,0x68,
+0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,0xb5,0x46,0x36,
+0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,0x51,0x9a,0x22,
+0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,0x02,0x03,0x01,
+0x00,0x01,0xa3,0x30,0x30,0x2e,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,
+0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,
+0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0b,0x06,0x02,0x2a,0x03,
+0x01,0x01,0xff,0x04,0x02,0x30,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
+0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x51,0x3e,0x35,0x1b,0x66,0x3c,
+0xca,0x5e,0xf3,0xf9,0x1b,0xd5,0x03,0x13,0xf8,0xcf,0x87,0xdf,0xed,0x75,0xa6,
+0xcd,0x4b,0x1c,0x15,0xd3,0xd8,0x58,0x85,0x85,0x2c,0x64,0x31,0xbd,0xbb,0xad,
+0xff,0x38,0x64,0xc5,0x16,0x43,0x14,0x0e,0x71,0x35,0xf3,0xe9,0xca,0xf9,0xf4,
+0x69,0xa7,0x67,0xa8,0x0f,0xc9,0xcf,0x6f,0x22,0xe5,0x39,0xb8,0xfc,0xe7,0x50,
+0x82,0xf7,0xa4,0xaa,0x29,0xe1,0xa9,0xb5,0x03,0x5e,0x0b,0x5f,0x9c,0x8e,0x29,
+0x64,0xe5,0xb6,0xed,0xde,0x04,0x0e,0xdb,0xad,0xa3,0xc6,0x2a,0xb0,0x12,0x86,
+0x60,0xd4,0xff,0xd8,0xea,0x85,0x54,0x34,0xca,0xc1,0x85,0x4e,0xb5,0x15,0x96,
+0xb7,0xa5,0x64,0x7b,0xc7,0x76,0xcb,0x04,0x75,0x9e,0x1e,0xbd,0x62,0x79,0xc5,
+0x1f,0x32 };
+static const BYTE chain30_2[] = {
+0x30,0x82,0x01,0x8d,0x30,0x81,0xf9,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
+0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30,0x10,
+0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,
+0x32,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,0x30,0x30,
+0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,
+0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,
+0x05,0x43,0x65,0x72,0x74,0x33,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a,0x86,
+0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02,
+0x81,0x81,0x00,0xc3,0x31,0x35,0xc3,0x9d,0x8a,0x87,0x20,0xc6,0x32,0xe9,0xb1,
+0xf6,0x8f,0xf9,0x05,0x73,0x1d,0xa7,0xde,0xab,0x15,0x8a,0x9c,0x7f,0x11,0x7e,
+0x77,0xa0,0x42,0x80,0xf4,0x79,0xda,0x98,0x7b,0x00,0xfa,0x8f,0x0c,0xd0,0xeb,
+0x8a,0x80,0xed,0x07,0xfc,0x64,0x71,0x03,0xc1,0xd6,0x2f,0x9b,0xde,0x42,0x63,
+0xd9,0x79,0xea,0xdd,0x10,0xe8,0x68,0xc8,0x69,0x4f,0x4a,0x39,0x23,0x87,0xca,
+0xd1,0xc9,0x77,0x14,0x30,0x85,0x9e,0xf7,0x79,0xf9,0x07,0xb7,0x7c,0x55,0xcb,
+0xa7,0xd5,0xb8,0x44,0xb5,0x20,0xb5,0x01,0x5c,0xa2,0xd1,0xd5,0xad,0x0f,0x87,
+0xaf,0x37,0xd1,0x39,0x0c,0x0d,0xd5,0xde,0x26,0x7a,0xed,0xf9,0x2a,0xb1,0x60,
+0x65,0x2d,0x08,0x24,0x51,0x1d,0xb0,0x0a,0xb5,0x13,0xc7,0x02,0x03,0x01,0x00,
+0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,
+0x81,0x81,0x00,0x14,0x75,0x85,0xcc,0x68,0xfe,0x98,0x6f,0xf6,0x67,0x00,0x5b,
+0x0c,0xfc,0x36,0x18,0xf4,0x56,0x46,0x7c,0xb9,0xfa,0x6c,0xe6,0x37,0xaf,0x69,
+0x37,0x93,0x8c,0x35,0x3a,0x1b,0x58,0x2f,0xe2,0x06,0x39,0x85,0x3f,0x73,0xcf,
+0xe1,0x3f,0x27,0x19,0x60,0xc3,0x1b,0xf6,0x69,0x3b,0x8e,0x57,0x7b,0xd8,0xb9,
+0xc6,0x9f,0x13,0x72,0x22,0x04,0x8f,0x5c,0x54,0x13,0x8c,0x63,0xe3,0x6b,0x70,
+0x98,0xec,0xcc,0xe1,0x93,0xb1,0x4b,0x30,0x4c,0xde,0xe8,0x3c,0x68,0x38,0x44,
+0x5e,0xe2,0x2b,0xf5,0xa1,0xee,0x02,0x7e,0x09,0x15,0xff,0xc9,0xf6,0xaf,0xf5,
+0xcc,0xeb,0xfc,0xe7,0x3c,0x92,0xdb,0x31,0xab,0x1e,0xb8,0x9e,0xf0,0x5e,0xa3,
+0x93,0xfe,0xab,0x26,0x7b,0x01,0xa8,0x98,0x88,0xbb,0xee };
+/* chain0_0 -> chain31_1: a chain whose end certificate has two CNs, a
+ * wildcard name "*.foo.com" and a non-wildcard name "foo.com".
+ */
+static const BYTE chain31_1[] = {
+0x30,0x82,0x01,0xa2,0x30,0x82,0x01,0x0d,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,
+0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30,
+0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,
+0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30,0x30,0x30,
+0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30,0x30,0x30,
+0x30,0x30,0x30,0x5a,0x30,0x24,0x31,0x22,0x30,0x0e,0x06,0x03,0x55,0x04,0x03,
+0x13,0x07,0x66,0x6f,0x6f,0x2e,0x63,0x6f,0x6d,0x30,0x10,0x06,0x03,0x55,0x04,
+0x03,0x13,0x09,0x2a,0x2e,0x66,0x6f,0x6f,0x2e,0x63,0x6f,0x6d,0x30,0x81,0x9d,
+0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,
+0x8d,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,
+0xe5,0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,
+0xc6,0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,
+0xa7,0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,
+0x8b,0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,
+0x6b,0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,
+0xfc,0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,
+0x85,0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,
+0xb2,0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,
+0x72,0xa3,0x02,0x03,0x01,0x00,0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
+0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0xa0,0x93,0x52,0x87,0x81,0xe2,
+0xff,0x2a,0xc7,0xef,0x5f,0x3c,0xbc,0x88,0x99,0xc0,0x47,0x3e,0x13,0xe9,0x87,
+0xfa,0x36,0xd7,0xb5,0xe8,0xdf,0x70,0xcc,0x36,0xe4,0x70,0x3c,0xcd,0xa2,0x0b,
+0x31,0x6e,0x0a,0xb9,0x00,0xf0,0x4f,0xb6,0xc2,0xce,0xf4,0x33,0x1e,0xc0,0x29,
+0xc0,0x73,0x0c,0xcf,0x28,0xa5,0x26,0x9d,0xc2,0xaf,0x85,0x30,0x81,0xbf,0xd1,
+0x70,0x3f,0x69,0x15,0xc5,0x41,0x1d,0x8e,0xd4,0xfa,0x02,0xcd,0xba,0xf1,0xf2,
+0x67,0xb5,0x45,0x29,0xad,0xe8,0x54,0x9a,0x0f,0x1a,0x8f,0xdf,0x16,0xf4,0xcb,
+0x43,0x08,0xe5,0x78,0x2b,0x95,0xf3,0x75,0xb6,0x88,0xf0,0x6b,0x5c,0x5b,0x50,
+0x04,0x91,0x3b,0x89,0x5a,0x60,0x1f,0xfc,0x36,0x53,0x32,0x36,0x0a,0x4d,0x03,
+0x2c,0xd7 };
 
 typedef struct _CONST_DATA_BLOB
 {
@@ -2566,7 +2804,9 @@ static PCCERT_CHAIN_CONTEXT getChain(HCERTCHAINENGINE engine,
             CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
             FILETIME fileTime;
 
-            SystemTimeToFileTime(checkTime, &fileTime);
+            ok(SystemTimeToFileTime(checkTime, &fileTime),
+             "SystemTimeToFileTime failed for day %d, month %d, year %d\n",
+             checkTime->wDay, checkTime->wMonth, checkTime->wYear);
             ret = pCertGetCertificateChain(engine, endCert, &fileTime,
              includeStore ? store : NULL, &chainPara, flags, NULL, &chain);
             if (todo & TODO_CHAIN)
@@ -2590,62 +2830,64 @@ typedef struct _SimpleChainStatusCheck
 
 static void checkElementStatus(const CERT_TRUST_STATUS *expected,
  const CERT_TRUST_STATUS *got, const CERT_TRUST_STATUS *ignore,
- DWORD todo, DWORD testIndex, DWORD chainIndex, DWORD elementIndex)
+ DWORD todo, LPCSTR testName, DWORD testIndex, DWORD chainIndex,
+ DWORD elementIndex)
 {
     if (got->dwErrorStatus == expected->dwErrorStatus)
         ok(got->dwErrorStatus == expected->dwErrorStatus,
-         "Chain %d, element [%d,%d]: expected error %08x, got %08x\n",
-         testIndex, chainIndex, elementIndex, expected->dwErrorStatus,
+         "%s[%d], element [%d,%d]: expected error %08x, got %08x\n",
+         testName, testIndex, chainIndex, elementIndex, expected->dwErrorStatus,
          got->dwErrorStatus);
     else if (todo & TODO_ERROR)
         todo_wine
         ok(got->dwErrorStatus == expected->dwErrorStatus ||
          broken((got->dwErrorStatus & ~ignore->dwErrorStatus) ==
          (expected->dwErrorStatus & ~ignore->dwErrorStatus)),
-         "Chain %d, element [%d,%d]: expected error %08x, got %08x\n",
-         testIndex, chainIndex, elementIndex, expected->dwErrorStatus,
+         "%s[%d], element [%d,%d]: expected error %08x, got %08x\n",
+         testName, testIndex, chainIndex, elementIndex, expected->dwErrorStatus,
          got->dwErrorStatus);
     else
         ok(got->dwErrorStatus == expected->dwErrorStatus ||
          broken((got->dwErrorStatus & ~ignore->dwErrorStatus) ==
          (expected->dwErrorStatus & ~ignore->dwErrorStatus)),
-         "Chain %d, element [%d,%d]: expected error %08x, got %08x. %08x is "
+         "%s[%d], element [%d,%d]: expected error %08x, got %08x. %08x is "
          "expected if no valid Verisign root certificate is available.\n",
-         testIndex, chainIndex, elementIndex, expected->dwErrorStatus,
+         testName, testIndex, chainIndex, elementIndex, expected->dwErrorStatus,
          got->dwErrorStatus, CERT_TRUST_IS_UNTRUSTED_ROOT);
     if (got->dwInfoStatus == expected->dwInfoStatus)
         ok(got->dwInfoStatus == expected->dwInfoStatus,
-         "Chain %d, element [%d,%d]: expected info %08x, got %08x\n",
-         testIndex, chainIndex, elementIndex, expected->dwInfoStatus,
+         "%s[%d], element [%d,%d]: expected info %08x, got %08x\n",
+         testName, testIndex, chainIndex, elementIndex, expected->dwInfoStatus,
          got->dwInfoStatus);
     else if (todo & TODO_INFO)
         todo_wine
         ok(got->dwInfoStatus == expected->dwInfoStatus ||
          broken((got->dwInfoStatus & ~ignore->dwInfoStatus) ==
          (expected->dwInfoStatus & ~ignore->dwInfoStatus)),
-         "Chain %d, element [%d,%d]: expected info %08x, got %08x\n",
-         testIndex, chainIndex, elementIndex, expected->dwInfoStatus,
+         "%s[%d], element [%d,%d]: expected info %08x, got %08x\n",
+         testName, testIndex, chainIndex, elementIndex, expected->dwInfoStatus,
          got->dwInfoStatus);
     else
         ok(got->dwInfoStatus == expected->dwInfoStatus ||
          broken((got->dwInfoStatus & ~ignore->dwInfoStatus) ==
          (expected->dwInfoStatus & ~ignore->dwInfoStatus)),
-         "Chain %d, element [%d,%d]: expected info %08x, got %08x\n",
-         testIndex, chainIndex, elementIndex, expected->dwInfoStatus,
+         "%s[%d], element [%d,%d]: expected info %08x, got %08x\n",
+         testName, testIndex, chainIndex, elementIndex, expected->dwInfoStatus,
          got->dwInfoStatus);
 }
 
 static void checkSimpleChainStatus(const CERT_SIMPLE_CHAIN *simpleChain,
  const SimpleChainStatusCheck *simpleChainStatus,
- const CERT_TRUST_STATUS *ignore, DWORD todo, DWORD testIndex, DWORD chainIndex)
+ const CERT_TRUST_STATUS *ignore, DWORD todo, LPCSTR testName, DWORD testIndex,
+ DWORD chainIndex)
 {
     if (todo & TODO_ELEMENTS)
         todo_wine ok(simpleChain->cElement == simpleChainStatus->cElement,
-         "Chain %d: expected %d elements, got %d\n", testIndex,
+         "%s[%d]: expected %d elements, got %d\n", testName, testIndex,
          simpleChainStatus->cElement, simpleChain->cElement);
     else
         ok(simpleChain->cElement == simpleChainStatus->cElement,
-         "Chain %d: expected %d elements, got %d\n", testIndex,
+         "%s[%d]: expected %d elements, got %d\n", testName, testIndex,
          simpleChainStatus->cElement, simpleChain->cElement);
     if (simpleChain->cElement == simpleChainStatus->cElement)
     {
@@ -2653,8 +2895,8 @@ static void checkSimpleChainStatus(const CERT_SIMPLE_CHAIN *simpleChain,
 
         for (i = 0; i < simpleChain->cElement; i++)
             checkElementStatus(&simpleChainStatus->rgElementStatus[i],
-             &simpleChain->rgpElement[i]->TrustStatus, ignore, todo, testIndex,
-             chainIndex, i);
+             &simpleChain->rgpElement[i]->TrustStatus, ignore, todo, testName,
+             testIndex, chainIndex, i);
     }
 }
 
@@ -2667,10 +2909,11 @@ typedef struct _ChainStatusCheck
 } ChainStatusCheck;
 
 static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain,
- const ChainStatusCheck *chainStatus, DWORD todo, DWORD testIndex)
+ const ChainStatusCheck *chainStatus, DWORD todo, LPCSTR testName,
+ DWORD testIndex)
 {
     ok(chain->cChain == chainStatus->cChain,
-     "Chain %d: expected %d simple chains, got %d\n", testIndex,
+     "%s[%d]: expected %d simple chains, got %d\n", testName, testIndex,
      chainStatus->cChain, chain->cChain);
     if (todo & TODO_ERROR &&
      chain->TrustStatus.dwErrorStatus != chainStatus->status.dwErrorStatus)
@@ -2680,8 +2923,8 @@ static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain,
          ~chainStatus->statusToIgnore.dwErrorStatus) ==
          (chainStatus->status.dwErrorStatus &
          ~chainStatus->statusToIgnore.dwErrorStatus)),
-         "Chain %d: expected error %08x, got %08x\n",
-         testIndex, chainStatus->status.dwErrorStatus,
+         "%s[%d]: expected error %08x, got %08x\n",
+         testName, testIndex, chainStatus->status.dwErrorStatus,
          chain->TrustStatus.dwErrorStatus);
     else
         ok(chain->TrustStatus.dwErrorStatus ==
@@ -2690,9 +2933,9 @@ static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain,
          ~chainStatus->statusToIgnore.dwErrorStatus) ==
          (chainStatus->status.dwErrorStatus &
          ~chainStatus->statusToIgnore.dwErrorStatus)),
-         "Chain %d: expected error %08x, got %08x. %08x is expected if no valid "
+         "%s[%d]: expected error %08x, got %08x. %08x is expected if no valid "
          "Verisign root certificate is available.\n",
-         testIndex, chainStatus->status.dwErrorStatus,
+         testName, testIndex, chainStatus->status.dwErrorStatus,
          chain->TrustStatus.dwErrorStatus, CERT_TRUST_IS_UNTRUSTED_ROOT);
     if (todo & TODO_INFO &&
      chain->TrustStatus.dwInfoStatus != chainStatus->status.dwInfoStatus)
@@ -2702,8 +2945,8 @@ static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain,
          ~chainStatus->statusToIgnore.dwInfoStatus) ==
          (chainStatus->status.dwInfoStatus &
          ~chainStatus->statusToIgnore.dwInfoStatus)),
-         "Chain %d: expected info %08x, got %08x\n",
-         testIndex, chainStatus->status.dwInfoStatus,
+         "%s[%d]: expected info %08x, got %08x\n",
+         testName, testIndex, chainStatus->status.dwInfoStatus,
          chain->TrustStatus.dwInfoStatus);
     else
         ok(chain->TrustStatus.dwInfoStatus ==
@@ -2712,8 +2955,8 @@ static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain,
          ~chainStatus->statusToIgnore.dwInfoStatus) ==
          (chainStatus->status.dwInfoStatus &
          ~chainStatus->statusToIgnore.dwInfoStatus)),
-         "Chain %d: expected info %08x, got %08x\n",
-         testIndex, chainStatus->status.dwInfoStatus,
+         "%s[%d]: expected info %08x, got %08x\n",
+         testName, testIndex, chainStatus->status.dwInfoStatus,
          chain->TrustStatus.dwInfoStatus);
     if (chain->cChain == chainStatus->cChain)
     {
@@ -2722,7 +2965,7 @@ static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain,
         for (i = 0; i < chain->cChain; i++)
             checkSimpleChainStatus(chain->rgpChain[i],
              &chainStatus->rgChainStatus[i], &chainStatus->statusToIgnore,
-             todo, testIndex, i);
+             todo, testName, testIndex, i);
     }
 }
 
@@ -3104,13 +3347,24 @@ static CONST_DATA_BLOB chain29[] = {
  { sizeof(chain0_0), chain0_0 },
  { sizeof(chain29_1), chain29_1 },
 };
-static const CERT_TRUST_STATUS elementStatus29[] = {
+static CONST_DATA_BLOB chain30[] = {
+ { sizeof(chain0_0), chain0_0 },
+ { sizeof(chain30_1), chain30_1 },
+ { sizeof(chain30_2), chain30_2 },
+};
+static const CERT_TRUST_STATUS elementStatus30[] = {
  { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER },
- { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT,
+ { CERT_TRUST_INVALID_EXTENSION | CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT,
+   CERT_TRUST_HAS_NAME_MATCH_ISSUER },
+ { CERT_TRUST_IS_UNTRUSTED_ROOT,
    CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER },
 };
-static const SimpleChainStatusCheck simpleStatus29[] = {
- { sizeof(elementStatus29) / sizeof(elementStatus29[0]), elementStatus29 },
+static const SimpleChainStatusCheck simpleStatus30[] = {
+ { sizeof(elementStatus30) / sizeof(elementStatus30[0]), elementStatus30 },
+};
+static CONST_DATA_BLOB chain31[] = {
+ { sizeof(chain0_0), chain0_0 },
+ { sizeof(chain31_1), chain31_1 },
 };
 static CONST_DATA_BLOB selfSignedChain[] = {
  { sizeof(selfSignedCert), selfSignedCert }
@@ -3123,21 +3377,6 @@ static const SimpleChainStatusCheck selfSignedSimpleStatus[] = {
  { sizeof(selfSignedElementStatus) / sizeof(selfSignedElementStatus[0]),
    selfSignedElementStatus },
 };
-static CONST_DATA_BLOB iTunesChain[] = {
- { sizeof(verisignCA), verisignCA },
- { sizeof(iTunesCert0), iTunesCert0 },
- { sizeof(iTunesCert1), iTunesCert1 },
-};
-static const CERT_TRUST_STATUS iTunesElementStatus[] = {
- { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_KEY_MATCH_ISSUER },
- { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_EXACT_MATCH_ISSUER },
- { CERT_TRUST_NO_ERROR,
-   CERT_TRUST_HAS_NAME_MATCH_ISSUER | CERT_TRUST_IS_SELF_SIGNED},
-};
-static const SimpleChainStatusCheck iTunesSimpleStatus[] = {
- { sizeof(iTunesElementStatus) / sizeof(iTunesElementStatus[0]),
-   iTunesElementStatus },
-};
 static CONST_DATA_BLOB googleChain[] = {
  { sizeof(verisignCA), verisignCA },
  { sizeof(thawte_sgc_ca), thawte_sgc_ca },
@@ -3156,6 +3395,11 @@ static const SimpleChainStatusCheck googleSimpleStatus[] = {
  { sizeof(googleElementStatus) / sizeof(googleElementStatus[0]),
    googleElementStatus },
 };
+static CONST_DATA_BLOB battlenetChain[] = {
+ { sizeof(thawte_primary_ca), thawte_primary_ca },
+ { sizeof(thawte_ssl_ca), thawte_ssl_ca },
+ { sizeof(battlenet), battlenet },
+};
 /* The openssl cert is only valid from 9/12/2008 to 9/13/2012, so with the date
  * tested (October 2007) it's not time valid.
  */
@@ -3174,6 +3418,21 @@ static const SimpleChainStatusCheck opensslSimpleStatus[] = {
  { sizeof(opensslElementStatus) / sizeof(opensslElementStatus[0]),
    opensslElementStatus },
 };
+/* The OpenSSL chain may not have its root trusted, in which case the chain
+ * is truncated (on Win98).
+ */
+static CONST_DATA_BLOB incompleteOpensslChain[] = {
+ { sizeof(global_sign_ca), global_sign_ca },
+ { sizeof(openssl_org), openssl_org },
+};
+static const CERT_TRUST_STATUS incompleteOpensslElementStatus[] = {
+ { CERT_TRUST_IS_NOT_TIME_VALID, CERT_TRUST_HAS_KEY_MATCH_ISSUER },
+ { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_KEY_MATCH_ISSUER },
+};
+static const SimpleChainStatusCheck incompleteOpensslSimpleStatus[] = {
+ { sizeof(incompleteOpensslElementStatus) / sizeof(incompleteOpensslElementStatus[0]),
+   incompleteOpensslElementStatus },
+};
 /* entrust_ca -> aaa_certificate_services -> cs_stanford_edu */
 /* cs.stanford.edu's cert is only valid from 7/16/2009 to 7/16/2012, so with
  * the date tested (October 2007) it's not time valid.
@@ -3398,29 +3657,33 @@ static ChainCheck chainCheck[] = {
      1, simpleStatus28 },
    0 },
  /* chain29 is handled separately elsewhere */
+ /* Microsoft incorrectly ignores unknown/unsupported critical extensions on
+  * older Windows versions, so ignore the error on Windows.
+  */
+ { { sizeof(chain30) / sizeof(chain30[0]), chain30 },
+   { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE |
+       CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT |
+       CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT |
+       CERT_TRUST_INVALID_EXTENSION |
+       CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT,
+       CERT_TRUST_HAS_PREFERRED_ISSUER },
+     { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_INVALID_EXTENSION |
+       CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT, 0 },
+     1, simpleStatus30 },
+   0 },
  { { sizeof(selfSignedChain) / sizeof(selfSignedChain[0]), selfSignedChain },
    { { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
      { CERT_TRUST_IS_NOT_TIME_VALID | CERT_TRUST_IS_UNTRUSTED_ROOT, 0 },
      1, selfSignedSimpleStatus }, 0 },
- /* The iTunes chain may or may not have its root trusted, so ignore the
-  * error
-  */
- { { sizeof(iTunesChain) / sizeof(iTunesChain[0]), iTunesChain },
-   { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER },
-     { 0, 0 },
-       1, iTunesSimpleStatus }, 0 },
- /* The google chain may or may not have its root trusted, so ignore the error
+ /* The google chain may or may not have its root trusted, so ignore the error.
+  * The chain is also considered not time nested on Win98, so ignore that
+  * error too.
   */
  { { sizeof(googleChain) / sizeof(googleChain[0]), googleChain },
-   { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER },
+   { { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_TIME_NESTED,
+       CERT_TRUST_HAS_PREFERRED_ISSUER },
      { CERT_TRUST_IS_NOT_TIME_VALID, 0 },
        1, googleSimpleStatus }, 0 },
- /* The openssl chain may or may not have its root trusted, so ignore the error
-  */
- { { sizeof(opensslChain) / sizeof(opensslChain[0]), opensslChain },
-   { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER },
-     { CERT_TRUST_IS_NOT_TIME_VALID, 0 },
-       1, opensslSimpleStatus }, 0 },
  /* The stanford chain may or may not have its root trusted, so ignore the error
   */
  { { sizeof(stanfordChain) / sizeof(stanfordChain[0]), stanfordChain },
@@ -3449,6 +3712,20 @@ static ChainCheck chainCheckNoStore[] = {
    0 },
 };
 
+ /* The openssl chain may or may not have its root trusted, so ignore the error
+  */
+static ChainCheck opensslChainCheck =
+ { { sizeof(opensslChain) / sizeof(opensslChain[0]), opensslChain },
+   { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER },
+     { CERT_TRUST_IS_NOT_TIME_VALID, 0 },
+       1, opensslSimpleStatus }, 0 };
+static ChainCheck incompleteOpensslChainCheck =
+ { { sizeof(incompleteOpensslChain) / sizeof(incompleteOpensslChain[0]),
+     incompleteOpensslChain },
+   { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER },
+     { CERT_TRUST_IS_NOT_TIME_VALID | CERT_TRUST_IS_PARTIAL_CHAIN, 0 },
+       1, incompleteOpensslSimpleStatus }, 0 };
+
 /* Chain27 checks a certificate with a subject alternate name containing an
  * embedded NULL.  Newer crypt32 versions fail to decode such alternate names,
  * correctly prohibiting them.  Older crypt32 versions do not.  Rather than
@@ -3477,6 +3754,19 @@ static ChainCheck chainCheckEmbeddedNullBroken = {
 static SYSTEMTIME oct2007 = { 2007, 10, 1, 1, 0, 0, 0, 0 };
 /* Wednesday, Oct 28, 2009 */
 static SYSTEMTIME oct2009 = { 2009, 10, 3, 28, 0, 0, 0, 0 };
+/* Wednesday, Oct 28, 2010 */
+static SYSTEMTIME oct2010 = { 2010, 10, 3, 28, 0, 0, 0, 0 };
+/* Friday, June 6, 2013 */
+static SYSTEMTIME jun2013 = { 2013, 6, 5, 6, 0, 0, 0, 0 };
+
+#define test_name_blob(a,b) _test_name_blob(__LINE__,a,b)
+static void _test_name_blob(unsigned line, CERT_NAME_BLOB *blob, const char *exdata)
+{
+    char buf[1024];
+
+    CertNameToStrA(CRYPT_ASN_ENCODING, blob, CERT_SIMPLE_NAME_STR, buf, sizeof(buf));
+    ok_(__FILE__,line)(!strcmp(buf, exdata), "got string %s, expected %s\n", buf, exdata);
+}
 
 static void testGetCertChain(void)
 {
@@ -3484,6 +3774,8 @@ static void testGetCertChain(void)
     PCCERT_CONTEXT cert;
     CERT_CHAIN_PARA para = { 0 };
     PCCERT_CHAIN_CONTEXT chain;
+    const CERT_SIMPLE_CHAIN *simple_chain;
+    const CERT_CHAIN_ELEMENT *chain_elem;
     FILETIME fileTime;
     DWORD i;
     HCERTSTORE store;
@@ -3572,7 +3864,7 @@ static void testGetCertChain(void)
     {
         ok(chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE,
          "expected CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n");
-        CertFreeCertificateChain(chain);
+        pCertFreeCertificateChain(chain);
     }
     oids[0] = oid_server_auth;
     ret = pCertGetCertificateChain(NULL, cert, &fileTime, store, &para,
@@ -3580,10 +3872,9 @@ static void testGetCertChain(void)
     ok(ret, "CertGetCertificateChain failed: %08x\n", GetLastError());
     if (ret)
     {
-        ok(!(chain->TrustStatus.dwErrorStatus &
-         CERT_TRUST_IS_NOT_VALID_FOR_USAGE),
-         "didn't expect CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n");
-        CertFreeCertificateChain(chain);
+        ok(!(chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE),
+           "didn't expect CERT_TRUST_IS_NOT_VALID_FOR_USAGE, got %x\n", chain->TrustStatus.dwErrorStatus);
+        pCertFreeCertificateChain(chain);
     }
     oids[1] = one_two_three;
     para.RequestedUsage.Usage.cUsageIdentifier = 2;
@@ -3595,7 +3886,7 @@ static void testGetCertChain(void)
     {
         ok(chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE,
          "expected CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n");
-        CertFreeCertificateChain(chain);
+        pCertFreeCertificateChain(chain);
     }
     para.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR;
     ret = pCertGetCertificateChain(NULL, cert, &fileTime, store, &para,
@@ -3606,7 +3897,7 @@ static void testGetCertChain(void)
         ok(!(chain->TrustStatus.dwErrorStatus &
          CERT_TRUST_IS_NOT_VALID_FOR_USAGE),
          "didn't expect CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n");
-        CertFreeCertificateChain(chain);
+        pCertFreeCertificateChain(chain);
     }
     CertCloseStore(store, 0);
     CertFreeCertificateContext(cert);
@@ -3618,10 +3909,32 @@ static void testGetCertChain(void)
         if (chain)
         {
             checkChainStatus(chain, &chainCheck[i].status, chainCheck[i].todo,
-             i);
+             "chainCheck", i);
             pCertFreeCertificateChain(chain);
         }
     }
+    chain = getChain(NULL, &opensslChainCheck.certs, 0, TRUE, &oct2007,
+     opensslChainCheck.todo, 0);
+    if (chain)
+    {
+        ok(chain->TrustStatus.dwErrorStatus ==
+         opensslChainCheck.status.status.dwErrorStatus ||
+         broken((chain->TrustStatus.dwErrorStatus &
+         ~incompleteOpensslChainCheck.status.statusToIgnore.dwErrorStatus) ==
+         (incompleteOpensslChainCheck.status.status.dwErrorStatus &
+         ~incompleteOpensslChainCheck.status.statusToIgnore.dwErrorStatus)),
+         "unexpected chain error status %08x\n",
+         chain->TrustStatus.dwErrorStatus);
+        if (opensslChainCheck.status.status.dwErrorStatus ==
+         chain->TrustStatus.dwErrorStatus)
+            checkChainStatus(chain, &opensslChainCheck.status,
+             opensslChainCheck.todo, "opensslChainCheck", 0);
+        else
+            checkChainStatus(chain, &incompleteOpensslChainCheck.status,
+             incompleteOpensslChainCheck.todo, "incompleteOpensslChainCheck",
+             0);
+        pCertFreeCertificateChain(chain);
+    }
     for (i = 0; i < sizeof(chainCheckNoStore) / sizeof(chainCheckNoStore[0]);
      i++)
     {
@@ -3630,7 +3943,7 @@ static void testGetCertChain(void)
         if (chain)
         {
             checkChainStatus(chain, &chainCheckNoStore[i].status,
-             chainCheckNoStore[i].todo, i);
+             chainCheckNoStore[i].todo, "chainCheckNoStore", i);
             pCertFreeCertificateChain(chain);
         }
     }
@@ -3649,12 +3962,84 @@ static void testGetCertChain(void)
         if (chainCheckEmbeddedNull.status.status.dwErrorStatus ==
          chain->TrustStatus.dwErrorStatus)
             checkChainStatus(chain, &chainCheckEmbeddedNull.status,
-             chainCheckEmbeddedNull.todo, 0);
+             chainCheckEmbeddedNull.todo, "chainCheckEmbeddedNull", 0);
         else
             checkChainStatus(chain, &chainCheckEmbeddedNullBroken.status,
-             chainCheckEmbeddedNullBroken.todo, 0);
+             chainCheckEmbeddedNullBroken.todo, "chainCheckEmbeddedNullBroken",
+             0);
+        pCertFreeCertificateChain(chain);
+    }
+
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store != NULL, "CertOpenStore failed: %u\n", GetLastError());
+
+    ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, winehq_org, sizeof(winehq_org),
+            CERT_STORE_ADD_ALWAYS, &cert);
+    ok(ret, "CertAddEncodedCertificateToStore failed: %u\n", GetLastError());
+
+    oids[0] = oid_server_auth;
+    memset(&para, 0, sizeof(para));
+    para.cbSize = sizeof(para);
+    para.RequestedUsage.Usage.cUsageIdentifier = 1;
+    para.RequestedUsage.Usage.rgpszUsageIdentifier = oids;
+    SystemTimeToFileTime(&jun2013, &fileTime);
+
+    /* Pass store that does not contain all certs in chain. */
+    ret = CertGetCertificateChain(NULL, cert, &fileTime, store, &para, 0, NULL, &chain);
+    ok(ret, "CertGetCertificateChain failed: %u\n", GetLastError());
+
+    if(chain->TrustStatus.dwErrorStatus == CERT_TRUST_IS_PARTIAL_CHAIN) { /* win2k */
+        win_skip("winehq cert reported as partial chain, skipping its tests\n");
         pCertFreeCertificateChain(chain);
+        CertCloseStore(store, 0);
+        return;
     }
+
+    ok(!chain->TrustStatus.dwErrorStatus, "chain->TrustStatus.dwErrorStatus = %x\n", chain->TrustStatus.dwErrorStatus);
+    todo_wine
+    ok(chain->TrustStatus.dwInfoStatus == CERT_TRUST_HAS_PREFERRED_ISSUER, "chain->TrustStatus.dwInfoStatus = %x\n",
+       chain->TrustStatus.dwInfoStatus);
+
+    ok(chain->cChain == 1, "chain->cChain = %d\n", chain->cChain);
+    ok(!chain->cLowerQualityChainContext, "chain->cLowerQualityChainContext = %x\n", chain->cLowerQualityChainContext);
+    ok(!chain->rgpLowerQualityChainContext, "chain->rgpLowerQualityChainContext =  %p\n", chain->rgpLowerQualityChainContext);
+
+    simple_chain = *chain->rgpChain;
+    ok(simple_chain->cbSize == sizeof(*simple_chain), "simple_chain->cbSize = %u\n", simple_chain->cbSize);
+    ok(!simple_chain->TrustStatus.dwErrorStatus, "simple_chain->TrustStatus.dwErrorStatus = %x\n",
+       simple_chain->TrustStatus.dwErrorStatus);
+    todo_wine
+    ok(simple_chain->TrustStatus.dwInfoStatus == CERT_TRUST_HAS_PREFERRED_ISSUER,
+       "simple_chain->TrustStatus.dwInfoStatus = %x\n", simple_chain->TrustStatus.dwInfoStatus);
+    ok(simple_chain->cElement == 3, "simple_chain->cElement = %u\n", simple_chain->cElement);
+
+    for(i=0; i < simple_chain->cElement; i++) {
+        chain_elem = simple_chain->rgpElement[i];
+        ok(chain_elem->cbSize == sizeof(*chain_elem), "chain_elem->cbSize = %u\n", chain_elem->cbSize);
+
+        ok(!chain_elem->TrustStatus.dwErrorStatus, "chain_elem->TrustStatus.dwErrorStatus = %x\n",
+           chain_elem->TrustStatus.dwErrorStatus);
+        trace("info[%u] = %x\n", i, chain_elem->TrustStatus.dwInfoStatus);
+        ok(chain_elem->pCertContext->dwCertEncodingType == CRYPT_ASN_ENCODING,
+           "chain_elem->pCertContext->dwCertEncodingType = %x\n",
+           chain_elem->pCertContext->dwCertEncodingType);
+    }
+
+    ok(simple_chain->rgpElement[0]->pCertContext == cert, "simple_chain->rgpElement[0]->pCertContext != cert\n");
+    test_name_blob(&simple_chain->rgpElement[1]->pCertContext->pCertInfo->Issuer, "US, GeoTrust Inc., GeoTrust Global CA");
+    test_name_blob(&simple_chain->rgpElement[1]->pCertContext->pCertInfo->Subject, "US, \"GeoTrust, Inc.\", RapidSSL CA");
+    test_name_blob(&simple_chain->rgpElement[2]->pCertContext->pCertInfo->Issuer, "US, GeoTrust Inc., GeoTrust Global CA");
+    test_name_blob(&simple_chain->rgpElement[2]->pCertContext->pCertInfo->Subject, "US, GeoTrust Inc., GeoTrust Global CA");
+
+    pCertFreeCertificateChain(chain);
+
+    /* Test HCCE_LOCAL_MACHINE */
+    ret = CertGetCertificateChain(HCCE_LOCAL_MACHINE, cert, &fileTime, store, &para, 0, NULL, &chain);
+    ok(ret, "CertGetCertificateChain failed: %u\n", GetLastError());
+    pCertFreeCertificateChain(chain);
+
+    CertFreeCertificateContext(cert);
+    CertCloseStore(store, 0);
 }
 
 static void test_CERT_CHAIN_PARA_cbSize(void)
@@ -3672,9 +4057,11 @@ static void test_CERT_CHAIN_PARA_cbSize(void)
     ret = CertAddEncodedCertificateToStore(store,
      X509_ASN_ENCODING, chain0_0, sizeof(chain0_0),
      CERT_STORE_ADD_ALWAYS, NULL);
+    ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
     ret = CertAddEncodedCertificateToStore(store,
      X509_ASN_ENCODING, chain0_1, sizeof(chain0_1),
      CERT_STORE_ADD_ALWAYS, &cert);
+    ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
 
     for (i = 0; i < sizeof(CERT_CHAIN_PARA) + 2; i++)
     {
@@ -3744,6 +4131,33 @@ static const ChainPolicyCheck basePolicyCheck[] = {
    { 0, CERT_E_UNTRUSTEDROOT, 0, 0, NULL }, NULL, 0 },
 };
 
+/* Windows NT 4 has a different error code when the validity period doesn't
+ * nest.  (It's arguably more correct than other Windows versions, but since
+ * others do not emulate its behavior, we mark its behavior broken.)
+ */
+static const CERT_CHAIN_POLICY_STATUS badDateNestingStatus =
+ { 0, CERT_E_VALIDITYPERIODNESTING, 0, 0, NULL };
+
+static const ChainPolicyCheck ignoredBadDateNestingBasePolicyCheck = {
+ { sizeof(chain2) / sizeof(chain2[0]), chain2 },
+ { 0, CERT_E_EXPIRED, 0, 1, NULL}, &badDateNestingStatus, TODO_ELEMENTS
+};
+
+static const ChainPolicyCheck ignoredInvalidDateBasePolicyCheck = {
+ { sizeof(googleChain) / sizeof(googleChain[0]), googleChain },
+ { 0, CERT_E_EXPIRED, 0, 1, NULL}, &badDateNestingStatus, TODO_ELEMENTS
+};
+
+static const ChainPolicyCheck ignoredInvalidUsageBasePolicyCheck = {
+ { sizeof(chain15) / sizeof(chain15[0]), chain15 },
+ { 0, CERT_E_EXPIRED, 0, 1, NULL}, NULL, TODO_ERROR
+};
+
+static const ChainPolicyCheck invalidUsageBasePolicyCheck = {
+ { sizeof(chain15) / sizeof(chain15[0]), chain15 },
+ { 0, CERT_E_WRONG_USAGE, 0, 1, NULL}, NULL, 0
+};
+
 static const ChainPolicyCheck sslPolicyCheck[] = {
  { { sizeof(chain0) / sizeof(chain0[0]), chain0 },
    { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 },
@@ -3787,33 +4201,37 @@ static const ChainPolicyCheck sslPolicyCheck[] = {
    { 0, CERT_E_UNTRUSTEDROOT, 0, 0, NULL }, NULL, 0 },
 };
 
+static const ChainPolicyCheck ignoredUnknownCAPolicyCheck = {
+ { sizeof(chain0) / sizeof(chain0[0]), chain0 },
+ { 0, CERT_E_EXPIRED, 0, 0, NULL }, NULL, 0
+};
+
 static const ChainPolicyCheck googlePolicyCheckWithMatchingNameExpired = {
  { sizeof(googleChain) / sizeof(googleChain[0]), googleChain },
  { 0, CERT_E_EXPIRED, 0, 0, NULL}, NULL, 0
 };
 
+/* Win98 sees the chain as expired, even though it isn't for the date tested */
+static const CERT_CHAIN_POLICY_STATUS expiredStatus =
+ { 0, CERT_E_EXPIRED, 0, 0, NULL };
+
 static const ChainPolicyCheck googlePolicyCheckWithMatchingName = {
  { sizeof(googleChain) / sizeof(googleChain[0]), googleChain },
- { 0, 0, -1, -1, NULL}, NULL, 0
+ { 0, 0, -1, -1, NULL}, &expiredStatus, 0
 };
 
-/* Windows NT 4 has a different error code when the name doesn't match. */
-static const CERT_CHAIN_POLICY_STATUS noMatchingNameBrokenStatus =
- { 0, CERT_E_ROLE, 0, 0, NULL };
-
-static const ChainPolicyCheck iTunesPolicyCheckWithoutMatchingName = {
- { sizeof(iTunesChain) / sizeof(iTunesChain[0]), iTunesChain },
- { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, &noMatchingNameBrokenStatus, 0
-};
+/* Win98 does not trust the root of the OpenSSL chain or the Stanford chain */
+static const CERT_CHAIN_POLICY_STATUS untrustedRootStatus =
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 0, NULL };
 
 static const ChainPolicyCheck opensslPolicyCheckWithMatchingName = {
  { sizeof(opensslChain) / sizeof(opensslChain[0]), opensslChain },
- { 0, 0, -1, -1, NULL}, NULL, 0
+ { 0, 0, -1, -1, NULL}, &untrustedRootStatus, 0
 };
 
 static const ChainPolicyCheck opensslPolicyCheckWithoutMatchingName = {
  { sizeof(opensslChain) / sizeof(opensslChain[0]), opensslChain },
- { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, NULL, 0
+ { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, &untrustedRootStatus, 0
 };
 
 static const ChainPolicyCheck winehqPolicyCheckWithMatchingName = {
@@ -3828,11 +4246,31 @@ static const ChainPolicyCheck winehqPolicyCheckWithoutMatchingName = {
 
 static const ChainPolicyCheck stanfordPolicyCheckWithMatchingName = {
  { sizeof(stanfordChain) / sizeof(stanfordChain[0]), stanfordChain },
- { 0, 0, -1, -1, NULL}, NULL, 0
+ { 0, 0, -1, -1, NULL}, &untrustedRootStatus, 0
 };
 
 static const ChainPolicyCheck stanfordPolicyCheckWithoutMatchingName = {
  { sizeof(stanfordChain) / sizeof(stanfordChain[0]), stanfordChain },
+ { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, &untrustedRootStatus, 0
+};
+
+static const ChainPolicyCheck nullTerminatedDomainComponentPolicyCheck = {
+ { sizeof(battlenetChain) / sizeof(battlenetChain[0]), battlenetChain },
+ { 0, 0, -1, -1, NULL}, &untrustedRootStatus, 0
+};
+
+static const ChainPolicyCheck invalidExtensionPolicyCheck = {
+ { sizeof(chain30) / sizeof(chain30[0]), chain30 },
+ { 0, CERT_E_CRITICAL, 0, 1, NULL}, &badDateNestingStatus, 0
+};
+
+static const ChainPolicyCheck fooPolicyCheckWithMatchingName = {
+ { sizeof(chain31) / sizeof(chain31[0]), chain31 },
+ { 0, 0, -1, -1, NULL}, NULL, 0
+};
+
+static const ChainPolicyCheck fooPolicyCheckWithoutMatchingName = {
+ { sizeof(chain31) / sizeof(chain31[0]), chain31 },
  { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, NULL, 0
 };
 
@@ -3938,8 +4376,8 @@ static const char *num_to_str(WORD num)
 }
 
 static void checkChainPolicyStatus(LPCSTR policy, HCERTCHAINENGINE engine,
- const ChainPolicyCheck *check, DWORD testIndex, SYSTEMTIME *sysTime,
- PCERT_CHAIN_POLICY_PARA para)
+ const ChainPolicyCheck *check, LPCSTR testName, DWORD testIndex,
SYSTEMTIME *sysTime, PCERT_CHAIN_POLICY_PARA para)
 {
     PCCERT_CHAIN_CONTEXT chain = getChain(engine, &check->certs, 0, TRUE,
      sysTime, check->todo, testIndex);
@@ -3952,20 +4390,23 @@ static void checkChainPolicyStatus(LPCSTR policy, HCERTCHAINENGINE engine,
 
         if (check->todo & TODO_POLICY)
             todo_wine ok(ret,
-             "%s[%d]: CertVerifyCertificateChainPolicy failed: %08x\n",
+             "%s[%d](%s): CertVerifyCertificateChainPolicy failed: %08x\n",
+             testName, testIndex,
              IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
-             testIndex, GetLastError());
+             GetLastError());
         else
         {
             if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
             {
-                skip("%d: missing policy %s, skipping test\n", testIndex,
+                skip("%s[%d]: missing policy %s, skipping test\n",
+                 testName, testIndex,
                  IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy);
                 pCertFreeCertificateChain(chain);
                 return;
             }
-            ok(ret, "%s[%d]: CertVerifyCertificateChainPolicy failed: %08x\n",
-             IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex,
+            ok(ret, "%s[%d](%s): CertVerifyCertificateChainPolicy failed: %08x\n",
+             testName, testIndex,
+             IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
              GetLastError());
         }
         if (ret)
@@ -3975,22 +4416,25 @@ static void checkChainPolicyStatus(LPCSTR policy, HCERTCHAINENGINE engine,
                  broken(policyStatus.dwError == CERT_TRUST_NO_ERROR) ||
                  (check->brokenStatus && broken(policyStatus.dwError ==
                  check->brokenStatus->dwError)),
-                 "%s[%d]: expected %08x, got %08x\n",
+                 "%s[%d](%s): expected %08x, got %08x\n",
+                 testName, testIndex,
                  IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
-                 testIndex, check->status.dwError, policyStatus.dwError);
+                 check->status.dwError, policyStatus.dwError);
             else
                 ok(policyStatus.dwError == check->status.dwError ||
                  broken(policyStatus.dwError == CERT_TRUST_NO_ERROR) ||
                  (check->brokenStatus && broken(policyStatus.dwError ==
                  check->brokenStatus->dwError)),
-                 "%s[%d]: expected %08x, got %08x\n",
+                 "%s[%d](%s): expected %08x, got %08x\n",
+                 testName, testIndex,
                  IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
-                 testIndex, check->status.dwError, policyStatus.dwError);
+                 check->status.dwError, policyStatus.dwError);
             if (policyStatus.dwError != check->status.dwError)
             {
-                skip("%s[%d]: error %08x doesn't match expected %08x, not checking indexes\n",
+                skip("%s[%d](%s): error %08x doesn't match expected %08x, not checking indexes\n",
+                 testName, testIndex,
                  IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
-                 testIndex, policyStatus.dwError, check->status.dwError);
+                 policyStatus.dwError, check->status.dwError);
                 pCertFreeCertificateChain(chain);
                 return;
             }
@@ -3999,48 +4443,121 @@ static void checkChainPolicyStatus(LPCSTR policy, HCERTCHAINENGINE engine,
                  check->status.lChainIndex ||
                  (check->brokenStatus && broken(policyStatus.lChainIndex ==
                  check->brokenStatus->lChainIndex)),
-                 "%s[%d]: expected %d, got %d\n",
+                 "%s[%d](%s): expected %d, got %d\n",
+                 testName, testIndex,
                  IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
-                 testIndex, check->status.lChainIndex,
-                 policyStatus.lChainIndex);
+                 check->status.lChainIndex, policyStatus.lChainIndex);
             else
                 ok(policyStatus.lChainIndex == check->status.lChainIndex ||
                  (check->brokenStatus && broken(policyStatus.lChainIndex ==
                  check->brokenStatus->lChainIndex)),
-                 "%s[%d]: expected %d, got %d\n",
+                 "%s[%d](%s): expected %d, got %d\n",
+                 testName, testIndex,
                  IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
-                 testIndex,
                  check->status.lChainIndex, policyStatus.lChainIndex);
             if (check->todo & TODO_ELEMENTS)
                 todo_wine ok(policyStatus.lElementIndex ==
                  check->status.lElementIndex ||
                  (check->brokenStatus && broken(policyStatus.lElementIndex ==
                  check->brokenStatus->lElementIndex)),
-                 "%s[%d]: expected %d, got %d\n",
+                 "%s[%d](%s): expected %d, got %d\n",
+                 testName, testIndex,
                  IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
-                 testIndex,
                  check->status.lElementIndex, policyStatus.lElementIndex);
             else
                 ok(policyStatus.lElementIndex == check->status.lElementIndex ||
                  (check->brokenStatus && broken(policyStatus.lElementIndex ==
                  check->brokenStatus->lElementIndex)),
-                 "%s[%d]: expected %d, got %d\n",
+                 testName, testIndex,
+                 "%s[%d](%s): expected %d, got %d\n",
                  IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
-                 testIndex,
                  check->status.lElementIndex, policyStatus.lElementIndex);
         }
         pCertFreeCertificateChain(chain);
     }
 }
 
+#define CHECK_CHAIN_POLICY_STATUS_ARRAY(policy, engine, array, date, para) \
+    do { \
+        DWORD i; \
+        for (i = 0; i < sizeof(array) / sizeof(array)[0]; i++) \
+            checkChainPolicyStatus((policy), (engine), &(array)[i], \
+             #array, i, (date), (para)); \
+    } while(0)
+
+#define CHECK_CHAIN_POLICY_STATUS(policy, engine, policyCheck, date, para) \
+    checkChainPolicyStatus((policy), (engine), &(policyCheck), \
+     #policyCheck, 0, (date), (para))
+
+static void check_base_policy(void)
+{
+    CERT_CHAIN_POLICY_PARA policyPara = { 0 };
+
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_BASE, NULL,
+     basePolicyCheck, &oct2007, NULL);
+    policyPara.cbSize = sizeof(policyPara);
+    policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL,
+     ignoredUnknownCAPolicyCheck, &oct2007, &policyPara);
+    policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG |
+     CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL,
+     ignoredBadDateNestingBasePolicyCheck, &oct2007, &policyPara);
+    policyPara.dwFlags = CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL,
+     ignoredInvalidDateBasePolicyCheck, &oct2007, &policyPara);
+    policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG |
+     CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG;
+    policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG |
+     CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG |
+     CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL,
+     ignoredInvalidUsageBasePolicyCheck, &oct2007, &policyPara);
+    policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG |
+     CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL,
+     invalidUsageBasePolicyCheck, &oct2007, &policyPara);
+    /* Test chain30, which has an invalid critical extension in an intermediate
+     * cert, against the base policy.
+     */
+    policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL,
+     invalidExtensionPolicyCheck, &oct2007, &policyPara);
+}
+
+static void check_authenticode_policy(void)
+{
+    CERT_CHAIN_POLICY_PARA policyPara = { 0 };
+    SYSTEMTIME epochStart = { 0 };
+
+    /* The authenticode policy doesn't seem to check anything beyond the base
+     * policy.  It might check for chains signed by the MS test cert, but none
+     * of these chains is.
+     */
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_AUTHENTICODE, NULL,
+     authenticodePolicyCheck, &oct2007, NULL);
+    policyPara.cbSize = sizeof(policyPara);
+    policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_AUTHENTICODE, NULL,
+     ignoredUnknownCAPolicyCheck, &oct2007, &policyPara);
+    epochStart.wDay = epochStart.wMonth = 1;
+    epochStart.wYear = 1601;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_AUTHENTICODE, NULL,
+     ignoredUnknownCAPolicyCheck, &epochStart, &policyPara);
+    policyPara.dwFlags = CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_AUTHENTICODE, NULL,
+     ignoredInvalidDateBasePolicyCheck, &oct2007, &policyPara);
+}
+
 static void check_ssl_policy(void)
 {
-    DWORD i;
     CERT_CHAIN_POLICY_PARA policyPara = { 0 };
     SSL_EXTRA_CERT_CHAIN_POLICY_PARA sslPolicyPara = { { 0 } };
     WCHAR winehq[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
     WCHAR google_dot_com[] = { 'w','w','w','.','g','o','o','g','l','e','.',
      'c','o','m',0 };
+    WCHAR battle_dot_net[] = { 'w','w','w','.','b','a','t','t','l','e','.',
+     'n','e','t',0 };
     WCHAR a_dot_openssl_dot_org[] = { 'a','.','o','p','e','n','s','s','l','.',
      'o','r','g',0 };
     WCHAR openssl_dot_org[] = { 'o','p','e','n','s','s','l','.','o','r','g',0 };
@@ -4058,120 +4575,114 @@ static void check_ssl_policy(void)
      'w','i','n','e','h','q','.','o','r','g',0 };
     WCHAR a_dot_b_dot_winehq_dot_org[] = { 'a','.','b','.',
      'w','i','n','e','h','q','.','o','r','g',0 };
+    WCHAR foo_dot_com[] = { 'f','o','o','.','c','o','m',0 };
+    WCHAR afoo_dot_com[] = { 'a','f','o','o','.','c','o','m',0 };
+    WCHAR a_dot_foo_dot_com[] = { 'a','.','f','o','o','.','c','o','m',0 };
     HCERTSTORE testRoot;
     CERT_CHAIN_ENGINE_CONFIG engineConfig = { sizeof(engineConfig), 0 };
     HCERTCHAINENGINE engine;
 
     /* Check ssl policy with no parameter */
-    for (i = 0;
-     i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
-         i, &oct2007, NULL);
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck,
+     &oct2007, NULL);
     /* Check again with a policy parameter that specifies nothing */
-    for (i = 0;
-     i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
-         i, &oct2007, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck,
+     &oct2007, &policyPara);
     /* Check yet again, but specify an empty SSL_EXTRA_CERT_CHAIN_POLICY_PARA
      * argument.
      */
     policyPara.pvExtraPolicyPara = &sslPolicyPara;
-    for (i = 0;
-     i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
-         i, &oct2007, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck,
+     &oct2007, &policyPara);
     /* And again, but specify the auth type as a client */
     sslPolicyPara.dwAuthType = AUTHTYPE_CLIENT;
-    for (i = 0;
-     i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
-         i, &oct2007, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck,
+     &oct2007, &policyPara);
     /* And again, but specify the auth type as a server */
     sslPolicyPara.dwAuthType = AUTHTYPE_SERVER;
-    for (i = 0;
-     i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
-         i, &oct2007, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck,
+     &oct2007, &policyPara);
     /* And again authenticating a client, but specify the size of the policy
      * parameter.
      */
     U(sslPolicyPara).cbSize = sizeof(sslPolicyCheck);
     sslPolicyPara.dwAuthType = AUTHTYPE_CLIENT;
-    for (i = 0;
-     i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
-         i, &oct2007, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck,
+     &oct2007, &policyPara);
     /* One more time authenticating a client, but specify winehq.org as the
      * server name.
      */
     sslPolicyPara.pwszServerName = winehq;
-    for (i = 0;
-     i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
-         i, &oct2007, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck,
+     &oct2007, &policyPara);
     /* And again authenticating a server, still specifying winehq.org as the
      * server name.
      */
     sslPolicyPara.dwAuthType = AUTHTYPE_SERVER;
-    for (i = 0;
-     i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
-         i, &oct2007, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck,
+     &oct2007, &policyPara);
     /* And again authenticating a server, this time specifying the size of the
      * policy param.
      */
     policyPara.cbSize = sizeof(policyPara);
-    for (i = 0;
-     i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
-         i, &oct2007, &policyPara);
-    /* Yet again, but checking the iTunes chain, which contains a name
-     * extension.
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck,
+     &oct2007, &policyPara);
+    /* And again, specifying a chain with an untrusted root, but ignoring
+     * unknown CAs.
      */
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
-     &iTunesPolicyCheckWithoutMatchingName, 0, &oct2007, &policyPara);
+    sslPolicyPara.fdwChecks = SECURITY_FLAG_IGNORE_UNKNOWN_CA;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     ignoredUnknownCAPolicyCheck, &oct2007, &policyPara);
+    sslPolicyPara.fdwChecks = 0;
     /* And again, but checking the Google chain at a bad date */
     sslPolicyPara.pwszServerName = google_dot_com;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
-     &googlePolicyCheckWithMatchingNameExpired, 0, &oct2007, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     googlePolicyCheckWithMatchingNameExpired, &oct2007, &policyPara);
+    /* Again checking the Google chain at a bad date, but ignoring date
+     * errors.
+     */
+    sslPolicyPara.fdwChecks = SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     googlePolicyCheckWithMatchingName, &oct2007, &policyPara);
+    sslPolicyPara.fdwChecks = 0;
     /* And again, but checking the Google chain at a good date */
     sslPolicyPara.pwszServerName = google_dot_com;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
-     &googlePolicyCheckWithMatchingName, 0, &oct2009, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     googlePolicyCheckWithMatchingName, &oct2009, &policyPara);
     /* Check again with the openssl cert, which has a wildcard in its name,
      * with various combinations of matching and non-matching names.
      * With "a.openssl.org": match
      */
     sslPolicyPara.pwszServerName = a_dot_openssl_dot_org;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
-     &opensslPolicyCheckWithMatchingName, 0, &oct2009, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     opensslPolicyCheckWithMatchingName, &oct2009, &policyPara);
     /* With "openssl.org": no match */
     sslPolicyPara.pwszServerName = openssl_dot_org;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
-     &opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     opensslPolicyCheckWithoutMatchingName, &oct2009, &policyPara);
     /* With "fopenssl.org": no match */
     sslPolicyPara.pwszServerName = fopenssl_dot_org;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
-     &opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     opensslPolicyCheckWithoutMatchingName, &oct2009, &policyPara);
     /* with "a.b.openssl.org": no match */
     sslPolicyPara.pwszServerName = a_dot_b_dot_openssl_dot_org;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
-     &opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     opensslPolicyCheckWithoutMatchingName, &oct2009, &policyPara);
     /* Check again with the cs.stanford.edu, which has both cs.stanford.edu
      * and www.cs.stanford.edu in its subject alternative name.
      * With "cs.stanford.edu": match
      */
     sslPolicyPara.pwszServerName = cs_dot_stanford_dot_edu;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
-     &stanfordPolicyCheckWithMatchingName, 0, &oct2009, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     stanfordPolicyCheckWithMatchingName, &oct2009, &policyPara);
     /* With "www.cs.stanford.edu": match */
     sslPolicyPara.pwszServerName = www_dot_cs_dot_stanford_dot_edu;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
-     &stanfordPolicyCheckWithMatchingName, 0, &oct2009, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     stanfordPolicyCheckWithMatchingName, &oct2009, &policyPara);
     /* With "a.cs.stanford.edu": no match */
     sslPolicyPara.pwszServerName = a_dot_cs_dot_stanford_dot_edu;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
-     &stanfordPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     stanfordPolicyCheckWithoutMatchingName, &oct2009, &policyPara);
     /* Check chain29, which has a wildcard in its subject alternative name,
      * but not in its distinguished name.
      * Step 1: create a chain engine that trusts chain29's root.
@@ -4181,25 +4692,55 @@ static void check_ssl_policy(void)
     CertAddEncodedCertificateToStore(testRoot, X509_ASN_ENCODING, chain0_0,
      sizeof(chain0_0), CERT_STORE_ADD_ALWAYS, NULL);
     engineConfig.hExclusiveRoot = testRoot;
-    if (!CertCreateCertificateChainEngine(&engineConfig, &engine))
+    if (!pCertCreateCertificateChainEngine(&engineConfig, &engine))
     {
         skip("Couldn't create chain engine\n");
         return;
     }
     /* With "winehq.org": no match */
     sslPolicyPara.pwszServerName = winehq;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, engine,
-     &winehqPolicyCheckWithoutMatchingName, 0, &oct2007, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, engine,
+     winehqPolicyCheckWithoutMatchingName, &oct2007, &policyPara);
     /* With "test.winehq.org": match */
     sslPolicyPara.pwszServerName = test_dot_winehq_dot_org;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, engine,
-     &winehqPolicyCheckWithMatchingName, 0, &oct2007, &policyPara);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, engine,
+     winehqPolicyCheckWithMatchingName, &oct2007, &policyPara);
     /* With "a.b.winehq.org": no match */
     sslPolicyPara.pwszServerName = a_dot_b_dot_winehq_dot_org;
-    checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, engine,
-     &winehqPolicyCheckWithoutMatchingName, 0, &oct2007, &policyPara);
-    CertFreeCertificateChainEngine(engine);
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, engine,
+     winehqPolicyCheckWithoutMatchingName, &oct2007, &policyPara);
+    /* When specifying to ignore name mismatch: match */
+    sslPolicyPara.fdwChecks |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, engine,
+     winehqPolicyCheckWithMatchingName, &oct2007, &policyPara);
+    pCertFreeCertificateChainEngine(engine);
     CertCloseStore(testRoot, 0);
+    /* Test chain30, which has an invalid critical extension in an intermediate
+     * cert, against the SSL policy.
+     */
+    sslPolicyPara.fdwChecks = SECURITY_FLAG_IGNORE_UNKNOWN_CA;
+    sslPolicyPara.pwszServerName = NULL;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     invalidExtensionPolicyCheck, &oct2007, &policyPara);
+    /* Test chain31, which has two CNs, "*.foo.com" and "foo.com", against
+     * some names that match one of the CNs:
+     */
+    sslPolicyPara.pwszServerName = foo_dot_com;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     fooPolicyCheckWithMatchingName, &oct2007, &policyPara);
+    sslPolicyPara.pwszServerName = a_dot_foo_dot_com;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     fooPolicyCheckWithMatchingName, &oct2007, &policyPara);
+    /* and against a name that doesn't match either CN: */
+    sslPolicyPara.pwszServerName = afoo_dot_com;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     fooPolicyCheckWithoutMatchingName, &oct2007, &policyPara);
+    /* The Battle.Net chain checks a certificate with a domain component
+     * containg a terminating NULL.
+     */
+    sslPolicyPara.pwszServerName = battle_dot_net;
+    CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL,
+     nullTerminatedDomainComponentPolicyCheck, &oct2010, &policyPara);
 }
 
 static void testVerifyCertChainPolicy(void)
@@ -4210,7 +4751,6 @@ static void testVerifyCertChainPolicy(void)
     PCCERT_CHAIN_CONTEXT chain;
     CERT_CHAIN_POLICY_STATUS policyStatus = { 0 };
     CERT_CHAIN_POLICY_PARA policyPara = { 0 };
-    DWORD i;
 
     if (!pCertVerifyCertificateChainPolicy)
     {
@@ -4248,40 +4788,29 @@ static void testVerifyCertChainPolicy(void)
     ret = pCertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_BASE, chain, NULL,
      &policyStatus);
     ok(ret, "CertVerifyCertificateChainPolicy failed: %08x\n", GetLastError());
-    ok(policyStatus.dwError == CERT_E_UNTRUSTEDROOT,
-     "Expected CERT_E_UNTRUSTEDROOT, got %08x\n", policyStatus.dwError);
+    ok(policyStatus.dwError == CERT_E_UNTRUSTEDROOT ||
+        policyStatus.dwError == TRUST_E_CERT_SIGNATURE, /* win7 + win8 */
+        "Expected CERT_E_UNTRUSTEDROOT or TRUST_E_CERT_SIGNATURE, got %08x\n", policyStatus.dwError);
     ok(policyStatus.lChainIndex == 0 && policyStatus.lElementIndex == 0,
      "Expected both indexes 0, got %d, %d\n", policyStatus.lChainIndex,
      policyStatus.lElementIndex);
     ret = pCertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_BASE, chain,
      &policyPara, &policyStatus);
     ok(ret, "CertVerifyCertificateChainPolicy failed: %08x\n", GetLastError());
-    ok(policyStatus.dwError == CERT_E_UNTRUSTEDROOT,
-     "Expected CERT_E_UNTRUSTEDROOT, got %08x\n", policyStatus.dwError);
+    ok(policyStatus.dwError == CERT_E_UNTRUSTEDROOT ||
+        policyStatus.dwError == TRUST_E_CERT_SIGNATURE, /* win7 + win8 */
+        "Expected CERT_E_UNTRUSTEDROOT or TRUST_E_CERT_SIGNATURE, got %08x\n", policyStatus.dwError);
     ok(policyStatus.lChainIndex == 0 && policyStatus.lElementIndex == 0,
      "Expected both indexes 0, got %d, %d\n", policyStatus.lChainIndex,
      policyStatus.lElementIndex);
     pCertFreeCertificateChain(chain);
     CertFreeCertificateContext(cert);
 
-    for (i = 0;
-     i < sizeof(basePolicyCheck) / sizeof(basePolicyCheck[0]); i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_BASE, NULL,
-         &basePolicyCheck[i], i, &oct2007, NULL);
+    check_base_policy();
     check_ssl_policy();
-    /* The authenticode policy doesn't seem to check anything beyond the base
-     * policy.  It might check for chains signed by the MS test cert, but none
-     * of these chains is.
-     */
-    for (i = 0; i <
-     sizeof(authenticodePolicyCheck) / sizeof(authenticodePolicyCheck[0]); i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_AUTHENTICODE, NULL,
-         &authenticodePolicyCheck[i], i, &oct2007, NULL);
-    for (i = 0; i <
-     sizeof(basicConstraintsPolicyCheck) / sizeof(basicConstraintsPolicyCheck[0]);
-     i++)
-        checkChainPolicyStatus(CERT_CHAIN_POLICY_BASIC_CONSTRAINTS, NULL,
-         &basicConstraintsPolicyCheck[i], i, &oct2007, NULL);
+    check_authenticode_policy();
+    CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_BASIC_CONSTRAINTS, NULL,
+     basicConstraintsPolicyCheck, &oct2007, NULL);
 }
 
 START_TEST(chain)
@@ -4294,9 +4823,9 @@ START_TEST(chain)
     pCertVerifyCertificateChainPolicy = (void*)GetProcAddress(hCrypt32, "CertVerifyCertificateChainPolicy");
 
     testCreateCertChainEngine();
-    if (!pCertGetCertificateChain)
+    if (!pCertGetCertificateChain || !pCertFreeCertificateChain)
     {
-        win_skip("CertGetCertificateChain() is not available\n");
+        win_skip("Cert*CertificateChain functions not available\n");
     }
     else
     {