1 /* 2 * crypt32 cert store function tests 3 * 4 * Copyright 2005-2006 Juan Lang 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdio.h> 22 #include <stdarg.h> 23 24 #include <windef.h> 25 #include <winbase.h> 26 #include <winuser.h> 27 #include <shlobj.h> 28 #include <shlwapi.h> 29 #include <winreg.h> 30 #include <winerror.h> 31 #include <wincrypt.h> 32 33 #include "wine/test.h" 34 35 /* The following aren't defined in wincrypt.h, as they're "reserved" */ 36 #define CERT_CERT_PROP_ID 32 37 #define CERT_CRL_PROP_ID 33 38 #define CERT_CTL_PROP_ID 34 39 40 struct CertPropIDHeader 41 { 42 DWORD propID; 43 DWORD unknown1; 44 DWORD cb; 45 }; 46 47 static const BYTE emptyCert[] = { 0x30, 0x00 }; 48 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 49 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 50 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 51 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 52 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 53 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 54 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 55 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 56 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 57 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; 58 static const BYTE signedBigCert[] = { 59 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30, 60 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 61 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 62 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 63 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 64 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 65 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 66 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 67 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 68 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 69 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 70 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; 71 static const BYTE serializedCert[] = { 0x20, 0x00, 0x00, 0x00, 72 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x7a, 0x02, 0x01, 0x01, 73 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 74 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 75 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 76 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 77 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 78 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 79 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 80 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 81 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 82 0x01, 0x01 }; 83 static const BYTE signedCRL[] = { 0x30, 0x45, 0x30, 0x2c, 0x30, 0x02, 0x06, 84 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 85 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 86 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 87 0x30, 0x5a, 0x30, 0x02, 0x06, 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 88 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; 89 static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 90 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 91 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 92 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 93 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 94 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 95 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 96 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 97 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 98 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; 99 static const BYTE signedCTLWithCTLInnerContent[] = { 100 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, 101 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06, 102 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09, 103 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00, 104 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 105 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05, 106 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31, 107 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20, 108 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 109 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86, 110 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04, 111 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d, 112 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9, 113 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04, 114 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf, 115 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1, 116 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f, 117 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23, 118 0x57,0x6c,0x0b,0x47,0xb8 }; 119 120 #define test_store_is_empty(store) _test_store_is_empty(__LINE__,store) 121 static void _test_store_is_empty(unsigned line, HCERTSTORE store) 122 { 123 const CERT_CONTEXT *cert; 124 125 cert = CertEnumCertificatesInStore(store, NULL); 126 ok_(__FILE__,line)(!cert && GetLastError() == CRYPT_E_NOT_FOUND, "store is not empty\n"); 127 } 128 129 static void testMemStore(void) 130 { 131 HCERTSTORE store1, store2; 132 PCCERT_CONTEXT context; 133 BOOL ret; 134 DWORD GLE; 135 136 /* NULL provider */ 137 store1 = CertOpenStore(0, 0, 0, 0, NULL); 138 ok(!store1 && GetLastError() == ERROR_FILE_NOT_FOUND, 139 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); 140 /* weird flags */ 141 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 142 CERT_STORE_DELETE_FLAG, NULL); 143 ok(!store1 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, 144 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %d\n", GetLastError()); 145 146 /* normal */ 147 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 148 CERT_STORE_CREATE_NEW_FLAG, NULL); 149 ok(store1 != NULL, "CertOpenStore failed: %d\n", GetLastError()); 150 /* open existing doesn't */ 151 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 152 CERT_STORE_OPEN_EXISTING_FLAG, NULL); 153 ok(store2 != NULL, "CertOpenStore failed: %d\n", GetLastError()); 154 ok(store1 != store2, "Expected different stores\n"); 155 156 /* add a bogus (empty) cert */ 157 context = NULL; 158 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, emptyCert, 159 sizeof(emptyCert), CERT_STORE_ADD_ALWAYS, &context); 160 /* Windows returns CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, but accept 161 * CRYPT_E_ASN1_CORRUPT as well (because matching errors is tough in this 162 * case) 163 */ 164 GLE = GetLastError(); 165 ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == CRYPT_E_ASN1_CORRUPT || 166 GLE == OSS_DATA_ERROR), 167 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 168 GLE); 169 /* add a "signed" cert--the signature isn't a real signature, so this adds 170 * without any check of the signature's validity 171 */ 172 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, 173 signedBigCert, sizeof(signedBigCert), CERT_STORE_ADD_ALWAYS, &context); 174 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 175 ok(context != NULL, "Expected a valid cert context\n"); 176 if (context) 177 { 178 ok(context->cbCertEncoded == sizeof(signedBigCert), 179 "Wrong cert size %d\n", context->cbCertEncoded); 180 ok(!memcmp(context->pbCertEncoded, signedBigCert, 181 sizeof(signedBigCert)), "Unexpected encoded cert in context\n"); 182 /* remove it, the rest of the tests will work on an unsigned cert */ 183 ret = CertDeleteCertificateFromStore(context); 184 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n", 185 GetLastError()); 186 } 187 /* try adding a "signed" CRL as a cert */ 188 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, 189 signedCRL, sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &context); 190 GLE = GetLastError(); 191 ok(!ret && (GLE == CRYPT_E_ASN1_BADTAG || GLE == CRYPT_E_ASN1_CORRUPT || 192 GLE == OSS_DATA_ERROR), 193 "Expected CRYPT_E_ASN1_BADTAG or CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 194 GLE); 195 /* add a cert to store1 */ 196 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, bigCert, 197 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context); 198 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 199 ok(context != NULL, "Expected a valid cert context\n"); 200 if (context) 201 { 202 DWORD size; 203 BYTE *buf; 204 205 ok(context->cbCertEncoded == sizeof(bigCert), 206 "Wrong cert size %d\n", context->cbCertEncoded); 207 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)), 208 "Unexpected encoded cert in context\n"); 209 ok(context->hCertStore == store1, "Unexpected store\n"); 210 211 /* check serializing this element */ 212 /* These crash 213 ret = CertSerializeCertificateStoreElement(NULL, 0, NULL, NULL); 214 ret = CertSerializeCertificateStoreElement(context, 0, NULL, NULL); 215 ret = CertSerializeCertificateStoreElement(NULL, 0, NULL, &size); 216 */ 217 /* apparently flags are ignored */ 218 ret = CertSerializeCertificateStoreElement(context, 1, NULL, &size); 219 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", 220 GetLastError()); 221 buf = HeapAlloc(GetProcessHeap(), 0, size); 222 if (buf) 223 { 224 ret = CertSerializeCertificateStoreElement(context, 0, buf, &size); 225 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", GetLastError()); 226 ok(size == sizeof(serializedCert), "Wrong size %d\n", size); 227 ok(!memcmp(serializedCert, buf, size), 228 "Unexpected serialized cert\n"); 229 HeapFree(GetProcessHeap(), 0, buf); 230 } 231 232 ret = CertFreeCertificateContext(context); 233 ok(ret, "CertFreeCertificateContext failed: %08x\n", GetLastError()); 234 } 235 /* verify the cert's in store1 */ 236 context = CertEnumCertificatesInStore(store1, NULL); 237 ok(context != NULL, "Expected a valid context\n"); 238 context = CertEnumCertificatesInStore(store1, context); 239 ok(!context && GetLastError() == CRYPT_E_NOT_FOUND, 240 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 241 /* verify store2 (the "open existing" mem store) is still empty */ 242 context = CertEnumCertificatesInStore(store2, NULL); 243 ok(!context, "Expected an empty store\n"); 244 /* delete the cert from store1, and check it's empty */ 245 context = CertEnumCertificatesInStore(store1, NULL); 246 if (context) 247 { 248 /* Deleting a bitwise copy crashes with an access to an uninitialized 249 * pointer, so a cert context has some special data out there in memory 250 * someplace 251 CERT_CONTEXT copy; 252 memcpy(©, context, sizeof(copy)); 253 ret = CertDeleteCertificateFromStore(©); 254 */ 255 PCCERT_CONTEXT copy = CertDuplicateCertificateContext(context); 256 257 ok(copy != NULL, "CertDuplicateCertificateContext failed: %08x\n", 258 GetLastError()); 259 ret = CertDeleteCertificateFromStore(context); 260 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n", 261 GetLastError()); 262 /* try deleting a copy */ 263 ret = CertDeleteCertificateFromStore(copy); 264 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n", 265 GetLastError()); 266 /* check that the store is empty */ 267 context = CertEnumCertificatesInStore(store1, NULL); 268 ok(!context, "Expected an empty store\n"); 269 } 270 271 /* close an empty store */ 272 ret = CertCloseStore(NULL, 0); 273 ok(ret, "CertCloseStore failed: %d\n", GetLastError()); 274 ret = CertCloseStore(store1, 0); 275 ok(ret, "CertCloseStore failed: %d\n", GetLastError()); 276 ret = CertCloseStore(store2, 0); 277 ok(ret, "CertCloseStore failed: %d\n", GetLastError()); 278 279 /* This seems nonsensical, but you can open a read-only mem store, only 280 * it isn't read-only 281 */ 282 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 283 CERT_STORE_READONLY_FLAG, NULL); 284 ok(store1 != NULL, "CertOpenStore failed: %d\n", GetLastError()); 285 /* yep, this succeeds */ 286 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, bigCert, 287 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context); 288 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 289 ok(context != NULL, "Expected a valid cert context\n"); 290 if (context) 291 { 292 ok(context->cbCertEncoded == sizeof(bigCert), 293 "Wrong cert size %d\n", context->cbCertEncoded); 294 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)), 295 "Unexpected encoded cert in context\n"); 296 ok(context->hCertStore == store1, "Unexpected store\n"); 297 ret = CertDeleteCertificateFromStore(context); 298 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n", 299 GetLastError()); 300 } 301 CertCloseStore(store1, 0); 302 } 303 304 static void compareStore(HCERTSTORE store, LPCSTR name, const BYTE *pb, 305 DWORD cb, BOOL todo) 306 { 307 BOOL ret; 308 CRYPT_DATA_BLOB blob = { 0, NULL }; 309 310 ret = CertSaveStore(store, X509_ASN_ENCODING, CERT_STORE_SAVE_AS_STORE, 311 CERT_STORE_SAVE_TO_MEMORY, &blob, 0); 312 ok(ret, "CertSaveStore failed: %08x\n", GetLastError()); 313 todo_wine_if (todo) 314 ok(blob.cbData == cb, "%s: expected size %d, got %d\n", name, cb, 315 blob.cbData); 316 blob.pbData = HeapAlloc(GetProcessHeap(), 0, blob.cbData); 317 if (blob.pbData) 318 { 319 ret = CertSaveStore(store, X509_ASN_ENCODING, CERT_STORE_SAVE_AS_STORE, 320 CERT_STORE_SAVE_TO_MEMORY, &blob, 0); 321 ok(ret, "CertSaveStore failed: %08x\n", GetLastError()); 322 todo_wine_if (todo) 323 ok(!memcmp(pb, blob.pbData, cb), "%s: unexpected value\n", name); 324 HeapFree(GetProcessHeap(), 0, blob.pbData); 325 } 326 } 327 328 static const BYTE serializedStoreWithCert[] = { 329 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x20,0x00,0x00,0x00,0x01,0x00,0x00, 330 0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30, 331 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, 332 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31, 333 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36, 334 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15, 335 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 336 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00, 337 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04, 338 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 339 0x00,0x00,0x00,0x00,0x00,0x00 }; 340 341 static const struct 342 { 343 HKEY key; 344 DWORD cert_store; 345 BOOL appdata_file; 346 WCHAR store_name[16]; 347 const WCHAR *base_reg_path; 348 } reg_store_saved_certs[] = { 349 { HKEY_LOCAL_MACHINE, CERT_SYSTEM_STORE_LOCAL_MACHINE, FALSE, 350 {'R','O','O','T',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH }, 351 { HKEY_LOCAL_MACHINE, CERT_SYSTEM_STORE_LOCAL_MACHINE, FALSE, 352 {'M','Y',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH }, 353 { HKEY_LOCAL_MACHINE, CERT_SYSTEM_STORE_LOCAL_MACHINE, FALSE, 354 {'C','A',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH }, 355 /* Adding to HKCU\Root triggers safety warning. */ 356 { HKEY_CURRENT_USER, CERT_SYSTEM_STORE_CURRENT_USER, TRUE, 357 {'M','Y',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH }, 358 { HKEY_CURRENT_USER, CERT_SYSTEM_STORE_CURRENT_USER, FALSE, 359 {'C','A',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH } 360 }; 361 362 /* Testing whether system stores are available for adding new certs 363 * and checking directly in the registry whether they are actually saved or deleted. 364 * Windows treats HKCU\My (at least) as a special case and uses AppData directory 365 * for storing certs, not registry. 366 */ 367 static void testRegStoreSavedCerts(void) 368 { 369 static const WCHAR fmt[] = 370 { '%','s','\\','%','s','\\','%','s','\\','%','s',0}, 371 ms_certs[] = 372 { 'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m','C','e','r','t','i','f','i','c','a','t','e','s',0}, 373 certs[] = 374 {'C','e','r','t','i','f','i','c','a','t','e','s',0}, 375 bigCert_hash[] = { 376 '6','E','3','0','9','0','7','1','5','F','D','9','2','3', 377 '5','6','E','B','A','E','2','5','4','0','E','6','2','2', 378 'D','A','1','9','2','6','0','2','A','6','0','8',0}; 379 PCCERT_CONTEXT cert1, cert2; 380 HCERTSTORE store; 381 HANDLE cert_file; 382 HRESULT pathres; 383 WCHAR key_name[MAX_PATH], appdata_path[MAX_PATH]; 384 HKEY key; 385 BOOL ret; 386 DWORD res,i; 387 388 for (i = 0; i < ARRAY_SIZE(reg_store_saved_certs); i++) 389 { 390 DWORD err; 391 392 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, 393 reg_store_saved_certs[i].cert_store, reg_store_saved_certs[i].store_name); 394 395 err = GetLastError(); 396 if (!store) 397 { 398 ok (err == ERROR_ACCESS_DENIED, "Failed to create store at %d (%08x)\n", i, err); 399 skip("Insufficient privileges for the test %d\n", i); 400 continue; 401 } 402 ok (store!=NULL, "Failed to open the store at %d, %x\n", i, GetLastError()); 403 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); 404 ok (cert1 != NULL, "Create cert context failed at %d, %x\n", i, GetLastError()); 405 ret = CertAddCertificateContextToStore(store, cert1, CERT_STORE_ADD_REPLACE_EXISTING, NULL); 406 /* Addittional skip per Win7, it allows opening HKLM store, but disallows adding certs */ 407 err = GetLastError(); 408 if (!ret) 409 { 410 ok (err == ERROR_ACCESS_DENIED, "Failed to add certificate to store at %d (%08x)\n", i, err); 411 skip("Insufficient privileges for the test %d\n", i); 412 continue; 413 } 414 ok (ret, "Adding to the store failed at %d, %x\n", i, err); 415 CertFreeCertificateContext(cert1); 416 CertCloseStore(store, 0); 417 418 wsprintfW(key_name, fmt, reg_store_saved_certs[i].base_reg_path, 419 reg_store_saved_certs[i].store_name, certs, bigCert_hash); 420 421 if (!reg_store_saved_certs[i].appdata_file) 422 { 423 res = RegOpenKeyExW(reg_store_saved_certs[i].key, key_name, 0, KEY_ALL_ACCESS, &key); 424 ok (!res, "The cert hasn't been saved at %d, %x\n", i, GetLastError()); 425 if (!res) RegCloseKey(key); 426 } else 427 { 428 pathres = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, appdata_path); 429 ok (pathres == S_OK, 430 "Failed to get app data path at %d (%x)\n", pathres, GetLastError()); 431 if (pathres == S_OK) 432 { 433 PathAppendW(appdata_path, ms_certs); 434 PathAppendW(appdata_path, reg_store_saved_certs[i].store_name); 435 PathAppendW(appdata_path, certs); 436 PathAppendW(appdata_path, bigCert_hash); 437 438 cert_file = CreateFileW(appdata_path, GENERIC_READ, 0, NULL, 439 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 440 todo_wine ok (cert_file != INVALID_HANDLE_VALUE, 441 "Cert was not saved in AppData at %d (%x)\n", i, GetLastError()); 442 CloseHandle(cert_file); 443 } 444 } 445 446 /* deleting cert from store */ 447 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, 448 reg_store_saved_certs[i].cert_store, reg_store_saved_certs[i].store_name); 449 ok (store!=NULL, "Failed to open the store at %d, %x\n", i, GetLastError()); 450 451 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); 452 ok (cert1 != NULL, "Create cert context failed at %d, %x\n", i, GetLastError()); 453 454 cert2 = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 455 CERT_FIND_EXISTING, cert1, NULL); 456 ok (cert2 != NULL, "Failed to find cert in the store at %d, %x\n", i, GetLastError()); 457 458 ret = CertDeleteCertificateFromStore(cert2); 459 ok (ret, "Failed to delete certificate from store at %d, %x\n", i, GetLastError()); 460 461 CertFreeCertificateContext(cert1); 462 CertFreeCertificateContext(cert2); 463 CertCloseStore(store, 0); 464 465 res = RegOpenKeyExW(reg_store_saved_certs[i].key, key_name, 0, KEY_ALL_ACCESS, &key); 466 ok (res, "The cert's registry entry should be absent at %i, %x\n", i, GetLastError()); 467 if (!res) RegCloseKey(key); 468 469 if (reg_store_saved_certs[i].appdata_file) 470 { 471 cert_file = CreateFileW(appdata_path, GENERIC_READ, 0, NULL, 472 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 473 ok (cert_file == INVALID_HANDLE_VALUE, 474 "Cert should have been absent in AppData %d\n", i); 475 476 CloseHandle(cert_file); 477 } 478 } 479 } 480 481 /** 482 * This test checks that certificate falls into correct store of a collection 483 * depending on the access flags and priorities. 484 */ 485 static void testStoresInCollection(void) 486 { 487 PCCERT_CONTEXT cert1, cert2, tcert1; 488 HCERTSTORE collection, ro_store, rw_store, rw_store_2, tstore; 489 static const WCHAR WineTestRO_W[] = { 'W','i','n','e','T','e','s','t','_','R','O',0 }, 490 WineTestRW_W[] = { 'W','i','n','e','T','e','s','t','_','R','W',0 }, 491 WineTestRW2_W[]= { 'W','i','n','e','T','e','s','t','_','R','W','2',0 }; 492 BOOL ret; 493 494 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 495 CERT_STORE_CREATE_NEW_FLAG, NULL); 496 ok(collection != NULL, "Failed to init collection store, last error %x\n", GetLastError()); 497 /* Add read-only store to collection with very high priority*/ 498 ro_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, 499 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRO_W); 500 ok(ro_store != NULL, "Failed to init ro store %x\n", GetLastError()); 501 502 ret = CertAddStoreToCollection(collection, ro_store, 0, 1000); 503 ok (ret, "Failed to add read-only store to collection %x\n", GetLastError()); 504 505 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); 506 ok (cert1 != NULL, "Create cert context failed %x\n", GetLastError()); 507 ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_ALWAYS, NULL); 508 ok (!ret, "Added cert to collection with single read-only store %x\n", GetLastError()); 509 510 /* Add read-write store to collection with the lowest priority*/ 511 rw_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, 512 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW_W); 513 ok (rw_store != NULL, "Failed to open rw store %x\n", GetLastError()); 514 ret = CertAddStoreToCollection(collection, rw_store, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 515 ok (ret, "Failed to add rw store to collection %x\n", GetLastError()); 516 /** Adding certificate to collection should fall into rw store, 517 * even though prioirty of the ro_store is higher */ 518 ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_REPLACE_EXISTING, NULL); 519 ok (ret, "Failed to add cert to the collection %x\n", GetLastError()); 520 521 tcert1 = CertEnumCertificatesInStore(ro_store, NULL); 522 ok (!tcert1, "Read-only ro_store contains cert\n"); 523 524 tcert1 = CertEnumCertificatesInStore(rw_store, NULL); 525 ok (cert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, 526 "Unexpected cert in the rw store\n"); 527 CertFreeCertificateContext(tcert1); 528 529 tcert1 = CertEnumCertificatesInStore(collection, NULL); 530 ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, 531 "Unexpected cert in the collection\n"); 532 CertFreeCertificateContext(tcert1); 533 534 /** adding one more rw store with higher priority*/ 535 rw_store_2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, 536 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW2_W); 537 ok (rw_store_2 != NULL, "Failed to init second rw store %x\n", GetLastError()); 538 ret = CertAddStoreToCollection(collection, rw_store_2, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 50); 539 ok (ret, "Failed to add rw_store_2 to collection %x\n",GetLastError()); 540 541 cert2 = CertCreateCertificateContext(X509_ASN_ENCODING, signedBigCert, sizeof(signedBigCert)); 542 ok (cert2 != NULL, "Failed to create cert context %x\n", GetLastError()); 543 ret = CertAddCertificateContextToStore(collection, cert2, CERT_STORE_ADD_REPLACE_EXISTING, NULL); 544 ok (ret, "Failed to add cert2 to the store %x\n",GetLastError()); 545 546 /** checking certificates in the stores */ 547 tcert1 = CertEnumCertificatesInStore(ro_store, 0); 548 ok (tcert1 == NULL, "Read-only store not empty\n"); 549 550 tcert1 = CertEnumCertificatesInStore(rw_store, NULL); 551 ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, 552 "Unexpected cert in the rw_store\n"); 553 CertFreeCertificateContext(tcert1); 554 555 tcert1 = CertEnumCertificatesInStore(rw_store_2, NULL); 556 ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, 557 "Unexpected cert in the rw_store_2\n"); 558 CertFreeCertificateContext(tcert1); 559 560 /** checking certificates in the collection */ 561 tcert1 = CertEnumCertificatesInStore(collection, NULL); 562 ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, 563 "cert2 expected in the collection got %p, %x\n",tcert1, GetLastError()); 564 tcert1 = CertEnumCertificatesInStore(collection, tcert1); 565 ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, 566 "cert1 expected in the collection got %p, %x\n",tcert1, GetLastError()); 567 tcert1 = CertEnumCertificatesInStore(collection, tcert1); 568 ok (tcert1==NULL,"Unexpected cert in the collection %p %x\n",tcert1, GetLastError()); 569 570 /* checking whether certs had been saved */ 571 tstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, 572 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, WineTestRW_W); 573 ok (tstore!=NULL, "Failed to open existing rw store\n"); 574 tcert1 = CertEnumCertificatesInStore(tstore, NULL); 575 todo_wine 576 ok(tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, "cert1 wasn't saved\n"); 577 CertFreeCertificateContext(tcert1); 578 CertCloseStore(tstore,0); 579 580 tstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, 581 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, WineTestRW2_W); 582 ok (tstore!=NULL, "Failed to open existing rw2 store\n"); 583 tcert1 = CertEnumCertificatesInStore(tstore, NULL); 584 todo_wine 585 ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, "cert2 wasn't saved\n"); 586 CertFreeCertificateContext(tcert1); 587 CertCloseStore(tstore,0); 588 589 CertCloseStore(collection,0); 590 CertCloseStore(ro_store,0); 591 CertCloseStore(rw_store,0); 592 CertCloseStore(rw_store_2,0); 593 594 /* reopening registry stores to check whether certs had been saved */ 595 rw_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, 596 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW_W); 597 tcert1 = CertEnumCertificatesInStore(rw_store, NULL); 598 ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, 599 "Unexpected cert in store %p\n", tcert1); 600 CertFreeCertificateContext(tcert1); 601 CertCloseStore(rw_store,0); 602 603 rw_store_2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, 604 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW2_W); 605 tcert1 = CertEnumCertificatesInStore(rw_store_2, NULL); 606 ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, 607 "Unexpected cert in store %p\n", tcert1); 608 CertFreeCertificateContext(tcert1); 609 CertCloseStore(rw_store_2,0); 610 611 CertFreeCertificateContext(cert1); 612 CertFreeCertificateContext(cert2); 613 CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, 614 CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRO_W); 615 CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, 616 CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW_W); 617 CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, 618 CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW2_W); 619 620 } 621 622 static void testCollectionStore(void) 623 { 624 HCERTSTORE store1, store2, collection, collection2; 625 PCCERT_CONTEXT context; 626 BOOL ret; 627 static const WCHAR szPrefix[] = { 'c','e','r',0 }; 628 static const WCHAR szDot[] = { '.',0 }; 629 WCHAR filename[MAX_PATH]; 630 HANDLE file; 631 632 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 633 CERT_STORE_CREATE_NEW_FLAG, NULL); 634 635 /* Try adding a cert to any empty collection */ 636 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING, 637 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 638 ok(!ret && GetLastError() == E_ACCESSDENIED, 639 "Expected E_ACCESSDENIED, got %08x\n", GetLastError()); 640 641 /* Create and add a cert to a memory store */ 642 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 643 CERT_STORE_CREATE_NEW_FLAG, NULL); 644 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, 645 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 646 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 647 /* Add the memory store to the collection, without allowing adding */ 648 ret = CertAddStoreToCollection(collection, store1, 0, 0); 649 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError()); 650 /* Verify the cert is in the collection */ 651 context = CertEnumCertificatesInStore(collection, NULL); 652 ok(context != NULL, "Expected a valid context\n"); 653 if (context) 654 { 655 ok(context->hCertStore == collection, "Unexpected store\n"); 656 CertFreeCertificateContext(context); 657 } 658 /* Check that adding to the collection isn't allowed */ 659 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING, 660 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_ALWAYS, NULL); 661 ok(!ret && GetLastError() == E_ACCESSDENIED, 662 "Expected E_ACCESSDENIED, got %08x\n", GetLastError()); 663 664 /* Create a new memory store */ 665 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 666 CERT_STORE_CREATE_NEW_FLAG, NULL); 667 /* Try adding a store to a non-collection store */ 668 ret = CertAddStoreToCollection(store1, store2, 669 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 670 ok(!ret && GetLastError() == E_INVALIDARG, 671 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 672 /* Try adding some bogus stores */ 673 /* This crashes in Windows 674 ret = pCertAddStoreToCollection(0, store2, 675 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 676 */ 677 /* This "succeeds"... */ 678 ret = CertAddStoreToCollection(collection, 0, 679 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 680 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError()); 681 /* while this crashes. 682 ret = pCertAddStoreToCollection(collection, 1, 683 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 684 */ 685 686 /* Add it to the collection, this time allowing adding */ 687 ret = CertAddStoreToCollection(collection, store2, 688 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 689 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError()); 690 /* Check that adding to the collection is allowed */ 691 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING, 692 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_ALWAYS, NULL); 693 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 694 /* Now check that it was actually added to store2 */ 695 context = CertEnumCertificatesInStore(store2, NULL); 696 ok(context != NULL, "Expected a valid context\n"); 697 if (context) 698 { 699 ok(context->hCertStore == store2, "Unexpected store\n"); 700 CertFreeCertificateContext(context); 701 } 702 /* Check that the collection has both bigCert and bigCert2. bigCert comes 703 * first because store1 was added first. 704 */ 705 context = CertEnumCertificatesInStore(collection, NULL); 706 ok(context != NULL, "Expected a valid context\n"); 707 if (context) 708 { 709 ok(context->hCertStore == collection, "Unexpected store\n"); 710 ok(context->cbCertEncoded == sizeof(bigCert), 711 "Wrong size %d\n", context->cbCertEncoded); 712 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded), 713 "Unexpected cert\n"); 714 context = CertEnumCertificatesInStore(collection, context); 715 ok(context != NULL, "Expected a valid context\n"); 716 if (context) 717 { 718 ok(context->hCertStore == collection, "Unexpected store\n"); 719 ok(context->cbCertEncoded == sizeof(bigCert2), 720 "Wrong size %d\n", context->cbCertEncoded); 721 ok(!memcmp(context->pbCertEncoded, bigCert2, 722 context->cbCertEncoded), "Unexpected cert\n"); 723 context = CertEnumCertificatesInStore(collection, context); 724 ok(!context, "Unexpected cert\n"); 725 } 726 } 727 /* close store2, and check that the collection is unmodified */ 728 CertCloseStore(store2, 0); 729 context = CertEnumCertificatesInStore(collection, NULL); 730 ok(context != NULL, "Expected a valid context\n"); 731 if (context) 732 { 733 ok(context->hCertStore == collection, "Unexpected store\n"); 734 ok(context->cbCertEncoded == sizeof(bigCert), 735 "Wrong size %d\n", context->cbCertEncoded); 736 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded), 737 "Unexpected cert\n"); 738 context = CertEnumCertificatesInStore(collection, context); 739 ok(context != NULL, "Expected a valid context\n"); 740 if (context) 741 { 742 ok(context->hCertStore == collection, "Unexpected store\n"); 743 ok(context->cbCertEncoded == sizeof(bigCert2), 744 "Wrong size %d\n", context->cbCertEncoded); 745 ok(!memcmp(context->pbCertEncoded, bigCert2, 746 context->cbCertEncoded), "Unexpected cert\n"); 747 context = CertEnumCertificatesInStore(collection, context); 748 ok(!context, "Unexpected cert\n"); 749 } 750 } 751 752 /* Adding a collection to a collection is legal */ 753 collection2 = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 754 CERT_STORE_CREATE_NEW_FLAG, NULL); 755 ret = CertAddStoreToCollection(collection2, collection, 756 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 757 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError()); 758 /* check the contents of collection2 */ 759 context = CertEnumCertificatesInStore(collection2, NULL); 760 ok(context != NULL, "Expected a valid context\n"); 761 if (context) 762 { 763 ok(context->hCertStore == collection2, "Unexpected store\n"); 764 ok(context->cbCertEncoded == sizeof(bigCert), 765 "Wrong size %d\n", context->cbCertEncoded); 766 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded), 767 "Unexpected cert\n"); 768 context = CertEnumCertificatesInStore(collection2, context); 769 ok(context != NULL, "Expected a valid context\n"); 770 if (context) 771 { 772 ok(context->hCertStore == collection2, "Unexpected store\n"); 773 ok(context->cbCertEncoded == sizeof(bigCert2), 774 "Wrong size %d\n", context->cbCertEncoded); 775 ok(!memcmp(context->pbCertEncoded, bigCert2, 776 context->cbCertEncoded), "Unexpected cert\n"); 777 context = CertEnumCertificatesInStore(collection2, context); 778 ok(!context, "Unexpected cert\n"); 779 } 780 } 781 782 /* I'd like to test closing the collection in the middle of enumeration, 783 * but my tests have been inconsistent. The first time calling 784 * CertEnumCertificatesInStore on a closed collection succeeded, while the 785 * second crashed. So anything appears to be fair game. 786 * I'd also like to test removing a store from a collection in the middle 787 * of an enumeration, but my tests in Windows have been inconclusive. 788 * In one scenario it worked. In another scenario, about a third of the 789 * time this leads to "random" crashes elsewhere in the code. This 790 * probably means this is not allowed. 791 */ 792 793 CertCloseStore(store1, 0); 794 CertCloseStore(collection, 0); 795 CertCloseStore(collection2, 0); 796 797 /* Add the same cert to two memory stores, then put them in a collection */ 798 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 799 CERT_STORE_CREATE_NEW_FLAG, NULL); 800 ok(store1 != 0, "CertOpenStore failed: %08x\n", GetLastError()); 801 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 802 CERT_STORE_CREATE_NEW_FLAG, NULL); 803 ok(store2 != 0, "CertOpenStore failed: %08x\n", GetLastError()); 804 805 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, 806 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 807 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 808 ret = CertAddEncodedCertificateToStore(store2, X509_ASN_ENCODING, 809 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 810 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 811 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 812 CERT_STORE_CREATE_NEW_FLAG, NULL); 813 ok(collection != 0, "CertOpenStore failed: %08x\n", GetLastError()); 814 815 ret = CertAddStoreToCollection(collection, store1, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 816 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError()); 817 ret = CertAddStoreToCollection(collection, store2, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 818 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError()); 819 820 /* Check that the collection has two copies of the same cert */ 821 context = CertEnumCertificatesInStore(collection, NULL); 822 ok(context != NULL, "Expected a valid context\n"); 823 if (context) 824 { 825 ok(context->hCertStore == collection, "Unexpected store\n"); 826 ok(context->cbCertEncoded == sizeof(bigCert), 827 "Wrong size %d\n", context->cbCertEncoded); 828 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded), 829 "Unexpected cert\n"); 830 context = CertEnumCertificatesInStore(collection, context); 831 ok(context != NULL, "Expected a valid context\n"); 832 if (context) 833 { 834 ok(context->hCertStore == collection, "Unexpected store\n"); 835 ok(context->cbCertEncoded == sizeof(bigCert), 836 "Wrong size %d\n", context->cbCertEncoded); 837 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded), 838 "Unexpected cert\n"); 839 context = CertEnumCertificatesInStore(collection, context); 840 ok(context == NULL, "Unexpected cert\n"); 841 } 842 } 843 844 /* The following would check whether I can delete an identical cert, rather 845 * than one enumerated from the store. It crashes, so that means I must 846 * only call CertDeleteCertificateFromStore with contexts enumerated from 847 * the store. 848 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, 849 sizeof(bigCert)); 850 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n", 851 GetLastError()); 852 if (context) 853 { 854 ret = CertDeleteCertificateFromStore(collection, context); 855 printf("ret is %d, GetLastError is %08x\n", ret, GetLastError()); 856 CertFreeCertificateContext(context); 857 } 858 */ 859 860 /* Now check deleting from the collection. */ 861 context = CertEnumCertificatesInStore(collection, NULL); 862 ok(context != NULL, "Expected a valid context\n"); 863 if (context) 864 { 865 CertDeleteCertificateFromStore(context); 866 /* store1 should now be empty */ 867 context = CertEnumCertificatesInStore(store1, NULL); 868 ok(!context, "Unexpected cert\n"); 869 /* and there should be one certificate in the collection */ 870 context = CertEnumCertificatesInStore(collection, NULL); 871 ok(context != NULL, "Expected a valid cert\n"); 872 if (context) 873 { 874 ok(context->hCertStore == collection, "Unexpected store\n"); 875 ok(context->cbCertEncoded == sizeof(bigCert), 876 "Wrong size %d\n", context->cbCertEncoded); 877 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded), 878 "Unexpected cert\n"); 879 } 880 context = CertEnumCertificatesInStore(collection, context); 881 ok(context == NULL, "Unexpected cert\n"); 882 } 883 884 /* Finally, test removing stores from the collection. No return 885 * value, so it's a bit funny to test. 886 */ 887 /* This crashes 888 * CertRemoveStoreFromCollection(NULL, NULL); 889 */ 890 /* This "succeeds," no crash, no last error set */ 891 SetLastError(0xdeadbeef); 892 CertRemoveStoreFromCollection(store2, collection); 893 ok(GetLastError() == 0xdeadbeef, 894 "Didn't expect an error to be set: %08x\n", GetLastError()); 895 896 /* After removing store2, the collection should be empty */ 897 SetLastError(0xdeadbeef); 898 CertRemoveStoreFromCollection(collection, store2); 899 ok(GetLastError() == 0xdeadbeef, 900 "Didn't expect an error to be set: %08x\n", GetLastError()); 901 context = CertEnumCertificatesInStore(collection, NULL); 902 ok(!context, "Unexpected cert\n"); 903 904 CertCloseStore(collection, 0); 905 CertCloseStore(store2, 0); 906 CertCloseStore(store1, 0); 907 908 /* Test adding certificates to and deleting certificates from collections. 909 */ 910 store1 = CertOpenSystemStoreA(0, "My"); 911 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 912 CERT_STORE_CREATE_NEW_FLAG, NULL); 913 914 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, 915 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context); 916 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 917 CertDeleteCertificateFromStore(context); 918 919 CertAddStoreToCollection(collection, store1, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 920 921 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING, 922 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context); 923 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 924 CertDeleteCertificateFromStore(context); 925 926 CertCloseStore(collection, 0); 927 CertCloseStore(store1, 0); 928 929 /* Test whether a collection store can be committed */ 930 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 931 CERT_STORE_CREATE_NEW_FLAG, NULL); 932 933 SetLastError(0xdeadbeef); 934 ret = CertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL); 935 ok(ret, "CertControlStore failed: %08x\n", GetLastError()); 936 937 /* Adding a mem store that can't be committed prevents a successful commit. 938 */ 939 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 940 CERT_STORE_CREATE_NEW_FLAG, NULL); 941 CertAddStoreToCollection(collection, store1, 0, 0); 942 SetLastError(0xdeadbeef); 943 ret = CertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL); 944 ok(!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, 945 "expected ERROR_CALL_NOT_IMPLEMENTED, got %d\n", GetLastError()); 946 CertRemoveStoreFromCollection(collection, store1); 947 CertCloseStore(store1, 0); 948 949 /* Test adding a cert to a collection with a file store, committing the 950 * change to the collection, and comparing the resulting file. 951 */ 952 if (!GetTempFileNameW(szDot, szPrefix, 0, filename)) 953 return; 954 955 DeleteFileW(filename); 956 file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, 957 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 958 if (file == INVALID_HANDLE_VALUE) 959 return; 960 961 store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 962 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file); 963 ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 964 CloseHandle(file); 965 CertAddStoreToCollection(collection, store1, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 966 CertCloseStore(store1, 0); 967 968 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING, 969 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 970 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 971 GetLastError()); 972 ret = CertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL); 973 ok(ret, "CertControlStore failed: %d\n", ret); 974 compareStore(collection, "serialized store with cert", 975 serializedStoreWithCert, sizeof(serializedStoreWithCert), FALSE); 976 CertCloseStore(collection, 0); 977 978 DeleteFileW(filename); 979 } 980 981 /* Looks for the property with ID propID in the buffer buf. Returns a pointer 982 * to its header if found, NULL if not. 983 */ 984 static const struct CertPropIDHeader *findPropID(const BYTE *buf, DWORD size, 985 DWORD propID) 986 { 987 const struct CertPropIDHeader *ret = NULL; 988 BOOL failed = FALSE; 989 990 while (size && !ret && !failed) 991 { 992 if (size < sizeof(struct CertPropIDHeader)) 993 failed = TRUE; 994 else 995 { 996 const struct CertPropIDHeader *hdr = 997 (const struct CertPropIDHeader *)buf; 998 999 size -= sizeof(struct CertPropIDHeader); 1000 buf += sizeof(struct CertPropIDHeader); 1001 if (size < hdr->cb) 1002 failed = TRUE; 1003 else if (hdr->propID == propID) 1004 ret = hdr; 1005 else 1006 { 1007 buf += hdr->cb; 1008 size -= hdr->cb; 1009 } 1010 } 1011 } 1012 return ret; 1013 } 1014 1015 static void testRegStore(void) 1016 { 1017 static const char tempKey[] = "Software\\Wine\\CryptTemp"; 1018 HCERTSTORE store; 1019 LONG rc; 1020 HKEY key = NULL; 1021 DWORD disp, GLE; 1022 1023 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, NULL); 1024 GLE = GetLastError(); 1025 ok(!store && (GLE == ERROR_INVALID_HANDLE || GLE == ERROR_BADKEY), 1026 "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", GLE); 1027 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, key); 1028 GLE = GetLastError(); 1029 ok(!store && (GLE == ERROR_INVALID_HANDLE || GLE == ERROR_BADKEY), 1030 "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", GLE); 1031 1032 /* Opening up any old key works.. */ 1033 key = HKEY_CURRENT_USER; 1034 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, key); 1035 /* Not sure if this is a bug in DuplicateHandle, marking todo_wine for now 1036 */ 1037 todo_wine ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError()); 1038 CertCloseStore(store, 0); 1039 1040 rc = RegCreateKeyExA(HKEY_CURRENT_USER, tempKey, 0, NULL, 0, KEY_ALL_ACCESS, 1041 NULL, &key, NULL); 1042 ok(!rc, "RegCreateKeyExA failed: %d\n", rc); 1043 if (key) 1044 { 1045 BOOL ret; 1046 BYTE hash[20]; 1047 DWORD size, i; 1048 static const char certificates[] = "Certificates\\"; 1049 char subKeyName[sizeof(certificates) + 20 * 2 + 1], *ptr; 1050 HKEY subKey; 1051 PCCERT_CONTEXT context; 1052 1053 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, key); 1054 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError()); 1055 /* Add a certificate. It isn't persisted right away, since it's only 1056 * added to the cache.. 1057 */ 1058 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1059 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_ALWAYS, NULL); 1060 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1061 GetLastError()); 1062 /* so flush the cache to force a commit.. */ 1063 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL); 1064 ok(ret, "CertControlStore failed: %08x\n", GetLastError()); 1065 /* and check that the expected subkey was written. */ 1066 size = sizeof(hash); 1067 ret = CryptHashCertificate(0, 0, 0, bigCert2, sizeof(bigCert2), 1068 hash, &size); 1069 ok(ret, "CryptHashCertificate failed: %d\n", GetLastError()); 1070 strcpy(subKeyName, certificates); 1071 for (i = 0, ptr = subKeyName + sizeof(certificates) - 1; i < size; 1072 i++, ptr += 2) 1073 sprintf(ptr, "%02X", hash[i]); 1074 rc = RegCreateKeyExA(key, subKeyName, 0, NULL, 0, KEY_ALL_ACCESS, NULL, 1075 &subKey, NULL); 1076 ok(!rc, "RegCreateKeyExA failed: %d\n", rc); 1077 if (subKey) 1078 { 1079 LPBYTE buf; 1080 1081 size = 0; 1082 RegQueryValueExA(subKey, "Blob", NULL, NULL, NULL, &size); 1083 buf = HeapAlloc(GetProcessHeap(), 0, size); 1084 if (buf) 1085 { 1086 rc = RegQueryValueExA(subKey, "Blob", NULL, NULL, buf, &size); 1087 ok(!rc, "RegQueryValueExA failed: %d\n", rc); 1088 if (!rc) 1089 { 1090 const struct CertPropIDHeader *hdr; 1091 1092 /* Both the hash and the cert should be present */ 1093 hdr = findPropID(buf, size, CERT_CERT_PROP_ID); 1094 ok(hdr != NULL, "Expected to find a cert property\n"); 1095 if (hdr) 1096 { 1097 ok(hdr->cb == sizeof(bigCert2), 1098 "Wrong size %d of cert property\n", hdr->cb); 1099 ok(!memcmp((const BYTE *)hdr + sizeof(*hdr), bigCert2, 1100 hdr->cb), "Unexpected cert in cert property\n"); 1101 } 1102 hdr = findPropID(buf, size, CERT_HASH_PROP_ID); 1103 ok(hdr != NULL, "Expected to find a hash property\n"); 1104 if (hdr) 1105 { 1106 ok(hdr->cb == sizeof(hash), 1107 "Wrong size %d of hash property\n", hdr->cb); 1108 ok(!memcmp((const BYTE *)hdr + sizeof(*hdr), hash, 1109 hdr->cb), "Unexpected hash in cert property\n"); 1110 } 1111 } 1112 HeapFree(GetProcessHeap(), 0, buf); 1113 } 1114 RegCloseKey(subKey); 1115 } 1116 1117 /* Remove the existing context */ 1118 context = CertEnumCertificatesInStore(store, NULL); 1119 ok(context != NULL, "Expected a cert context\n"); 1120 if (context) 1121 CertDeleteCertificateFromStore(context); 1122 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL); 1123 ok(ret, "CertControlStore failed: %08x\n", GetLastError()); 1124 1125 /* Add a serialized cert with a bogus hash directly to the registry */ 1126 memset(hash, 0, sizeof(hash)); 1127 strcpy(subKeyName, certificates); 1128 for (i = 0, ptr = subKeyName + sizeof(certificates) - 1; 1129 i < sizeof(hash); i++, ptr += 2) 1130 sprintf(ptr, "%02X", hash[i]); 1131 rc = RegCreateKeyExA(key, subKeyName, 0, NULL, 0, KEY_ALL_ACCESS, NULL, 1132 &subKey, NULL); 1133 ok(!rc, "RegCreateKeyExA failed: %d\n", rc); 1134 if (subKey) 1135 { 1136 BYTE buf[sizeof(struct CertPropIDHeader) * 2 + sizeof(hash) + 1137 sizeof(bigCert)], *ptr; 1138 DWORD certCount = 0; 1139 struct CertPropIDHeader *hdr; 1140 1141 hdr = (struct CertPropIDHeader *)buf; 1142 hdr->propID = CERT_HASH_PROP_ID; 1143 hdr->unknown1 = 1; 1144 hdr->cb = sizeof(hash); 1145 ptr = buf + sizeof(*hdr); 1146 memcpy(ptr, hash, sizeof(hash)); 1147 ptr += sizeof(hash); 1148 hdr = (struct CertPropIDHeader *)ptr; 1149 hdr->propID = CERT_CERT_PROP_ID; 1150 hdr->unknown1 = 1; 1151 hdr->cb = sizeof(bigCert); 1152 ptr += sizeof(*hdr); 1153 memcpy(ptr, bigCert, sizeof(bigCert)); 1154 1155 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf, 1156 sizeof(buf)); 1157 ok(!rc, "RegSetValueExA failed: %d\n", rc); 1158 1159 ret = CertControlStore(store, 0, CERT_STORE_CTRL_RESYNC, NULL); 1160 ok(ret, "CertControlStore failed: %08x\n", GetLastError()); 1161 1162 /* Make sure the bogus hash cert gets loaded. */ 1163 certCount = 0; 1164 context = NULL; 1165 do { 1166 context = CertEnumCertificatesInStore(store, context); 1167 if (context) 1168 certCount++; 1169 } while (context != NULL); 1170 ok(certCount == 1, "Expected 1 certificates, got %d\n", certCount); 1171 1172 RegCloseKey(subKey); 1173 } 1174 1175 /* Add another serialized cert directly to the registry, this time 1176 * under the correct key name (named with the correct hash value). 1177 */ 1178 size = sizeof(hash); 1179 ret = CryptHashCertificate(0, 0, 0, bigCert2, 1180 sizeof(bigCert2), hash, &size); 1181 ok(ret, "CryptHashCertificate failed: %d\n", GetLastError()); 1182 strcpy(subKeyName, certificates); 1183 for (i = 0, ptr = subKeyName + sizeof(certificates) - 1; 1184 i < sizeof(hash); i++, ptr += 2) 1185 sprintf(ptr, "%02X", hash[i]); 1186 rc = RegCreateKeyExA(key, subKeyName, 0, NULL, 0, KEY_ALL_ACCESS, NULL, 1187 &subKey, NULL); 1188 ok(!rc, "RegCreateKeyExA failed: %d\n", rc); 1189 if (subKey) 1190 { 1191 BYTE buf[sizeof(struct CertPropIDHeader) * 2 + sizeof(hash) + 1192 sizeof(bigCert2)], *ptr; 1193 DWORD certCount = 0; 1194 PCCERT_CONTEXT context; 1195 struct CertPropIDHeader *hdr; 1196 1197 /* First try with a bogus hash... */ 1198 hdr = (struct CertPropIDHeader *)buf; 1199 hdr->propID = CERT_HASH_PROP_ID; 1200 hdr->unknown1 = 1; 1201 hdr->cb = sizeof(hash); 1202 ptr = buf + sizeof(*hdr); 1203 memset(ptr, 0, sizeof(hash)); 1204 ptr += sizeof(hash); 1205 hdr = (struct CertPropIDHeader *)ptr; 1206 hdr->propID = CERT_CERT_PROP_ID; 1207 hdr->unknown1 = 1; 1208 hdr->cb = sizeof(bigCert2); 1209 ptr += sizeof(*hdr); 1210 memcpy(ptr, bigCert2, sizeof(bigCert2)); 1211 1212 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf, 1213 sizeof(buf)); 1214 ok(!rc, "RegSetValueExA failed: %d\n", rc); 1215 1216 ret = CertControlStore(store, 0, CERT_STORE_CTRL_RESYNC, NULL); 1217 ok(ret, "CertControlStore failed: %08x\n", GetLastError()); 1218 1219 /* and make sure just one cert still gets loaded. */ 1220 certCount = 0; 1221 context = NULL; 1222 do { 1223 context = CertEnumCertificatesInStore(store, context); 1224 if (context) 1225 certCount++; 1226 } while (context != NULL); 1227 ok(certCount == 1, "Expected 1 certificate, got %d\n", certCount); 1228 1229 /* Try again with the correct hash... */ 1230 ptr = buf + sizeof(*hdr); 1231 memcpy(ptr, hash, sizeof(hash)); 1232 1233 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf, 1234 sizeof(buf)); 1235 ok(!rc, "RegSetValueExA failed: %d\n", rc); 1236 1237 ret = CertControlStore(store, 0, CERT_STORE_CTRL_RESYNC, NULL); 1238 ok(ret, "CertControlStore failed: %08x\n", GetLastError()); 1239 1240 /* and make sure two certs get loaded. */ 1241 certCount = 0; 1242 context = NULL; 1243 do { 1244 context = CertEnumCertificatesInStore(store, context); 1245 if (context) 1246 certCount++; 1247 } while (context != NULL); 1248 ok(certCount == 2, "Expected 2 certificates, got %d\n", certCount); 1249 1250 RegCloseKey(subKey); 1251 } 1252 CertCloseStore(store, 0); 1253 /* Is delete allowed on a reg store? */ 1254 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 1255 CERT_STORE_DELETE_FLAG, key); 1256 ok(store == NULL, "Expected NULL return from CERT_STORE_DELETE_FLAG\n"); 1257 ok(GetLastError() == 0, "CertOpenStore failed: %08x\n", 1258 GetLastError()); 1259 1260 RegCloseKey(key); 1261 } 1262 /* The CertOpenStore with CERT_STORE_DELETE_FLAG above will delete the 1263 * contents of the key, but not the key itself. 1264 */ 1265 rc = RegCreateKeyExA(HKEY_CURRENT_USER, tempKey, 0, NULL, 0, KEY_ALL_ACCESS, 1266 NULL, &key, &disp); 1267 ok(!rc, "RegCreateKeyExA failed: %d\n", rc); 1268 ok(disp == REG_OPENED_EXISTING_KEY, 1269 "Expected REG_OPENED_EXISTING_KEY, got %d\n", disp); 1270 if (!rc) 1271 { 1272 RegCloseKey(key); 1273 rc = RegDeleteKeyA(HKEY_CURRENT_USER, tempKey); 1274 if (rc) 1275 { 1276 /* Use shlwapi's SHDeleteKeyA to _really_ blow away the key, 1277 * otherwise subsequent tests will fail. 1278 */ 1279 SHDeleteKeyA(HKEY_CURRENT_USER, tempKey); 1280 } 1281 } 1282 } 1283 1284 static const char MyA[] = { 'M','y',0,0 }; 1285 static const WCHAR MyW[] = { 'M','y',0 }; 1286 static const WCHAR BogusW[] = { 'B','o','g','u','s',0 }; 1287 static const WCHAR BogusPathW[] = { 'S','o','f','t','w','a','r','e','\\', 1288 'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m','C','e','r', 1289 't','i','f','i','c','a','t','e','s','\\','B','o','g','u','s',0 }; 1290 1291 static void testSystemRegStore(void) 1292 { 1293 HCERTSTORE store, memStore; 1294 1295 /* Check with a UNICODE name */ 1296 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 1297 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyW); 1298 /* Not all OSes support CERT_STORE_PROV_SYSTEM_REGISTRY, so don't continue 1299 * testing if they don't. 1300 */ 1301 if (!store) 1302 return; 1303 1304 /* Check that it isn't a collection store */ 1305 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 1306 CERT_STORE_CREATE_NEW_FLAG, NULL); 1307 if (memStore) 1308 { 1309 BOOL ret = CertAddStoreToCollection(store, memStore, 0, 0); 1310 ok(!ret && GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1311 CertCloseStore(memStore, 0); 1312 } 1313 CertCloseStore(store, 0); 1314 1315 /* Check opening a bogus store */ 1316 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 1317 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, BogusW); 1318 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND, 1319 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 1320 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 1321 CERT_SYSTEM_STORE_CURRENT_USER, BogusW); 1322 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError()); 1323 if (store) 1324 CertCloseStore(store, 0); 1325 /* Now check whether deleting is allowed */ 1326 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 1327 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW); 1328 ok(!store, "CertOpenStore failed: %08x\n", GetLastError()); 1329 RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW); 1330 1331 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 0, NULL); 1332 ok(!store && GetLastError() == E_INVALIDARG, 1333 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1334 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 1335 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyA); 1336 ok(!store && GetLastError() == E_INVALIDARG, 1337 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1338 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 1339 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyW); 1340 ok(!store && GetLastError() == E_INVALIDARG, 1341 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1342 /* The name is expected to be UNICODE, check with an ASCII name */ 1343 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 1344 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyA); 1345 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND, 1346 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 1347 } 1348 1349 static void testSystemStore(void) 1350 { 1351 static const WCHAR baskslashW[] = { '\\',0 }; 1352 HCERTSTORE store; 1353 WCHAR keyName[MAX_PATH]; 1354 HKEY key; 1355 LONG rc; 1356 1357 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 0, NULL); 1358 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND, 1359 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 1360 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 1361 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyA); 1362 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND, 1363 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 1364 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 1365 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyW); 1366 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND, 1367 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 1368 /* The name is expected to be UNICODE, first check with an ASCII name */ 1369 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 1370 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyA); 1371 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND, 1372 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 1373 /* Create the expected key */ 1374 lstrcpyW(keyName, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH); 1375 lstrcatW(keyName, baskslashW); 1376 lstrcatW(keyName, MyW); 1377 rc = RegCreateKeyExW(HKEY_CURRENT_USER, keyName, 0, NULL, 0, KEY_READ, 1378 NULL, &key, NULL); 1379 ok(!rc, "RegCreateKeyEx failed: %d\n", rc); 1380 if (!rc) 1381 RegCloseKey(key); 1382 /* Check opening with a UNICODE name, specifying the create new flag */ 1383 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 1384 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_CREATE_NEW_FLAG, MyW); 1385 ok(!store && GetLastError() == ERROR_FILE_EXISTS, 1386 "Expected ERROR_FILE_EXISTS, got %08x\n", GetLastError()); 1387 /* Now check opening with a UNICODE name, this time opening existing */ 1388 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 1389 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyW); 1390 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError()); 1391 if (store) 1392 { 1393 HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 1394 CERT_STORE_CREATE_NEW_FLAG, NULL); 1395 1396 /* Check that it's a collection store */ 1397 if (memStore) 1398 { 1399 BOOL ret = CertAddStoreToCollection(store, memStore, 0, 0); 1400 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError()); 1401 CertCloseStore(memStore, 0); 1402 } 1403 CertCloseStore(store, 0); 1404 } 1405 1406 /* Check opening a bogus store */ 1407 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 1408 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, BogusW); 1409 ok(!store, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 1410 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 1411 CERT_SYSTEM_STORE_CURRENT_USER, BogusW); 1412 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError()); 1413 if (store) 1414 CertCloseStore(store, 0); 1415 /* Now check whether deleting is allowed */ 1416 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 1417 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW); 1418 ok(!store, "Didn't expect a store to be returned when deleting\n"); 1419 RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW); 1420 } 1421 1422 static const BYTE serializedStoreWithCertAndCRL[] = { 1423 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x20,0x00,0x00,0x00,0x01,0x00,0x00, 1424 0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30, 1425 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, 1426 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31, 1427 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36, 1428 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15, 1429 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 1430 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00, 1431 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04, 1432 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x21,0x00,0x00,0x00,0x01,0x00, 1433 0x00,0x00,0x47,0x00,0x00,0x00,0x30,0x45,0x30,0x2c,0x30,0x02,0x06,0x00,0x30, 1434 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, 1435 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 1436 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x03,0x11, 1437 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02, 1438 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; 1439 1440 static void testFileStore(void) 1441 { 1442 static const WCHAR szPrefix[] = { 'c','e','r',0 }; 1443 static const WCHAR szDot[] = { '.',0 }; 1444 WCHAR filename[MAX_PATH]; 1445 HCERTSTORE store; 1446 BOOL ret; 1447 PCCERT_CONTEXT cert; 1448 HANDLE file; 1449 1450 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 0, NULL); 1451 ok(!store && GetLastError() == ERROR_INVALID_HANDLE, 1452 "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError()); 1453 1454 if (!GetTempFileNameW(szDot, szPrefix, 0, filename)) 1455 return; 1456 1457 DeleteFileW(filename); 1458 file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, 1459 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 1460 if (file == INVALID_HANDLE_VALUE) 1461 return; 1462 1463 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, CERT_STORE_DELETE_FLAG, 1464 file); 1465 ok(!store && GetLastError() == E_INVALIDARG, 1466 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1467 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 1468 CERT_FILE_STORE_COMMIT_ENABLE_FLAG | CERT_STORE_READONLY_FLAG, file); 1469 ok(!store && GetLastError() == E_INVALIDARG, 1470 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1471 1472 /* A "read-only" file store.. */ 1473 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 1474 CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, file); 1475 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1476 if (store) 1477 { 1478 DWORD size; 1479 1480 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1481 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 1482 /* apparently allows adding certificates.. */ 1483 ok(ret, "CertAddEncodedCertificateToStore failed: %d\n", ret); 1484 /* but not commits.. */ 1485 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL); 1486 ok(!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, 1487 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError()); 1488 /* It still has certs in memory.. */ 1489 cert = CertEnumCertificatesInStore(store, NULL); 1490 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n", 1491 GetLastError()); 1492 CertFreeCertificateContext(cert); 1493 /* but the file size is still 0. */ 1494 size = GetFileSize(file, NULL); 1495 ok(size == 0, "Expected size 0, got %d\n", size); 1496 CertCloseStore(store, 0); 1497 } 1498 1499 /* The create new flag is allowed.. */ 1500 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 1501 CERT_STORE_CREATE_NEW_FLAG, file); 1502 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1503 if (store) 1504 { 1505 /* but without the commit enable flag, commits don't happen. */ 1506 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1507 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 1508 ok(ret, "CertAddEncodedCertificateToStore failed: %d\n", ret); 1509 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL); 1510 ok(!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, 1511 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError()); 1512 CertCloseStore(store, 0); 1513 } 1514 /* as is the open existing flag. */ 1515 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 1516 CERT_STORE_OPEN_EXISTING_FLAG, file); 1517 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1518 if (store) 1519 { 1520 /* but without the commit enable flag, commits don't happen. */ 1521 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1522 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 1523 ok(ret, "CertAddEncodedCertificateToStore failed: %d\n", ret); 1524 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL); 1525 ok(!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, 1526 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError()); 1527 CertCloseStore(store, 0); 1528 } 1529 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 1530 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file); 1531 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1532 if (store) 1533 { 1534 CloseHandle(file); 1535 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1536 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 1537 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1538 GetLastError()); 1539 /* with commits enabled, commit is allowed */ 1540 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL); 1541 ok(ret, "CertControlStore failed: %d\n", ret); 1542 compareStore(store, "serialized store with cert", 1543 serializedStoreWithCert, sizeof(serializedStoreWithCert), FALSE); 1544 CertCloseStore(store, 0); 1545 } 1546 file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, 1547 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 1548 if (file == INVALID_HANDLE_VALUE) 1549 return; 1550 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 1551 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file); 1552 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1553 if (store) 1554 { 1555 CloseHandle(file); 1556 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL, 1557 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL); 1558 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError()); 1559 compareStore(store, "serialized store with cert and CRL", 1560 serializedStoreWithCertAndCRL, sizeof(serializedStoreWithCertAndCRL), 1561 FALSE); 1562 CertCloseStore(store, 0); 1563 } 1564 1565 DeleteFileW(filename); 1566 } 1567 1568 static BOOL initFileFromData(LPCWSTR filename, const BYTE *pb, DWORD cb) 1569 { 1570 HANDLE file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, 1571 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 1572 BOOL ret; 1573 1574 if (file != INVALID_HANDLE_VALUE) 1575 { 1576 DWORD written; 1577 1578 ret = WriteFile(file, pb, cb, &written, NULL); 1579 CloseHandle(file); 1580 } 1581 else 1582 ret = FALSE; 1583 return ret; 1584 } 1585 1586 static const BYTE base64SPC[] = 1587 "MIICJQYJKoZIhvcNAQcCoIICFjCCAhICAQExADALBgkqhkiG9w0BBwGgggH6MIIB" 1588 "9jCCAV+gAwIBAgIQnP8+EF4opr9OxH7h4uBPWTANBgkqhkiG9w0BAQQFADAUMRIw" 1589 "EAYDVQQDEwlKdWFuIExhbmcwHhcNMDgxMjEyMTcxMDE0WhcNMzkxMjMxMjM1OTU5" 1590 "WjAUMRIwEAYDVQQDEwlKdWFuIExhbmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ" 1591 "AoGBALCgNjyNvOic0FOfjxvi43HbM+D5joDkhiGSXe+gbZlf8f16k07kkObFEunz" 1592 "mdB5coscmA7gyqiWNN4ZUyr2cA3lCbnpGPA/0IblyyOcuGIFmmCzeZaVa5ZG6xZP" 1593 "K7L7o+73Qo6jXVbGhBGnMZ7Q9sAn6s2933olnStnejnqwV0NAgMBAAGjSTBHMEUG" 1594 "A1UdAQQ+MDyAEFKbKEdXYyx+CWKcV6vxM6ShFjAUMRIwEAYDVQQDEwlKdWFuIExh" 1595 "bmeCEJz/PhBeKKa/TsR+4eLgT1kwDQYJKoZIhvcNAQEEBQADgYEALpkgLgW3mEaK" 1596 "idPQ3iPJYLG0Ub1wraqEl9bd42hrhzIdcDzlQgxnm8/5cHYVxIF/C20x/HJplb1R" 1597 "G6U1ipFe/q8byWD/9JpiBKMGPi9YlUTgXHfS9d4S/QWO1h9Z7KeipBYhoslQpHXu" 1598 "y9bUr8Adqi6SzgHpCnMu53dxgxUD1r4xAA=="; 1599 /* Same as base64SPC, but as a wide-char string */ 1600 static const WCHAR utf16Base64SPC[] = { 1601 'M','I','I','C','J','Q','Y','J','K','o','Z','I','h','v','c','N','A', 1602 'Q','c','C','o','I','I','C','F','j','C','C','A','h','I','C','A','Q', 1603 'E','x','A','D','A','L','B','g','k','q','h','k','i','G','9','w','0', 1604 'B','B','w','G','g','g','g','H','6','M','I','I','B','9','j','C','C', 1605 'A','V','+','g','A','w','I','B','A','g','I','Q','n','P','8','+','E', 1606 'F','4','o','p','r','9','O','x','H','7','h','4','u','B','P','W','T', 1607 'A','N','B','g','k','q','h','k','i','G','9','w','0','B','A','Q','Q', 1608 'F','A','D','A','U','M','R','I','w','E','A','Y','D','V','Q','Q','D', 1609 'E','w','l','K','d','W','F','u','I','E','x','h','b','m','c','w','H', 1610 'h','c','N','M','D','g','x','M','j','E','y','M','T','c','x','M','D', 1611 'E','0','W','h','c','N','M','z','k','x','M','j','M','x','M','j','M', 1612 '1','O','T','U','5','W','j','A','U','M','R','I','w','E','A','Y','D', 1613 'V','Q','Q','D','E','w','l','K','d','W','F','u','I','E','x','h','b', 1614 'm','c','w','g','Z','8','w','D','Q','Y','J','K','o','Z','I','h','v', 1615 'c','N','A','Q','E','B','B','Q','A','D','g','Y','0','A','M','I','G', 1616 'J','A','o','G','B','A','L','C','g','N','j','y','N','v','O','i','c', 1617 '0','F','O','f','j','x','v','i','4','3','H','b','M','+','D','5','j', 1618 'o','D','k','h','i','G','S','X','e','+','g','b','Z','l','f','8','f', 1619 '1','6','k','0','7','k','k','O','b','F','E','u','n','z','m','d','B', 1620 '5','c','o','s','c','m','A','7','g','y','q','i','W','N','N','4','Z', 1621 'U','y','r','2','c','A','3','l','C','b','n','p','G','P','A','/','0', 1622 'I','b','l','y','y','O','c','u','G','I','F','m','m','C','z','e','Z', 1623 'a','V','a','5','Z','G','6','x','Z','P','K','7','L','7','o','+','7', 1624 '3','Q','o','6','j','X','V','b','G','h','B','G','n','M','Z','7','Q', 1625 '9','s','A','n','6','s','2','9','3','3','o','l','n','S','t','n','e', 1626 'j','n','q','w','V','0','N','A','g','M','B','A','A','G','j','S','T', 1627 'B','H','M','E','U','G','A','1','U','d','A','Q','Q','+','M','D','y', 1628 'A','E','F','K','b','K','E','d','X','Y','y','x','+','C','W','K','c', 1629 'V','6','v','x','M','6','S','h','F','j','A','U','M','R','I','w','E', 1630 'A','Y','D','V','Q','Q','D','E','w','l','K','d','W','F','u','I','E', 1631 'x','h','b','m','e','C','E','J','z','/','P','h','B','e','K','K','a', 1632 '/','T','s','R','+','4','e','L','g','T','1','k','w','D','Q','Y','J', 1633 'K','o','Z','I','h','v','c','N','A','Q','E','E','B','Q','A','D','g', 1634 'Y','E','A','L','p','k','g','L','g','W','3','m','E','a','K','i','d', 1635 'P','Q','3','i','P','J','Y','L','G','0','U','b','1','w','r','a','q', 1636 'E','l','9','b','d','4','2','h','r','h','z','I','d','c','D','z','l', 1637 'Q','g','x','n','m','8','/','5','c','H','Y','V','x','I','F','/','C', 1638 '2','0','x','/','H','J','p','l','b','1','R','G','6','U','1','i','p', 1639 'F','e','/','q','8','b','y','W','D','/','9','J','p','i','B','K','M', 1640 'G','P','i','9','Y','l','U','T','g','X','H','f','S','9','d','4','S', 1641 '/','Q','W','O','1','h','9','Z','7','K','e','i','p','B','Y','h','o', 1642 's','l','Q','p','H','X','u','y','9','b','U','r','8','A','d','q','i', 1643 '6','S','z','g','H','p','C','n','M','u','5','3','d','x','g','x','U', 1644 'D','1','r','4','x','A','A','=','=',0 }; 1645 1646 static void testFileNameStore(void) 1647 { 1648 static const WCHAR szPrefix[] = { 'c','e','r',0 }; 1649 static const WCHAR spcPrefix[] = { 's','p','c',0 }; 1650 static const WCHAR szDot[] = { '.',0 }; 1651 WCHAR filename[MAX_PATH]; 1652 HCERTSTORE store; 1653 BOOL ret; 1654 DWORD GLE; 1655 1656 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, 0, NULL); 1657 GLE = GetLastError(); 1658 ok(!store && (GLE == ERROR_PATH_NOT_FOUND || GLE == ERROR_INVALID_PARAMETER), 1659 "Expected ERROR_PATH_NOT_FOUND or ERROR_INVALID_PARAMETER, got %08x\n", 1660 GLE); 1661 1662 if (!GetTempFileNameW(szDot, szPrefix, 0, filename)) 1663 return; 1664 DeleteFileW(filename); 1665 1666 /* The two flags are mutually exclusive */ 1667 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, 1668 CERT_FILE_STORE_COMMIT_ENABLE_FLAG | CERT_STORE_READONLY_FLAG, filename); 1669 ok(!store && GetLastError() == E_INVALIDARG, 1670 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1671 1672 /* In all of the following tests, the encoding type seems to be ignored */ 1673 if (initFileFromData(filename, bigCert, sizeof(bigCert))) 1674 { 1675 PCCERT_CONTEXT cert; 1676 PCCRL_CONTEXT crl; 1677 1678 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, 1679 CERT_STORE_READONLY_FLAG, filename); 1680 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1681 1682 cert = CertEnumCertificatesInStore(store, NULL); 1683 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n", 1684 GetLastError()); 1685 cert = CertEnumCertificatesInStore(store, cert); 1686 ok(!cert, "Expected only one cert\n"); 1687 crl = CertEnumCRLsInStore(store, NULL); 1688 ok(!crl, "Expected no CRLs\n"); 1689 1690 CertCloseStore(store, 0); 1691 DeleteFileW(filename); 1692 } 1693 if (initFileFromData(filename, serializedStoreWithCert, 1694 sizeof(serializedStoreWithCert))) 1695 { 1696 PCCERT_CONTEXT cert; 1697 PCCRL_CONTEXT crl; 1698 1699 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, 1700 CERT_STORE_READONLY_FLAG, filename); 1701 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1702 1703 cert = CertEnumCertificatesInStore(store, NULL); 1704 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n", 1705 GetLastError()); 1706 cert = CertEnumCertificatesInStore(store, cert); 1707 ok(!cert, "Expected only one cert\n"); 1708 crl = CertEnumCRLsInStore(store, NULL); 1709 ok(!crl, "Expected no CRLs\n"); 1710 1711 CertCloseStore(store, 0); 1712 DeleteFileW(filename); 1713 } 1714 if (initFileFromData(filename, serializedStoreWithCertAndCRL, 1715 sizeof(serializedStoreWithCertAndCRL))) 1716 { 1717 PCCERT_CONTEXT cert; 1718 PCCRL_CONTEXT crl; 1719 1720 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, 1721 CERT_STORE_READONLY_FLAG, filename); 1722 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1723 1724 cert = CertEnumCertificatesInStore(store, NULL); 1725 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n", 1726 GetLastError()); 1727 cert = CertEnumCertificatesInStore(store, cert); 1728 ok(!cert, "Expected only one cert\n"); 1729 crl = CertEnumCRLsInStore(store, NULL); 1730 ok(crl != NULL, "CertEnumCRLsInStore failed: %08x\n", GetLastError()); 1731 crl = CertEnumCRLsInStore(store, crl); 1732 ok(!crl, "Expected only one CRL\n"); 1733 1734 CertCloseStore(store, 0); 1735 /* Don't delete it this time, the next test uses it */ 1736 } 1737 /* Now that the file exists, we can open it read-only */ 1738 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, 1739 CERT_STORE_READONLY_FLAG, filename); 1740 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1741 CertCloseStore(store, 0); 1742 DeleteFileW(filename); 1743 1744 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, 1745 CERT_FILE_STORE_COMMIT_ENABLE_FLAG | CERT_STORE_CREATE_NEW_FLAG, filename); 1746 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1747 if (store) 1748 { 1749 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1750 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 1751 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1752 GetLastError()); 1753 compareStore(store, "serialized store with cert", 1754 serializedStoreWithCert, sizeof(serializedStoreWithCert), FALSE); 1755 CertCloseStore(store, 0); 1756 } 1757 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, 1758 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, filename); 1759 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1760 if (store) 1761 { 1762 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, 1763 signedCRL, sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL); 1764 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError()); 1765 compareStore(store, "serialized store with cert and CRL", 1766 serializedStoreWithCertAndCRL, sizeof(serializedStoreWithCertAndCRL), 1767 FALSE); 1768 CertCloseStore(store, 0); 1769 } 1770 DeleteFileW(filename); 1771 1772 if (!GetTempFileNameW(szDot, spcPrefix, 0, filename)) 1773 return; 1774 DeleteFileW(filename); 1775 1776 if (initFileFromData(filename, base64SPC, sizeof(base64SPC))) 1777 { 1778 PCCERT_CONTEXT cert; 1779 PCCRL_CONTEXT crl; 1780 1781 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, 1782 CERT_STORE_READONLY_FLAG, filename); 1783 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1784 1785 cert = CertEnumCertificatesInStore(store, NULL); 1786 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n", 1787 GetLastError()); 1788 cert = CertEnumCertificatesInStore(store, cert); 1789 ok(!cert, "Expected only one cert\n"); 1790 crl = CertEnumCRLsInStore(store, NULL); 1791 ok(!crl, "Expected no CRLs\n"); 1792 1793 CertCloseStore(store, 0); 1794 DeleteFileW(filename); 1795 } 1796 if (initFileFromData(filename, (BYTE *)utf16Base64SPC, 1797 sizeof(utf16Base64SPC))) 1798 { 1799 PCCERT_CONTEXT cert; 1800 PCCRL_CONTEXT crl; 1801 1802 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, 1803 CERT_STORE_READONLY_FLAG, filename); 1804 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1805 1806 cert = CertEnumCertificatesInStore(store, NULL); 1807 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n", 1808 GetLastError()); 1809 cert = CertEnumCertificatesInStore(store, cert); 1810 ok(!cert, "Expected only one cert\n"); 1811 crl = CertEnumCRLsInStore(store, NULL); 1812 ok(!crl, "Expected no CRLs\n"); 1813 1814 CertCloseStore(store, 0); 1815 DeleteFileW(filename); 1816 } 1817 } 1818 1819 static const BYTE signedContent[] = { 1820 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 1821 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 1822 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86, 1823 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04, 1824 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11, 1825 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 1826 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 1827 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70, 1828 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d, 1829 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe, 1830 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29, 1831 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8, 1832 0x0d }; 1833 static const BYTE signedWithCertAndCrlBareContent[] = { 1834 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86, 1835 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48, 1836 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0, 1837 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 1838 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 1839 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 1840 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 1841 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 1842 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 1843 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14, 1844 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01, 1845 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15, 1846 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 1847 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 1848 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01, 1849 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a, 1850 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c, 1851 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06, 1852 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b, 1853 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c, 1854 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d, 1855 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39, 1856 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; 1857 static const BYTE hashContent[] = { 1858 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a, 1859 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 1860 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 1861 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0, 1862 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f }; 1863 static const BYTE hashBareContent[] = { 1864 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 1865 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 1866 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0, 1867 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f }; 1868 1869 static void testMessageStore(void) 1870 { 1871 HCERTSTORE store; 1872 HCRYPTMSG msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, 1873 NULL); 1874 CRYPT_DATA_BLOB blob = { sizeof(signedWithCertAndCrlBareContent), 1875 (LPBYTE)signedWithCertAndCrlBareContent }; 1876 DWORD count, size; 1877 BOOL ret; 1878 1879 /* Crashes 1880 store = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0, NULL); 1881 */ 1882 SetLastError(0xdeadbeef); 1883 store = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0, msg); 1884 ok(!store && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 1885 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 1886 CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE); 1887 store = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0, msg); 1888 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1889 if (store) 1890 { 1891 PCCERT_CONTEXT cert = NULL; 1892 PCCRL_CONTEXT crl = NULL; 1893 1894 count = 0; 1895 do { 1896 cert = CertEnumCertificatesInStore(store, cert); 1897 if (cert) 1898 count++; 1899 } while (cert); 1900 ok(count == 0, "Expected 0 certificates, got %d\n", count); 1901 1902 count = 0; 1903 do { 1904 crl = CertEnumCRLsInStore(store, crl); 1905 if (crl) 1906 count++; 1907 } while (crl); 1908 ok(count == 0, "Expected 0 CRLs, got %d\n", count); 1909 1910 /* Can add certs to a message store */ 1911 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1912 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 1913 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1914 GetLastError()); 1915 count = 0; 1916 do { 1917 cert = CertEnumCertificatesInStore(store, cert); 1918 if (cert) 1919 count++; 1920 } while (cert); 1921 ok(count == 1, "Expected 1 certificate, got %d\n", count); 1922 1923 CertCloseStore(store, 0); 1924 } 1925 /* but the added certs weren't actually added to the message */ 1926 size = sizeof(count); 1927 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size); 1928 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 1929 ok(count == 0, "Expected 0 certificates, got %d\n", count); 1930 CryptMsgClose(msg); 1931 1932 /* Crashes 1933 store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, NULL); 1934 */ 1935 store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, &blob); 1936 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1937 if (store) 1938 { 1939 DWORD count = 0; 1940 PCCERT_CONTEXT cert = NULL; 1941 PCCRL_CONTEXT crl = NULL; 1942 1943 do { 1944 cert = CertEnumCertificatesInStore(store, cert); 1945 if (cert) 1946 count++; 1947 } while (cert); 1948 ok(count == 1, "Expected 1 certificate, got %d\n", count); 1949 1950 count = 0; 1951 do { 1952 crl = CertEnumCRLsInStore(store, crl); 1953 if (crl) 1954 count++; 1955 } while (crl); 1956 ok(count == 1, "Expected 1 CRL, got %d\n", count); 1957 1958 CertCloseStore(store, 0); 1959 } 1960 /* Encoding appears to be ignored */ 1961 store = CertOpenStore(CERT_STORE_PROV_PKCS7, X509_ASN_ENCODING, 0, 0, 1962 &blob); 1963 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1964 if (store) 1965 CertCloseStore(store, 0); 1966 /* Messages other than signed messages aren't allowed */ 1967 blob.cbData = sizeof(hashContent); 1968 blob.pbData = (LPBYTE)hashContent; 1969 SetLastError(0xdeadbeef); 1970 store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, &blob); 1971 ok(!store && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 1972 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 1973 blob.cbData = sizeof(hashBareContent); 1974 blob.pbData = (LPBYTE)hashBareContent; 1975 SetLastError(0xdeadbeef); 1976 store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, &blob); 1977 ok(!store && GetLastError() == CRYPT_E_ASN1_BADTAG, 1978 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); 1979 } 1980 1981 static void testSerializedStore(void) 1982 { 1983 HCERTSTORE store; 1984 CRYPT_DATA_BLOB blob; 1985 1986 if (0) 1987 { 1988 /* Crash */ 1989 store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 0, NULL); 1990 store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 1991 CERT_STORE_DELETE_FLAG, NULL); 1992 } 1993 blob.cbData = sizeof(serializedStoreWithCert); 1994 blob.pbData = (BYTE *)serializedStoreWithCert; 1995 store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 1996 CERT_STORE_DELETE_FLAG, &blob); 1997 ok(!store && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, 1998 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError()); 1999 store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 0, &blob); 2000 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 2001 if (store) 2002 { 2003 PCCERT_CONTEXT cert; 2004 PCCRL_CONTEXT crl; 2005 2006 cert = CertEnumCertificatesInStore(store, NULL); 2007 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n", 2008 GetLastError()); 2009 cert = CertEnumCertificatesInStore(store, cert); 2010 ok(!cert, "Expected only one cert\n"); 2011 crl = CertEnumCRLsInStore(store, NULL); 2012 ok(!crl, "Expected no CRLs\n"); 2013 2014 CertCloseStore(store, 0); 2015 } 2016 blob.cbData = sizeof(serializedStoreWithCertAndCRL); 2017 blob.pbData = (BYTE *)serializedStoreWithCertAndCRL; 2018 store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 0, &blob); 2019 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 2020 if (store) 2021 { 2022 PCCERT_CONTEXT cert; 2023 PCCRL_CONTEXT crl; 2024 2025 cert = CertEnumCertificatesInStore(store, NULL); 2026 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n", 2027 GetLastError()); 2028 cert = CertEnumCertificatesInStore(store, cert); 2029 ok(!cert, "Expected only one cert\n"); 2030 crl = CertEnumCRLsInStore(store, NULL); 2031 ok(crl != NULL, "CertEnumCRLsInStore failed: %08x\n", 2032 GetLastError()); 2033 crl = CertEnumCRLsInStore(store, crl); 2034 ok(!crl, "Expected only one CRL\n"); 2035 2036 CertCloseStore(store, 0); 2037 } 2038 } 2039 2040 static void testCertOpenSystemStore(void) 2041 { 2042 HCERTSTORE store; 2043 2044 store = CertOpenSystemStoreW(0, NULL); 2045 ok(!store && GetLastError() == E_INVALIDARG, 2046 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2047 /* This succeeds, and on WinXP at least, the Bogus key is created under 2048 * HKCU (but not under HKLM, even when run as an administrator.) 2049 */ 2050 store = CertOpenSystemStoreW(0, BogusW); 2051 ok(store != 0, "CertOpenSystemStore failed: %08x\n", GetLastError()); 2052 if (store) 2053 CertCloseStore(store, 0); 2054 /* Delete it so other tests succeed next time around */ 2055 CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 2056 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW); 2057 RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW); 2058 } 2059 2060 static const struct 2061 { 2062 DWORD cert_store; 2063 BOOL expected; 2064 BOOL todo; 2065 } reg_system_store_test_data[] = { 2066 { CERT_SYSTEM_STORE_CURRENT_USER, TRUE, 0}, 2067 /* Following tests could require administrator privileges and thus could be skipped */ 2068 { CERT_SYSTEM_STORE_CURRENT_SERVICE, TRUE, 1}, 2069 { CERT_SYSTEM_STORE_LOCAL_MACHINE, TRUE, 0}, 2070 { CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, TRUE, 0}, 2071 { CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, TRUE, 0}, 2072 { CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, TRUE, 1} 2073 }; 2074 2075 static void testCertRegisterSystemStore(void) 2076 { 2077 BOOL ret, cur_flag; 2078 DWORD err = 0; 2079 HCERTSTORE hstore; 2080 static const WCHAR WineTestW[] = {'W','i','n','e','T','e','s','t',0}; 2081 const CERT_CONTEXT *cert, *cert2; 2082 unsigned int i; 2083 2084 for (i = 0; i < ARRAY_SIZE(reg_system_store_test_data); i++) { 2085 cur_flag = reg_system_store_test_data[i].cert_store; 2086 ret = CertRegisterSystemStore(WineTestW, cur_flag, NULL, NULL); 2087 if (!ret) 2088 { 2089 err = GetLastError(); 2090 if (err == ERROR_ACCESS_DENIED) 2091 { 2092 win_skip("Insufficient privileges for the flag %08x test\n", cur_flag); 2093 continue; 2094 } 2095 } 2096 todo_wine_if (reg_system_store_test_data[i].todo) 2097 ok (ret == reg_system_store_test_data[i].expected, 2098 "Store registration (dwFlags=%08x) failed, last error %x\n", cur_flag, err); 2099 if (!ret) 2100 { 2101 skip("Nothing to test without registered store at %08x\n", cur_flag); 2102 continue; 2103 } 2104 2105 hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, CERT_STORE_OPEN_EXISTING_FLAG | cur_flag, WineTestW); 2106 ok (hstore != NULL, "Opening just registered store at %08x failed, last error %x\n", cur_flag, GetLastError()); 2107 2108 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); 2109 ok (cert != NULL, "Failed creating cert at %08x, last error: %x\n", cur_flag, GetLastError()); 2110 if (cert) 2111 { 2112 ret = CertAddCertificateContextToStore(hstore, cert, CERT_STORE_ADD_NEW, NULL); 2113 ok (ret, "Failed to add cert at %08x, last error: %x\n", cur_flag, GetLastError()); 2114 2115 cert2 = CertEnumCertificatesInStore(hstore, NULL); 2116 ok (cert2 != NULL && cert2->cbCertEncoded == cert->cbCertEncoded, 2117 "Unexpected cert encoded size at %08x, last error: %x\n", cur_flag, GetLastError()); 2118 2119 ret = CertDeleteCertificateFromStore(cert2); 2120 ok (ret, "Failed to delete certificate from the new store at %08x, last error: %x\n", cur_flag, GetLastError()); 2121 2122 CertFreeCertificateContext(cert); 2123 } 2124 2125 ret = CertCloseStore(hstore, 0); 2126 ok (ret, "CertCloseStore failed at %08x, last error %x\n", cur_flag, GetLastError()); 2127 2128 ret = CertUnregisterSystemStore(WineTestW, cur_flag ); 2129 todo_wine_if (reg_system_store_test_data[i].todo) 2130 ok( ret == reg_system_store_test_data[i].expected, 2131 "Unregistering failed at %08x, last error %d\n", cur_flag, GetLastError()); 2132 } 2133 2134 } 2135 2136 struct EnumSystemStoreInfo 2137 { 2138 BOOL goOn; 2139 DWORD storeCount; 2140 }; 2141 2142 static BOOL CALLBACK enumSystemStoreCB(const void *systemStore, DWORD dwFlags, 2143 PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved, void *pvArg) 2144 { 2145 struct EnumSystemStoreInfo *info = pvArg; 2146 2147 info->storeCount++; 2148 return info->goOn; 2149 } 2150 2151 static void testCertEnumSystemStore(void) 2152 { 2153 BOOL ret; 2154 struct EnumSystemStoreInfo info = { FALSE, 0 }; 2155 2156 SetLastError(0xdeadbeef); 2157 ret = CertEnumSystemStore(0, NULL, NULL, NULL); 2158 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2159 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2160 /* Crashes 2161 ret = CertEnumSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, NULL, NULL, 2162 NULL); 2163 */ 2164 2165 SetLastError(0xdeadbeef); 2166 ret = CertEnumSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, NULL, &info, 2167 enumSystemStoreCB); 2168 /* Callback returning FALSE stops enumeration */ 2169 ok(!ret, "Expected CertEnumSystemStore to stop\n"); 2170 ok(info.storeCount == 0 || info.storeCount == 1, 2171 "Expected 0 or 1 stores\n"); 2172 2173 info.goOn = TRUE; 2174 info.storeCount = 0; 2175 ret = CertEnumSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, NULL, &info, 2176 enumSystemStoreCB); 2177 ok(ret, "CertEnumSystemStore failed: %08x\n", GetLastError()); 2178 /* There should always be at least My, Root, and CA stores */ 2179 ok(info.storeCount == 0 || info.storeCount >= 3, 2180 "Expected at least 3 stores\n"); 2181 } 2182 2183 static void testStoreProperty(void) 2184 { 2185 HCERTSTORE store; 2186 BOOL ret; 2187 DWORD propID, size = 0, state; 2188 CRYPT_DATA_BLOB blob; 2189 2190 /* Crash 2191 ret = CertGetStoreProperty(NULL, 0, NULL, NULL); 2192 ret = CertGetStoreProperty(NULL, 0, NULL, &size); 2193 ret = CertGetStoreProperty(store, 0, NULL, NULL); 2194 */ 2195 2196 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 2197 CERT_STORE_CREATE_NEW_FLAG, NULL); 2198 /* Check a missing prop ID */ 2199 SetLastError(0xdeadbeef); 2200 ret = CertGetStoreProperty(store, 0, NULL, &size); 2201 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 2202 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 2203 /* Contrary to MSDN, CERT_ACCESS_STATE_PROP_ID is supported for stores.. */ 2204 size = sizeof(state); 2205 ret = CertGetStoreProperty(store, CERT_ACCESS_STATE_PROP_ID, &state, &size); 2206 ok(ret, "CertGetStoreProperty failed for CERT_ACCESS_STATE_PROP_ID: %08x\n", 2207 GetLastError()); 2208 ok(!state, "Expected a non-persisted store\n"); 2209 /* and CERT_STORE_LOCALIZED_NAME_PROP_ID isn't supported by default. */ 2210 size = 0; 2211 ret = CertGetStoreProperty(store, CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL, 2212 &size); 2213 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 2214 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 2215 /* Delete an arbitrary property on a store */ 2216 ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, NULL); 2217 ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError()); 2218 /* Set an arbitrary property on a store */ 2219 blob.pbData = (LPBYTE)&state; 2220 blob.cbData = sizeof(state); 2221 ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, &blob); 2222 ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError()); 2223 /* Get an arbitrary property that's been set */ 2224 ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, NULL, &size); 2225 ok(ret, "CertGetStoreProperty failed: %08x\n", GetLastError()); 2226 ok(size == sizeof(state), "Unexpected data size %d\n", size); 2227 ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, &propID, &size); 2228 ok(ret, "CertGetStoreProperty failed: %08x\n", GetLastError()); 2229 ok(propID == state, "CertGetStoreProperty got the wrong value\n"); 2230 /* Delete it again */ 2231 ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, NULL); 2232 ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError()); 2233 /* And check that it's missing */ 2234 SetLastError(0xdeadbeef); 2235 ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, NULL, &size); 2236 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 2237 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 2238 CertCloseStore(store, 0); 2239 2240 /* Recheck on the My store.. */ 2241 store = CertOpenSystemStoreW(0, MyW); 2242 size = sizeof(state); 2243 ret = CertGetStoreProperty(store, CERT_ACCESS_STATE_PROP_ID, &state, &size); 2244 ok(ret, "CertGetStoreProperty failed for CERT_ACCESS_STATE_PROP_ID: %08x\n", 2245 GetLastError()); 2246 ok(state, "Expected a persisted store\n"); 2247 SetLastError(0xdeadbeef); 2248 size = 0; 2249 ret = CertGetStoreProperty(store, CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL, 2250 &size); 2251 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 2252 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 2253 CertCloseStore(store, 0); 2254 } 2255 2256 static void testAddSerialized(void) 2257 { 2258 BOOL ret; 2259 HCERTSTORE store; 2260 BYTE buf[sizeof(struct CertPropIDHeader) * 2 + 20 + sizeof(bigCert)] = 2261 { 0 }; 2262 BYTE hash[20]; 2263 struct CertPropIDHeader *hdr; 2264 PCCERT_CONTEXT context; 2265 2266 ret = CertAddSerializedElementToStore(0, NULL, 0, 0, 0, 0, NULL, NULL); 2267 ok(!ret && GetLastError() == ERROR_END_OF_MEDIA, 2268 "Expected ERROR_END_OF_MEDIA, got %08x\n", GetLastError()); 2269 2270 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 2271 CERT_STORE_CREATE_NEW_FLAG, NULL); 2272 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError()); 2273 2274 ret = CertAddSerializedElementToStore(store, NULL, 0, 0, 0, 0, NULL, NULL); 2275 ok(!ret && GetLastError() == ERROR_END_OF_MEDIA, 2276 "Expected ERROR_END_OF_MEDIA, got %08x\n", GetLastError()); 2277 2278 /* Test with an empty property */ 2279 hdr = (struct CertPropIDHeader *)buf; 2280 hdr->propID = CERT_CERT_PROP_ID; 2281 hdr->unknown1 = 1; 2282 hdr->cb = 0; 2283 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 0, 2284 NULL, NULL); 2285 ok(!ret && GetLastError() == E_INVALIDARG, 2286 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2287 /* Test with a bad size in property header */ 2288 hdr->cb = sizeof(bigCert) - 1; 2289 memcpy(buf + sizeof(struct CertPropIDHeader), bigCert, sizeof(bigCert)); 2290 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 0, 2291 NULL, NULL); 2292 ok(!ret && GetLastError() == E_INVALIDARG, 2293 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2294 ret = CertAddSerializedElementToStore(store, buf, 2295 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0, 0, NULL, 2296 NULL); 2297 ok(!ret && GetLastError() == E_INVALIDARG, 2298 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2299 ret = CertAddSerializedElementToStore(store, buf, 2300 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW, 2301 0, 0, NULL, NULL); 2302 ok(!ret && GetLastError() == E_INVALIDARG, 2303 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2304 /* Kosher size in property header, but no context type */ 2305 hdr->cb = sizeof(bigCert); 2306 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 0, 2307 NULL, NULL); 2308 ok(!ret && GetLastError() == E_INVALIDARG, 2309 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2310 ret = CertAddSerializedElementToStore(store, buf, 2311 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0, 0, NULL, 2312 NULL); 2313 ok(!ret && GetLastError() == E_INVALIDARG, 2314 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2315 ret = CertAddSerializedElementToStore(store, buf, 2316 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW, 2317 0, 0, NULL, NULL); 2318 ok(!ret && GetLastError() == E_INVALIDARG, 2319 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2320 /* With a bad context type */ 2321 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 2322 CERT_STORE_CRL_CONTEXT_FLAG, NULL, NULL); 2323 ok(!ret && GetLastError() == E_INVALIDARG, 2324 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2325 ret = CertAddSerializedElementToStore(store, buf, 2326 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0, 2327 CERT_STORE_CRL_CONTEXT_FLAG, NULL, NULL); 2328 ok(!ret && GetLastError() == E_INVALIDARG, 2329 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2330 ret = CertAddSerializedElementToStore(store, buf, 2331 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW, 2332 0, CERT_STORE_CRL_CONTEXT_FLAG, NULL, NULL); 2333 ok(!ret && GetLastError() == E_INVALIDARG, 2334 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2335 /* Bad unknown field, good type */ 2336 hdr->unknown1 = 2; 2337 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 2338 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL); 2339 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2340 "Expected ERROR_FILE_NOT_FOUND got %08x\n", GetLastError()); 2341 ret = CertAddSerializedElementToStore(store, buf, 2342 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0, 2343 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL); 2344 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2345 "Expected ERROR_FILE_NOT_FOUND got %08x\n", GetLastError()); 2346 ret = CertAddSerializedElementToStore(store, buf, 2347 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW, 2348 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL); 2349 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2350 "Expected ERROR_FILE_NOT_FOUND got %08x\n", GetLastError()); 2351 /* Most everything okay, but bad add disposition */ 2352 hdr->unknown1 = 1; 2353 /* This crashes 2354 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 2355 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL); 2356 * as does this 2357 ret = CertAddSerializedElementToStore(store, buf, 2358 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0, 2359 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL); 2360 */ 2361 /* Everything okay, but buffer's too big */ 2362 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 2363 CERT_STORE_ADD_NEW, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL); 2364 ok(ret, "CertAddSerializedElementToStore failed: %08x\n", GetLastError()); 2365 /* Everything okay, check it's not re-added */ 2366 ret = CertAddSerializedElementToStore(store, buf, 2367 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW, 2368 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL); 2369 ok(!ret && GetLastError() == CRYPT_E_EXISTS, 2370 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError()); 2371 2372 context = CertEnumCertificatesInStore(store, NULL); 2373 ok(context != NULL, "Expected a cert\n"); 2374 if (context) 2375 CertDeleteCertificateFromStore(context); 2376 2377 /* Try adding with a bogus hash. Oddly enough, it succeeds, and the hash, 2378 * when queried, is the real hash rather than the bogus hash. 2379 */ 2380 hdr = (struct CertPropIDHeader *)(buf + sizeof(struct CertPropIDHeader) + 2381 sizeof(bigCert)); 2382 hdr->propID = CERT_HASH_PROP_ID; 2383 hdr->unknown1 = 1; 2384 hdr->cb = sizeof(hash); 2385 memset(hash, 0xc, sizeof(hash)); 2386 memcpy((LPBYTE)hdr + sizeof(struct CertPropIDHeader), hash, sizeof(hash)); 2387 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 2388 CERT_STORE_ADD_NEW, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, 2389 (const void **)&context); 2390 ok(ret, "CertAddSerializedElementToStore failed: %08x\n", GetLastError()); 2391 if (context) 2392 { 2393 BYTE hashVal[20], realHash[20]; 2394 DWORD size = sizeof(hashVal); 2395 2396 ret = CryptHashCertificate(0, 0, 0, bigCert, sizeof(bigCert), 2397 realHash, &size); 2398 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError()); 2399 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID, 2400 hashVal, &size); 2401 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 2402 GetLastError()); 2403 ok(!memcmp(hashVal, realHash, size), "Unexpected hash\n"); 2404 CertFreeCertificateContext(context); 2405 } 2406 2407 CertCloseStore(store, 0); 2408 } 2409 2410 static const BYTE serializedCertWithFriendlyName[] = { 2411 0x0b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x57,0x00,0x69, 2412 0x00,0x6e,0x00,0x65,0x00,0x54,0x00,0x65,0x00,0x73,0x00,0x74,0x00,0x00,0x00, 2413 0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02, 2414 0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55, 2415 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30, 2416 0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30, 2417 0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30, 2418 0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04, 2419 0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07, 2420 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03, 2421 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01, 2422 0x01 }; 2423 static const BYTE serializedStoreWithCertWithFriendlyName[] = { 2424 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x0b,0x00,0x00,0x00,0x01,0x00,0x00, 2425 0x00,0x12,0x00,0x00,0x00,0x57,0x00,0x69,0x00,0x6e,0x00,0x65,0x00,0x54,0x00, 2426 0x65,0x00,0x73,0x00,0x74,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x00, 2427 0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30, 2428 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, 2429 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31, 2430 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36, 2431 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15, 2432 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 2433 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00, 2434 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04, 2435 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 2436 0x00,0x00,0x00,0x00,0x00,0x00 }; 2437 static const BYTE serializedStoreWithCertAndHash[] = { 2438 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x03,0x00,0x00,0x00,0x01,0x00,0x00, 2439 0x00,0x14,0x00,0x00,0x00,0x6e,0x30,0x90,0x71,0x5f,0xd9,0x23,0x56,0xeb,0xae, 2440 0x25,0x40,0xe6,0x22,0xda,0x19,0x26,0x02,0xa6,0x08,0x20,0x00,0x00,0x00,0x01, 2441 0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06, 2442 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a, 2443 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36, 2444 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f, 2445 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, 2446 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75, 2447 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03, 2448 0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01, 2449 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00, 2450 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; 2451 2452 static void delete_test_key(void) 2453 { 2454 HKEY root_key, test_key; 2455 static const WCHAR SysCertW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', 2456 'S','y','s','t','e','m','C','e','r','t','i','f','i','c','a','t','e','s',0}; 2457 static const WCHAR WineTestW[] = {'W','i','n','e','T','e','s','t',0}; 2458 WCHAR subkey_name[32]; 2459 DWORD num_subkeys, subkey_name_len; 2460 int idx; 2461 2462 if (RegOpenKeyExW(HKEY_CURRENT_USER, SysCertW, 0, KEY_READ, &root_key)) 2463 return; 2464 if (RegOpenKeyExW(root_key, WineTestW, 0, KEY_READ, &test_key)) 2465 { 2466 RegCloseKey(root_key); 2467 return; 2468 } 2469 RegQueryInfoKeyW(test_key, NULL, NULL, NULL, &num_subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 2470 for (idx = num_subkeys; idx-- > 0;) 2471 { 2472 subkey_name_len = ARRAY_SIZE(subkey_name); 2473 RegEnumKeyExW(test_key, idx, subkey_name, &subkey_name_len, NULL, NULL, NULL, NULL); 2474 RegDeleteKeyW(test_key, subkey_name); 2475 } 2476 RegCloseKey(test_key); 2477 RegDeleteKeyW(root_key, WineTestW); 2478 RegCloseKey(root_key); 2479 } 2480 2481 static void testAddCertificateLink(void) 2482 { 2483 BOOL ret; 2484 HCERTSTORE store1, store2; 2485 PCCERT_CONTEXT source, linked; 2486 DWORD size; 2487 LPBYTE buf; 2488 CERT_NAME_BLOB blob; 2489 static const WCHAR szPrefix[] = { 'c','e','r',0 }; 2490 static const WCHAR szDot[] = { '.',0 }; 2491 static const WCHAR WineTestW[] = { 'W','i','n','e','T','e','s','t',0 }; 2492 WCHAR filename1[MAX_PATH], filename2[MAX_PATH]; 2493 HANDLE file; 2494 2495 if (0) 2496 { 2497 /* Crashes, i.e. the store is dereferenced without checking. */ 2498 ret = CertAddCertificateLinkToStore(NULL, NULL, 0, NULL); 2499 } 2500 2501 /* Adding a certificate link to a store requires a valid add disposition */ 2502 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 2503 CERT_STORE_CREATE_NEW_FLAG, NULL); 2504 SetLastError(0xdeadbeef); 2505 ret = CertAddCertificateLinkToStore(store1, NULL, 0, NULL); 2506 ok(!ret && GetLastError() == E_INVALIDARG, 2507 "expected E_INVALIDARG, got %08x\n", GetLastError()); 2508 source = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, 2509 sizeof(bigCert)); 2510 SetLastError(0xdeadbeef); 2511 ret = CertAddCertificateLinkToStore(store1, source, 0, NULL); 2512 ok(!ret && GetLastError() == E_INVALIDARG, 2513 "expected E_INVALIDARG, got %08x\n", GetLastError()); 2514 ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS, 2515 NULL); 2516 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); 2517 if (0) 2518 { 2519 /* Crashes, i.e. the source certificate is dereferenced without 2520 * checking when a valid add disposition is given. 2521 */ 2522 ret = CertAddCertificateLinkToStore(store1, NULL, CERT_STORE_ADD_ALWAYS, 2523 NULL); 2524 } 2525 CertCloseStore(store1, 0); 2526 2527 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 2528 CERT_STORE_CREATE_NEW_FLAG, NULL); 2529 ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS, 2530 &linked); 2531 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); 2532 if (ret) 2533 { 2534 ok(linked->hCertStore == store1, "unexpected store\n"); 2535 ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size); 2536 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", 2537 GetLastError()); 2538 buf = HeapAlloc(GetProcessHeap(), 0, size); 2539 if (buf) 2540 { 2541 ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size); 2542 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", 2543 GetLastError()); 2544 /* The serialized linked certificate is identical to the serialized 2545 * original certificate. 2546 */ 2547 ok(size == sizeof(serializedCert), "Wrong size %d\n", size); 2548 ok(!memcmp(serializedCert, buf, size), 2549 "Unexpected serialized cert\n"); 2550 HeapFree(GetProcessHeap(), 0, buf); 2551 } 2552 /* Set a friendly name on the source certificate... */ 2553 blob.pbData = (LPBYTE)WineTestW; 2554 blob.cbData = sizeof(WineTestW); 2555 ret = CertSetCertificateContextProperty(source, 2556 CERT_FRIENDLY_NAME_PROP_ID, 0, &blob); 2557 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", 2558 GetLastError()); 2559 /* and the linked certificate has the same friendly name. */ 2560 ret = CertGetCertificateContextProperty(linked, 2561 CERT_FRIENDLY_NAME_PROP_ID, NULL, &size); 2562 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 2563 GetLastError()); 2564 buf = HeapAlloc(GetProcessHeap(), 0, size); 2565 if (buf) 2566 { 2567 ret = CertGetCertificateContextProperty(linked, 2568 CERT_FRIENDLY_NAME_PROP_ID, buf, &size); 2569 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 2570 GetLastError()); 2571 ok(!lstrcmpW((LPCWSTR)buf, WineTestW), 2572 "unexpected friendly name\n"); 2573 HeapFree(GetProcessHeap(), 0, buf); 2574 } 2575 CertFreeCertificateContext(linked); 2576 } 2577 CertFreeCertificateContext(source); 2578 CertCloseStore(store1, 0); 2579 2580 /* Test adding a cert to a file store, committing the change to the store, 2581 * and creating a link to the resulting cert. 2582 */ 2583 if (!GetTempFileNameW(szDot, szPrefix, 0, filename1)) 2584 return; 2585 2586 DeleteFileW(filename1); 2587 file = CreateFileW(filename1, GENERIC_READ | GENERIC_WRITE, 0, NULL, 2588 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 2589 if (file == INVALID_HANDLE_VALUE) 2590 return; 2591 2592 store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 2593 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file); 2594 ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 2595 CloseHandle(file); 2596 2597 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, 2598 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &source); 2599 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 2600 GetLastError()); 2601 2602 /* Test adding a link to a memory store. */ 2603 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 2604 CERT_STORE_CREATE_NEW_FLAG, NULL); 2605 ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, 2606 &linked); 2607 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); 2608 if (ret) 2609 { 2610 ok(linked->hCertStore == store2, "unexpected store\n"); 2611 ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size); 2612 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", 2613 GetLastError()); 2614 buf = HeapAlloc(GetProcessHeap(), 0, size); 2615 if (buf) 2616 { 2617 ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size); 2618 /* The serialized linked certificate is identical to the serialized 2619 * original certificate. 2620 */ 2621 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", GetLastError()); 2622 ok(size == sizeof(serializedCert), "Wrong size %d\n", size); 2623 ok(!memcmp(serializedCert, buf, size), 2624 "Unexpected serialized cert\n"); 2625 HeapFree(GetProcessHeap(), 0, buf); 2626 } 2627 /* Set a friendly name on the source certificate... */ 2628 blob.pbData = (LPBYTE)WineTestW; 2629 blob.cbData = sizeof(WineTestW); 2630 ret = CertSetCertificateContextProperty(source, 2631 CERT_FRIENDLY_NAME_PROP_ID, 0, &blob); 2632 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", 2633 GetLastError()); 2634 /* and the linked certificate has the same friendly name. */ 2635 ret = CertGetCertificateContextProperty(linked, 2636 CERT_FRIENDLY_NAME_PROP_ID, NULL, &size); 2637 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 2638 GetLastError()); 2639 buf = HeapAlloc(GetProcessHeap(), 0, size); 2640 if (buf) 2641 { 2642 ret = CertGetCertificateContextProperty(linked, 2643 CERT_FRIENDLY_NAME_PROP_ID, buf, &size); 2644 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError()); 2645 ok(!lstrcmpW((LPCWSTR)buf, WineTestW), 2646 "unexpected friendly name\n"); 2647 HeapFree(GetProcessHeap(), 0, buf); 2648 } 2649 CertFreeCertificateContext(linked); 2650 } 2651 CertCloseStore(store2, 0); 2652 2653 if (!GetTempFileNameW(szDot, szPrefix, 0, filename2)) 2654 return; 2655 2656 DeleteFileW(filename2); 2657 file = CreateFileW(filename2, GENERIC_READ | GENERIC_WRITE, 0, NULL, 2658 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 2659 if (file == INVALID_HANDLE_VALUE) 2660 return; 2661 2662 store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 2663 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file); 2664 ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 2665 CloseHandle(file); 2666 /* Test adding a link to a file store. */ 2667 ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, 2668 &linked); 2669 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); 2670 if (ret) 2671 { 2672 ok(linked->hCertStore == store2, "unexpected store\n"); 2673 ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size); 2674 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", 2675 GetLastError()); 2676 buf = HeapAlloc(GetProcessHeap(), 0, size); 2677 if (buf) 2678 { 2679 ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size); 2680 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", 2681 GetLastError()); 2682 /* The serialized linked certificate now contains the friendly 2683 * name property. 2684 */ 2685 ok(size == sizeof(serializedCertWithFriendlyName), 2686 "Wrong size %d\n", size); 2687 ok(!memcmp(serializedCertWithFriendlyName, buf, size), 2688 "Unexpected serialized cert\n"); 2689 HeapFree(GetProcessHeap(), 0, buf); 2690 } 2691 CertFreeCertificateContext(linked); 2692 compareStore(store2, "file store -> file store", 2693 serializedStoreWithCertWithFriendlyName, 2694 sizeof(serializedStoreWithCertWithFriendlyName), FALSE); 2695 } 2696 CertCloseStore(store2, 0); 2697 DeleteFileW(filename2); 2698 2699 CertFreeCertificateContext(source); 2700 2701 CertCloseStore(store1, 0); 2702 DeleteFileW(filename1); 2703 2704 /* Test adding a link to a system store (which is a collection store.) */ 2705 store1 = CertOpenSystemStoreA(0, "My"); 2706 source = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, 2707 sizeof(bigCert)); 2708 SetLastError(0xdeadbeef); 2709 ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS, 2710 &linked); 2711 ok(!ret && GetLastError() == E_INVALIDARG, 2712 "expected E_INVALIDARG, got %08x\n", GetLastError()); 2713 CertFreeCertificateContext(source); 2714 2715 /* Test adding a link to a file store, where the linked certificate is 2716 * in a system store. 2717 */ 2718 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, 2719 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &source); 2720 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 2721 GetLastError()); 2722 if (!GetTempFileNameW(szDot, szPrefix, 0, filename1)) 2723 return; 2724 2725 DeleteFileW(filename1); 2726 file = CreateFileW(filename1, GENERIC_READ | GENERIC_WRITE, 0, NULL, 2727 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 2728 if (file == INVALID_HANDLE_VALUE) 2729 return; 2730 2731 store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 2732 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file); 2733 ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 2734 CloseHandle(file); 2735 2736 ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, 2737 &linked); 2738 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); 2739 if (ret) 2740 { 2741 ok(linked->hCertStore == store2, "unexpected store\n"); 2742 ret = CertControlStore(store2, 0, CERT_STORE_CTRL_COMMIT, NULL); 2743 ok(ret, "CertControlStore failed: %d\n", ret); 2744 compareStore(store2, "file store -> system store", 2745 serializedStoreWithCertAndHash, 2746 sizeof(serializedStoreWithCertAndHash), TRUE); 2747 CertFreeCertificateContext(linked); 2748 } 2749 2750 CertCloseStore(store2, 0); 2751 DeleteFileW(filename1); 2752 2753 /* Test adding a link to a registry store, where the linked certificate is 2754 * in a system store. 2755 */ 2756 store2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 2757 CERT_SYSTEM_STORE_CURRENT_USER, WineTestW); 2758 ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 2759 ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, 2760 &linked); 2761 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); 2762 if (ret) 2763 { 2764 ok(linked->hCertStore == store2, "unexpected store\n"); 2765 CertDeleteCertificateFromStore(linked); 2766 } 2767 CertCloseStore(store2, 0); 2768 2769 CertFreeCertificateContext(source); 2770 CertCloseStore(store1, 0); 2771 2772 delete_test_key(); 2773 } 2774 2775 static DWORD countCertsInStore(HCERTSTORE store) 2776 { 2777 PCCERT_CONTEXT cert = NULL; 2778 DWORD certs = 0; 2779 2780 do { 2781 cert = CertEnumCertificatesInStore(store, cert); 2782 if (cert) 2783 certs++; 2784 } while (cert); 2785 return certs; 2786 } 2787 2788 static DWORD countCRLsInStore(HCERTSTORE store) 2789 { 2790 PCCRL_CONTEXT crl = NULL; 2791 DWORD crls = 0; 2792 2793 do { 2794 crl = CertEnumCRLsInStore(store, crl); 2795 if (crl) 2796 crls++; 2797 } while (crl); 2798 return crls; 2799 } 2800 2801 static void testEmptyStore(void) 2802 { 2803 const CERT_CONTEXT *cert, *cert2, *cert3; 2804 const CRL_CONTEXT *crl; 2805 const CTL_CONTEXT *ctl; 2806 HCERTSTORE store; 2807 BOOL res; 2808 2809 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); 2810 ok(cert != NULL, "CertCreateCertificateContext failed\n"); 2811 ok(cert->hCertStore != NULL, "cert->hCertStore == NULL\n"); 2812 if(!cert->hCertStore) { 2813 CertFreeCertificateContext(cert); 2814 return; 2815 } 2816 2817 test_store_is_empty(cert->hCertStore); 2818 2819 cert2 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2, sizeof(bigCert2)); 2820 ok(cert2 != NULL, "CertCreateCertificateContext failed\n"); 2821 ok(cert2->hCertStore == cert->hCertStore, "Unexpected hCertStore\n"); 2822 2823 test_store_is_empty(cert2->hCertStore); 2824 2825 res = CertAddCertificateContextToStore(cert->hCertStore, cert2, CERT_STORE_ADD_NEW, &cert3); 2826 ok(res, "CertAddCertificateContextToStore failed\n"); 2827 todo_wine 2828 ok(cert3 && cert3 != cert2, "Unexpected cert3\n"); 2829 ok(cert3->hCertStore == cert->hCertStore, "Unexpected hCertStore\n"); 2830 2831 test_store_is_empty(cert->hCertStore); 2832 2833 res = CertDeleteCertificateFromStore(cert3); 2834 ok(res, "CertDeleteCertificateContextFromStore failed\n"); 2835 ok(cert3->hCertStore == cert->hCertStore, "Unexpected hCertStore\n"); 2836 2837 CertFreeCertificateContext(cert3); 2838 2839 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); 2840 ok(store != NULL, "CertOpenStore failed\n"); 2841 2842 res = CertAddCertificateContextToStore(store, cert2, CERT_STORE_ADD_NEW, &cert3); 2843 ok(res, "CertAddCertificateContextToStore failed\n"); 2844 ok(cert3 && cert3 != cert2, "Unexpected cert3\n"); 2845 ok(cert3->hCertStore == store, "Unexpected hCertStore\n"); 2846 2847 res = CertDeleteCertificateFromStore(cert3); 2848 ok(res, "CertDeleteCertificateContextFromStore failed\n"); 2849 ok(cert3->hCertStore == store, "Unexpected hCertStore\n"); 2850 2851 CertCloseStore(store, 0); 2852 CertFreeCertificateContext(cert3); 2853 2854 res = CertCloseStore(cert->hCertStore, CERT_CLOSE_STORE_CHECK_FLAG); 2855 ok(!res && GetLastError() == E_UNEXPECTED, "CertCloseStore returned: %x(%x)\n", res, GetLastError()); 2856 2857 res = CertCloseStore(cert->hCertStore, 0); 2858 ok(!res && GetLastError() == E_UNEXPECTED, "CertCloseStore returned: %x(%x)\n", res, GetLastError()); 2859 2860 CertFreeCertificateContext(cert2); 2861 2862 crl = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL, sizeof(signedCRL)); 2863 ok(crl != NULL, "CertCreateCRLContext failed\n"); 2864 ok(crl->hCertStore == cert->hCertStore, "unexpected hCertStore\n"); 2865 2866 CertFreeCRLContext(crl); 2867 2868 ctl = CertCreateCTLContext(X509_ASN_ENCODING, signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent)); 2869 ok(ctl != NULL, "CertCreateCTLContext failed\n"); 2870 ok(ctl->hCertStore == cert->hCertStore, "unexpected hCertStore\n"); 2871 2872 CertFreeCTLContext(ctl); 2873 2874 CertFreeCertificateContext(cert); 2875 } 2876 2877 static void testCloseStore(void) 2878 { 2879 const CERT_CONTEXT *cert; 2880 const CRL_CONTEXT *crl; 2881 const CTL_CONTEXT *ctl; 2882 HCERTSTORE store, store2; 2883 BOOL res; 2884 2885 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); 2886 ok(store != NULL, "CertOpenStore failed\n"); 2887 2888 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG); 2889 ok(res, "CertCloseStore failed\n"); 2890 2891 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); 2892 ok(store != NULL, "CertOpenStore failed\n"); 2893 2894 store2 = CertDuplicateStore(store); 2895 ok(store2 != NULL, "CertCloneStore failed\n"); 2896 ok(store2 == store, "unexpected store2\n"); 2897 2898 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG); 2899 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n"); 2900 2901 res = CertCloseStore(store2, CERT_CLOSE_STORE_CHECK_FLAG); 2902 ok(res, "CertCloseStore failed\n"); 2903 2904 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); 2905 ok(store != NULL, "CertOpenStore failed\n"); 2906 2907 res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, bigCert, 2908 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert); 2909 ok(res, "CertAddEncodedCertificateToStore failed\n"); 2910 2911 /* There is still a reference from cert */ 2912 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG); 2913 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n"); 2914 2915 res = CertFreeCertificateContext(cert); 2916 ok(res, "CertFreeCertificateContext failed\n"); 2917 2918 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); 2919 ok(store != NULL, "CertOpenStore failed\n"); 2920 2921 res = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL, 2922 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl); 2923 ok(res, "CertAddEncodedCRLToStore failed\n"); 2924 2925 /* There is still a reference from CRL */ 2926 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG); 2927 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n"); 2928 2929 res = CertFreeCRLContext(crl); 2930 ok(res, "CertFreeCRLContext failed\n"); 2931 2932 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); 2933 ok(store != NULL, "CertOpenStore failed\n"); 2934 2935 res = CertAddEncodedCTLToStore(store, X509_ASN_ENCODING, signedCTLWithCTLInnerContent, 2936 sizeof(signedCTLWithCTLInnerContent), CERT_STORE_ADD_ALWAYS, &ctl); 2937 ok(res, "CertAddEncodedCTLToStore failed\n"); 2938 2939 /* There is still a reference from CTL */ 2940 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG); 2941 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore returned: %x(%u)\n", res, GetLastError()); 2942 2943 res = CertFreeCTLContext(ctl); 2944 ok(res, "CertFreeCTLContext failed\n"); 2945 2946 /* Add all kinds of contexts, then release external references and make sure that store is properly closed. */ 2947 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); 2948 ok(store != NULL, "CertOpenStore failed\n"); 2949 2950 res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, bigCert, 2951 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert); 2952 ok(res, "CertAddEncodedCertificateToStore failed\n"); 2953 2954 res = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL, 2955 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl); 2956 ok(res, "CertAddEncodedCRLToStore failed\n"); 2957 2958 res = CertAddEncodedCTLToStore(store, X509_ASN_ENCODING, signedCTLWithCTLInnerContent, 2959 sizeof(signedCTLWithCTLInnerContent), CERT_STORE_ADD_ALWAYS, &ctl); 2960 ok(res, "CertAddEncodedCTLToStore failed\n"); 2961 2962 CertFreeCertificateContext(cert); 2963 CertFreeCRLContext(crl); 2964 CertFreeCTLContext(ctl); 2965 2966 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG); 2967 ok(res, "CertCloseStore failed\n"); 2968 } 2969 2970 static void test_I_UpdateStore(void) 2971 { 2972 HMODULE lib = GetModuleHandleA("crypt32"); 2973 BOOL (WINAPI *pI_CertUpdatestore)(HCERTSTORE, HCERTSTORE, DWORD, DWORD) = 2974 (void *)GetProcAddress(lib, "I_CertUpdateStore"); 2975 BOOL ret; 2976 HCERTSTORE store1, store2; 2977 PCCERT_CONTEXT cert; 2978 DWORD certs; 2979 2980 if (!pI_CertUpdatestore) 2981 { 2982 win_skip("No I_CertUpdateStore\n"); 2983 return; 2984 } 2985 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 2986 CERT_STORE_CREATE_NEW_FLAG, NULL); 2987 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 2988 CERT_STORE_CREATE_NEW_FLAG, NULL); 2989 2990 /* Crash 2991 ret = pI_CertUpdatestore(NULL, NULL, 0, 0); 2992 ret = pI_CertUpdatestore(store1, NULL, 0, 0); 2993 ret = pI_CertUpdatestore(NULL, store2, 0, 0); 2994 */ 2995 ret = pI_CertUpdatestore(store1, store2, 0, 0); 2996 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError()); 2997 2998 CertAddEncodedCertificateToStore(store2, X509_ASN_ENCODING, bigCert, 2999 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert); 3000 /* I_CertUpdateStore adds the contexts from store2 to store1 */ 3001 ret = pI_CertUpdatestore(store1, store2, 0, 0); 3002 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError()); 3003 certs = countCertsInStore(store1); 3004 ok(certs == 1, "Expected 1 cert, got %d\n", certs); 3005 /* Calling it a second time has no effect */ 3006 ret = pI_CertUpdatestore(store1, store2, 0, 0); 3007 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError()); 3008 certs = countCertsInStore(store1); 3009 ok(certs == 1, "Expected 1 cert, got %d\n", certs); 3010 3011 /* The last parameters to I_CertUpdateStore appear to be ignored */ 3012 ret = pI_CertUpdatestore(store1, store2, 1, 0); 3013 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError()); 3014 ret = pI_CertUpdatestore(store1, store2, 0, 1); 3015 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError()); 3016 3017 CertAddEncodedCRLToStore(store2, X509_ASN_ENCODING, signedCRL, 3018 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL); 3019 3020 /* I_CertUpdateStore also adds the CRLs from store2 to store1 */ 3021 ret = pI_CertUpdatestore(store1, store2, 0, 0); 3022 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError()); 3023 certs = countCertsInStore(store1); 3024 ok(certs == 1, "Expected 1 cert, got %d\n", certs); 3025 certs = countCRLsInStore(store1); 3026 ok(certs == 1, "Expected 1 CRL, got %d\n", certs); 3027 3028 CertDeleteCertificateFromStore(cert); 3029 /* If a context is deleted from store2, I_CertUpdateStore deletes it 3030 * from store1 3031 */ 3032 ret = pI_CertUpdatestore(store1, store2, 0, 0); 3033 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError()); 3034 certs = countCertsInStore(store1); 3035 ok(certs == 0, "Expected 0 certs, got %d\n", certs); 3036 3037 CertCloseStore(store1, 0); 3038 CertCloseStore(store2, 0); 3039 } 3040 3041 START_TEST(store) 3042 { 3043 /* various combinations of CertOpenStore */ 3044 testMemStore(); 3045 testCollectionStore(); 3046 testStoresInCollection(); 3047 3048 testRegStore(); 3049 testRegStoreSavedCerts(); 3050 3051 testSystemRegStore(); 3052 testSystemStore(); 3053 testFileStore(); 3054 testFileNameStore(); 3055 testMessageStore(); 3056 testSerializedStore(); 3057 testCloseStore(); 3058 3059 testCertRegisterSystemStore(); 3060 3061 testCertOpenSystemStore(); 3062 testCertEnumSystemStore(); 3063 testStoreProperty(); 3064 3065 testAddSerialized(); 3066 testAddCertificateLink(); 3067 3068 testEmptyStore(); 3069 3070 test_I_UpdateStore(); 3071 } 3072