1 /* 2 * crypt32 cert functions 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 "precomp.h" 22 23 static PCCERT_CONTEXT (WINAPI *pCertCreateSelfSignCertificate)(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE,PCERT_NAME_BLOB,DWORD,PCRYPT_KEY_PROV_INFO,PCRYPT_ALGORITHM_IDENTIFIER,PSYSTEMTIME,PSYSTEMTIME,PCERT_EXTENSIONS); 24 static BOOL (WINAPI *pCertGetValidUsages)(DWORD,PCCERT_CONTEXT*,int*,LPSTR*,DWORD*); 25 static BOOL (WINAPI *pCryptAcquireCertificatePrivateKey)(PCCERT_CONTEXT,DWORD,void*,HCRYPTPROV_OR_NCRYPT_KEY_HANDLE*,DWORD*,BOOL*); 26 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*); 27 static BOOL (WINAPI * pCryptVerifyCertificateSignatureEx) 28 (HCRYPTPROV, DWORD, DWORD, void *, DWORD, void *, DWORD, void *); 29 30 static BOOL (WINAPI * pCryptAcquireContextA) 31 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD); 32 33 static void init_function_pointers(void) 34 { 35 HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll"); 36 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll"); 37 38 #define GET_PROC(dll, func) \ 39 p ## func = (void *)GetProcAddress(dll, #func); \ 40 if(!p ## func) \ 41 trace("GetProcAddress(%s) failed\n", #func); 42 43 GET_PROC(hCrypt32, CertCreateSelfSignCertificate) 44 GET_PROC(hCrypt32, CertGetValidUsages) 45 GET_PROC(hCrypt32, CryptAcquireCertificatePrivateKey) 46 GET_PROC(hCrypt32, CryptEncodeObjectEx) 47 GET_PROC(hCrypt32, CryptVerifyCertificateSignatureEx) 48 49 GET_PROC(hAdvapi32, CryptAcquireContextA) 50 51 #undef GET_PROC 52 } 53 54 static BYTE subjectName[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 55 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 56 0x6e, 0x67, 0x00 }; 57 static BYTE serialNum[] = { 1 }; 58 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 59 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 60 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 61 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 62 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 63 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 64 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 65 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 66 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 67 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; 68 static BYTE bigCertHash[] = { 0x6e, 0x30, 0x90, 0x71, 0x5f, 0xd9, 0x23, 69 0x56, 0xeb, 0xae, 0x25, 0x40, 0xe6, 0x22, 0xda, 0x19, 0x26, 0x02, 0xa6, 0x08 }; 70 71 static const BYTE bigCertWithDifferentSubject[] = { 0x30, 0x7a, 0x02, 0x01, 0x02, 72 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 73 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 74 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 75 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 76 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 77 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 78 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 79 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 80 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 81 0x01, 0x01 }; 82 static const BYTE bigCertWithDifferentIssuer[] = { 0x30, 0x7a, 0x02, 0x01, 83 0x01, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 84 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 85 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 86 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 87 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 88 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 89 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 90 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 91 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 92 0x02, 0x01, 0x01 }; 93 94 static BYTE subjectName2[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 95 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 96 0x6e, 0x67, 0x00 }; 97 static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 98 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 99 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 100 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 101 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 102 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 103 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 104 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 105 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 106 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; 107 static const BYTE bigCert2WithDifferentSerial[] = { 0x30, 0x7a, 0x02, 0x01, 108 0x02, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 109 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 110 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 111 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 112 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 113 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 114 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 115 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 116 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 117 0x02, 0x01, 0x01 }; 118 static BYTE bigCert2Hash[] = { 0x4a, 0x7f, 0x32, 0x1f, 0xcf, 0x3b, 0xc0, 119 0x87, 0x48, 0x2b, 0xa1, 0x86, 0x54, 0x18, 0xe4, 0x3a, 0x0e, 0x53, 0x7e, 0x2b }; 120 121 static const BYTE certWithUsage[] = { 0x30, 0x81, 0x93, 0x02, 0x01, 0x01, 0x30, 122 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 123 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 124 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 125 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 126 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 127 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 128 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 129 0x03, 0x01, 0x00, 0xa3, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x1d, 130 0x25, 0x01, 0x01, 0xff, 0x04, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 131 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 132 0x03, 0x02, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 }; 133 134 static void testAddCert(void) 135 { 136 HCERTSTORE store; 137 HCERTSTORE collection; 138 PCCERT_CONTEXT context; 139 PCCERT_CONTEXT copyContext; 140 BOOL ret; 141 142 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 143 CERT_STORE_CREATE_NEW_FLAG, NULL); 144 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError()); 145 if (!store) 146 return; 147 148 /* Weird--bad add disposition leads to an access violation in Windows. 149 * Both tests crash on some win9x boxes. 150 */ 151 if (0) 152 { 153 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert, 154 sizeof(bigCert), 0, NULL); 155 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION || 156 GetLastError() == E_INVALIDARG), 157 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n", 158 GetLastError()); 159 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 160 bigCert, sizeof(bigCert), 0, NULL); 161 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION || 162 GetLastError() == E_INVALIDARG), 163 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n", 164 GetLastError()); 165 } 166 167 /* Weird--can add a cert to the NULL store (does this have special 168 * meaning?) 169 */ 170 context = NULL; 171 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert, 172 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context); 173 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */), 174 "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 175 if (context) 176 CertFreeCertificateContext(context); 177 if (!ret && GetLastError() == OSS_DATA_ERROR) 178 { 179 skip("bigCert can't be decoded, skipping tests\n"); 180 return; 181 } 182 183 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 184 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 185 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 186 GetLastError()); 187 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 188 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL); 189 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 190 GetLastError()); 191 /* This has the same name as bigCert, so finding isn't done by name */ 192 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 193 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, &context); 194 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 195 GetLastError()); 196 ok(context != NULL, "Expected a context\n"); 197 if (context) 198 { 199 CRYPT_DATA_BLOB hash = { sizeof(bigCert2Hash), bigCert2Hash }; 200 201 /* Duplicate (AddRef) the context so we can still use it after 202 * deleting it from the store. 203 */ 204 CertDuplicateCertificateContext(context); 205 CertDeleteCertificateFromStore(context); 206 /* Set the same hash as bigCert2, and try to readd it */ 207 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 208 0, &hash); 209 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", 210 GetLastError()); 211 ret = CertAddCertificateContextToStore(store, context, 212 CERT_STORE_ADD_NEW, NULL); 213 /* The failure is a bit odd (CRYPT_E_ASN1_BADTAG), so just check 214 * that it fails. 215 */ 216 ok(!ret, "Expected failure\n"); 217 CertFreeCertificateContext(context); 218 } 219 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2, 220 sizeof(bigCert2)); 221 ok(context != NULL, "Expected a context\n"); 222 if (context) 223 { 224 /* Try to readd bigCert2 to the store */ 225 ret = CertAddCertificateContextToStore(store, context, 226 CERT_STORE_ADD_NEW, NULL); 227 ok(!ret && GetLastError() == CRYPT_E_EXISTS, 228 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError()); 229 CertFreeCertificateContext(context); 230 } 231 232 /* Adding a cert with the same issuer name and serial number (but 233 * different subject) as an existing cert succeeds. 234 */ 235 context = NULL; 236 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 237 bigCert2WithDifferentSerial, sizeof(bigCert2WithDifferentSerial), 238 CERT_STORE_ADD_NEW, &context); 239 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 240 GetLastError()); 241 if (context) 242 CertDeleteCertificateFromStore(context); 243 244 /* Adding a cert with the same subject name and serial number (but 245 * different issuer) as an existing cert succeeds. 246 */ 247 context = NULL; 248 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 249 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject), 250 CERT_STORE_ADD_NEW, &context); 251 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 252 GetLastError()); 253 if (context) 254 CertDeleteCertificateFromStore(context); 255 256 /* Adding a cert with the same issuer name and serial number (but 257 * different otherwise) as an existing cert succeeds. 258 */ 259 context = NULL; 260 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 261 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer), 262 CERT_STORE_ADD_NEW, &context); 263 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 264 GetLastError()); 265 if (context) 266 CertDeleteCertificateFromStore(context); 267 268 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 269 CERT_STORE_CREATE_NEW_FLAG, NULL); 270 ok(collection != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 271 if (collection) 272 { 273 /* Add store to the collection, but disable updates */ 274 CertAddStoreToCollection(collection, store, 0, 0); 275 276 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2, 277 sizeof(bigCert2)); 278 ok(context != NULL, "Expected a context\n"); 279 if (context) 280 { 281 /* Try to readd bigCert2 to the collection */ 282 ret = CertAddCertificateContextToStore(collection, context, 283 CERT_STORE_ADD_NEW, NULL); 284 ok(!ret && GetLastError() == CRYPT_E_EXISTS, 285 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError()); 286 /* Replacing an existing certificate context is allowed, even 287 * though updates to the collection aren't.. 288 */ 289 ret = CertAddCertificateContextToStore(collection, context, 290 CERT_STORE_ADD_REPLACE_EXISTING, NULL); 291 ok(ret, "CertAddCertificateContextToStore failed: %08x\n", 292 GetLastError()); 293 /* use the existing certificate and ask for a copy of the context*/ 294 copyContext = NULL; 295 ret = CertAddCertificateContextToStore(collection, context, 296 CERT_STORE_ADD_USE_EXISTING, ©Context); 297 ok(ret, "CertAddCertificateContextToStore failed: %08x\n", 298 GetLastError()); 299 ok(copyContext != NULL, "Expected on output a non NULL copyContext\n"); 300 if (copyContext) 301 CertFreeCertificateContext(copyContext); 302 /* but adding a new certificate isn't allowed. */ 303 ret = CertAddCertificateContextToStore(collection, context, 304 CERT_STORE_ADD_ALWAYS, NULL); 305 ok(!ret && GetLastError() == E_ACCESSDENIED, 306 "Expected E_ACCESSDENIED, got %08x\n", GetLastError()); 307 CertFreeCertificateContext(context); 308 } 309 310 CertCloseStore(collection, 0); 311 } 312 313 CertCloseStore(store, 0); 314 } 315 316 static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID, 317 PCCERT_CONTEXT context, DWORD propID) 318 { 319 BYTE hash[20] = { 0 }, hashProperty[20]; 320 BOOL ret; 321 DWORD size; 322 DWORD dwSizeWithNull; 323 324 memset(hash, 0, sizeof(hash)); 325 memset(hashProperty, 0, sizeof(hashProperty)); 326 size = sizeof(hash); 327 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size); 328 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError()); 329 ret = CertGetCertificateContextProperty(context, propID, NULL, 330 &dwSizeWithNull); 331 ok(ret, "algID %08x, propID %d: CertGetCertificateContextProperty failed: %08x\n", 332 algID, propID, GetLastError()); 333 ret = CertGetCertificateContextProperty(context, propID, hashProperty, 334 &size); 335 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 336 GetLastError()); 337 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n", 338 propID); 339 ok(size == dwSizeWithNull, "Unexpected length of hash for property: received %d instead of %d\n", 340 dwSizeWithNull,size); 341 } 342 343 static const CHAR cspNameA[] = "WineCryptTemp"; 344 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e','m','p',0 }; 345 static const BYTE v1CertWithPubKey[] = { 346 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 347 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 348 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 349 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 350 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 351 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 352 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 353 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 354 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06, 355 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02, 356 0x01,0x01 }; 357 static const BYTE v1CertWithSubjectKeyId[] = { 358 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11, 359 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 360 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 361 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 362 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06, 363 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67, 364 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30, 365 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20, 366 0x4c,0x61,0x6e,0x67,0x00 }; 367 static const BYTE subjectKeyId[] = { 368 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 369 static const BYTE selfSignedCert[] = { 370 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 371 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49, 372 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 373 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 374 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 375 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30, 376 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31, 377 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 378 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 379 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 380 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 381 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4, 382 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b, 383 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0, 384 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96, 385 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79, 386 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 387 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41, 388 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66, 389 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a, 390 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7, 391 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f, 392 0xa8, 0x76, 0x57, 0x92, 0x36 }; 393 static const BYTE selfSignedSignatureHash[] = { 0x07,0x5a,0x3e,0xfd,0x0d,0xf6, 394 0x88,0xeb,0x00,0x64,0xbd,0xc9,0xd6,0xea,0x0a,0x7c,0xcc,0x24,0xdb,0x5d }; 395 396 static void testCertProperties(void) 397 { 398 PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING, 399 bigCert, sizeof(bigCert)); 400 DWORD propID, numProps, access, size; 401 BOOL ret; 402 BYTE hash[20] = { 0 }, hashProperty[20]; 403 CRYPT_DATA_BLOB blob; 404 CERT_KEY_CONTEXT keyContext; 405 406 ok(context != NULL || broken(GetLastError() == OSS_DATA_ERROR /* win98 */), 407 "CertCreateCertificateContext failed: %08x\n", GetLastError()); 408 if (!context) 409 return; 410 411 /* This crashes 412 propID = CertEnumCertificateContextProperties(NULL, 0); 413 */ 414 415 propID = 0; 416 numProps = 0; 417 do { 418 propID = CertEnumCertificateContextProperties(context, propID); 419 if (propID) 420 numProps++; 421 } while (propID != 0); 422 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps); 423 424 /* Tests with a NULL cert context. Prop ID 0 fails.. */ 425 ret = CertSetCertificateContextProperty(NULL, 0, 0, NULL); 426 ok(!ret && GetLastError() == E_INVALIDARG, 427 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 428 /* while this just crashes. 429 ret = CertSetCertificateContextProperty(NULL, 430 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL); 431 */ 432 433 ret = CertSetCertificateContextProperty(context, 0, 0, NULL); 434 ok(!ret && GetLastError() == E_INVALIDARG, 435 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 436 /* Can't set the cert property directly, this crashes. 437 ret = CertSetCertificateContextProperty(context, 438 CERT_CERT_PROP_ID, 0, bigCert2); 439 */ 440 441 /* These all crash. 442 ret = CertGetCertificateContextProperty(context, 443 CERT_ACCESS_STATE_PROP_ID, 0, NULL); 444 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID, 445 NULL, NULL); 446 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID, 447 hashProperty, NULL); 448 */ 449 /* A missing prop */ 450 size = 0; 451 ret = CertGetCertificateContextProperty(context, 452 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size); 453 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 454 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 455 /* And, an implicit property */ 456 size = sizeof(access); 457 ret = CertGetCertificateContextProperty(context, 458 CERT_ACCESS_STATE_PROP_ID, &access, &size); 459 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 460 GetLastError()); 461 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG), 462 "Didn't expect a persisted cert\n"); 463 /* Trying to set this "read only" property crashes. 464 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG; 465 ret = CertSetCertificateContextProperty(context, 466 CERT_ACCESS_STATE_PROP_ID, 0, &access); 467 */ 468 469 /* Can I set the hash to an invalid hash? */ 470 blob.pbData = hash; 471 blob.cbData = sizeof(hash); 472 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0, 473 &blob); 474 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", 475 GetLastError()); 476 size = sizeof(hashProperty); 477 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID, 478 hashProperty, &size); 479 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 480 GetLastError()); 481 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n"); 482 /* Delete the (bogus) hash, and get the real one */ 483 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0, 484 NULL); 485 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", 486 GetLastError()); 487 checkHash(bigCert, sizeof(bigCert), CALG_SHA1, context, 488 CERT_HASH_PROP_ID); 489 490 /* Now that the hash property is set, we should get one property when 491 * enumerating. 492 */ 493 propID = 0; 494 numProps = 0; 495 do { 496 propID = CertEnumCertificateContextProperties(context, propID); 497 if (propID) 498 numProps++; 499 } while (propID != 0); 500 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps); 501 502 /* Check a few other implicit properties */ 503 checkHash(bigCert, sizeof(bigCert), CALG_MD5, context, 504 CERT_MD5_HASH_PROP_ID); 505 506 /* Getting the signature hash fails with this bogus certificate */ 507 size = 0; 508 ret = CertGetCertificateContextProperty(context, 509 CERT_SIGNATURE_HASH_PROP_ID, NULL, &size); 510 ok(!ret && 511 (GetLastError() == CRYPT_E_ASN1_BADTAG || 512 GetLastError() == CRYPT_E_NOT_FOUND || 513 GetLastError() == OSS_DATA_ERROR), /* win9x */ 514 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); 515 516 /* Test key contexts and handles and such */ 517 size = 0; 518 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID, 519 NULL, &size); 520 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 521 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 522 size = sizeof(CERT_KEY_CONTEXT); 523 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID, 524 NULL, &size); 525 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 526 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 527 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID, 528 &keyContext, &size); 529 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 530 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 531 /* Key context with an invalid size */ 532 keyContext.cbSize = 0; 533 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID, 534 0, &keyContext); 535 ok(!ret && GetLastError() == E_INVALIDARG, 536 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 537 size = sizeof(keyContext); 538 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID, 539 &keyContext, &size); 540 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 541 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 542 keyContext.cbSize = sizeof(keyContext); 543 keyContext.hCryptProv = 0; 544 keyContext.dwKeySpec = AT_SIGNATURE; 545 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID, 546 0, &keyContext); 547 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError()); 548 /* Now that that's set, the key prov handle property is also gettable. 549 */ 550 size = sizeof(keyContext.hCryptProv); 551 ret = CertGetCertificateContextProperty(context, 552 CERT_KEY_PROV_HANDLE_PROP_ID, &keyContext.hCryptProv, &size); 553 ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08x\n", 554 GetLastError()); 555 /* Remove the key prov handle property.. */ 556 ret = CertSetCertificateContextProperty(context, 557 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL); 558 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", 559 GetLastError()); 560 /* and the key context's CSP is set to NULL. */ 561 size = sizeof(keyContext); 562 ret = CertGetCertificateContextProperty(context, 563 CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size); 564 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 565 GetLastError()); 566 ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n"); 567 568 /* According to MSDN the subject key id can be stored as a property, 569 * as a subject key extension, or as the SHA1 hash of the public key, 570 * but this cert has none of them: 571 */ 572 ret = CertGetCertificateContextProperty(context, 573 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); 574 ok(!ret && GetLastError() == ERROR_INVALID_DATA, 575 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError()); 576 CertFreeCertificateContext(context); 577 /* This cert does have a public key, but its subject key identifier still 578 * isn't available: */ 579 context = CertCreateCertificateContext(X509_ASN_ENCODING, 580 v1CertWithPubKey, sizeof(v1CertWithPubKey)); 581 ret = CertGetCertificateContextProperty(context, 582 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); 583 ok(!ret && GetLastError() == ERROR_INVALID_DATA, 584 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError()); 585 CertFreeCertificateContext(context); 586 /* This cert with a subject key extension can have its key identifier 587 * property retrieved: 588 */ 589 context = CertCreateCertificateContext(X509_ASN_ENCODING, 590 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId)); 591 ret = CertGetCertificateContextProperty(context, 592 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); 593 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError()); 594 if (ret) 595 { 596 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size); 597 598 if (buf) 599 { 600 ret = CertGetCertificateContextProperty(context, 601 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); 602 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 603 GetLastError()); 604 ok(!memcmp(buf, subjectKeyId, size), "Unexpected subject key id\n"); 605 HeapFree(GetProcessHeap(), 0, buf); 606 } 607 } 608 CertFreeCertificateContext(context); 609 610 context = CertCreateCertificateContext(X509_ASN_ENCODING, 611 selfSignedCert, sizeof(selfSignedCert)); 612 /* Getting the signature hash of a valid (self-signed) cert succeeds */ 613 size = 0; 614 ret = CertGetCertificateContextProperty(context, 615 CERT_SIGNATURE_HASH_PROP_ID, NULL, &size); 616 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError()); 617 ok(size == sizeof(selfSignedSignatureHash), "unexpected size %d\n", size); 618 ret = CertGetCertificateContextProperty(context, 619 CERT_SIGNATURE_HASH_PROP_ID, hashProperty, &size); 620 if (ret) 621 ok(!memcmp(hashProperty, selfSignedSignatureHash, size), 622 "unexpected value\n"); 623 CertFreeCertificateContext(context); 624 } 625 626 static void testCreateCert(void) 627 { 628 PCCERT_CONTEXT cert, enumCert; 629 DWORD count, size; 630 BOOL ret; 631 632 SetLastError(0xdeadbeef); 633 cert = CertCreateCertificateContext(0, NULL, 0); 634 ok(!cert && GetLastError() == E_INVALIDARG, 635 "expected E_INVALIDARG, got %08x\n", GetLastError()); 636 SetLastError(0xdeadbeef); 637 cert = CertCreateCertificateContext(0, selfSignedCert, 638 sizeof(selfSignedCert)); 639 ok(!cert && GetLastError() == E_INVALIDARG, 640 "expected E_INVALIDARG, got %08x\n", GetLastError()); 641 SetLastError(0xdeadbeef); 642 cert = CertCreateCertificateContext(X509_ASN_ENCODING, NULL, 0); 643 ok(!cert && 644 (GetLastError() == CRYPT_E_ASN1_EOD || 645 broken(GetLastError() == OSS_MORE_INPUT /* NT4 */)), 646 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); 647 648 cert = CertCreateCertificateContext(X509_ASN_ENCODING, 649 selfSignedCert, sizeof(selfSignedCert)); 650 ok(cert != NULL, "creating cert failed: %08x\n", GetLastError()); 651 /* Even in-memory certs are expected to have a store associated with them */ 652 ok(cert->hCertStore != NULL, "expected created cert to have a store\n"); 653 /* The cert doesn't have the archived property set (which would imply it 654 * doesn't show up in enumerations.) 655 */ 656 size = 0; 657 ret = CertGetCertificateContextProperty(cert, CERT_ARCHIVED_PROP_ID, 658 NULL, &size); 659 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 660 "expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 661 /* Strangely, enumerating the certs in the store finds none. */ 662 enumCert = NULL; 663 count = 0; 664 while ((enumCert = CertEnumCertificatesInStore(cert->hCertStore, enumCert))) 665 count++; 666 ok(!count, "expected 0, got %d\n", count); 667 CertFreeCertificateContext(cert); 668 } 669 670 static void testDupCert(void) 671 { 672 PCCERT_CONTEXT context, dupContext, storeContext, storeContext2, context2; 673 HCERTSTORE store, store2; 674 BOOL ret; 675 676 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 677 CERT_STORE_CREATE_NEW_FLAG, NULL); 678 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError()); 679 if (!store) 680 return; 681 682 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 683 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context); 684 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */), 685 "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 686 if (!ret && GetLastError() == OSS_DATA_ERROR) 687 { 688 skip("bigCert can't be decoded, skipping tests\n"); 689 return; 690 } 691 ok(context != NULL, "Expected a valid cert context\n"); 692 if (context) 693 { 694 ok(context->cbCertEncoded == sizeof(bigCert), 695 "Wrong cert size %d\n", context->cbCertEncoded); 696 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)), 697 "Unexpected encoded cert in context\n"); 698 ok(context->hCertStore == store, "Unexpected store\n"); 699 700 dupContext = CertDuplicateCertificateContext(context); 701 ok(dupContext != NULL, "Expected valid duplicate\n"); 702 /* Not only is it a duplicate, it's identical: the address is the 703 * same. 704 */ 705 ok(dupContext == context, "Expected identical context addresses\n"); 706 CertFreeCertificateContext(dupContext); 707 CertFreeCertificateContext(context); 708 } 709 CertCloseStore(store, 0); 710 711 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); 712 ok(context != NULL, "CertCreateCertificateContext failed\n"); 713 714 dupContext = CertDuplicateCertificateContext(context); 715 ok(dupContext == context, "context != dupContext\n"); 716 717 ret = CertFreeCertificateContext(dupContext); 718 ok(ret, "CertFreeCertificateContext failed\n"); 719 720 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); 721 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError()); 722 723 ret = CertAddCertificateContextToStore(store, context, CERT_STORE_ADD_NEW, &storeContext); 724 ok(ret, "CertAddCertificateContextToStore failed\n"); 725 ok(storeContext != NULL && storeContext != context, "unexpected storeContext\n"); 726 ok(storeContext->hCertStore == store, "unexpected hCertStore\n"); 727 728 ok(storeContext->pbCertEncoded != context->pbCertEncoded, "unexpected pbCertEncoded\n"); 729 ok(storeContext->cbCertEncoded == context->cbCertEncoded, "unexpected cbCertEncoded\n"); 730 ok(storeContext->pCertInfo != context->pCertInfo, "unexpected pCertInfo\n"); 731 732 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); 733 ok(store2 != NULL, "CertOpenStore failed: %d\n", GetLastError()); 734 735 ret = CertAddCertificateContextToStore(store2, storeContext, CERT_STORE_ADD_NEW, &storeContext2); 736 ok(ret, "CertAddCertificateContextToStore failed\n"); 737 ok(storeContext2 != NULL && storeContext2 != storeContext, "unexpected storeContext\n"); 738 ok(storeContext2->hCertStore == store2, "unexpected hCertStore\n"); 739 740 ok(storeContext2->pbCertEncoded != storeContext->pbCertEncoded, "unexpected pbCertEncoded\n"); 741 ok(storeContext2->cbCertEncoded == storeContext->cbCertEncoded, "unexpected cbCertEncoded\n"); 742 ok(storeContext2->pCertInfo != storeContext->pCertInfo, "unexpected pCertInfo\n"); 743 744 CertFreeCertificateContext(storeContext2); 745 CertFreeCertificateContext(storeContext); 746 747 context2 = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage, sizeof(certWithUsage)); 748 ok(context2 != NULL, "CertCreateCertificateContext failed\n"); 749 750 ok(context2->hCertStore == context->hCertStore, "Unexpected hCertStore\n"); 751 752 CertFreeCertificateContext(context2); 753 ret = CertFreeCertificateContext(context); 754 ok(ret, "CertFreeCertificateContext failed\n"); 755 756 CertCloseStore(store, 0); 757 CertCloseStore(store2, 0); 758 759 SetLastError(0xdeadbeef); 760 context = CertDuplicateCertificateContext(NULL); 761 ok(context == NULL, "Expected context to be NULL\n"); 762 763 ret = CertFreeCertificateContext(NULL); 764 ok(ret, "CertFreeCertificateContext failed\n"); 765 } 766 767 static void testLinkCert(void) 768 { 769 const CERT_CONTEXT *context, *link; 770 HCERTSTORE store; 771 BOOL ret; 772 773 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); 774 ok(context != NULL, "CertCreateCertificateContext failed\n"); 775 776 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); 777 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError()); 778 779 ret = CertAddCertificateLinkToStore(store, context, CERT_STORE_ADD_NEW, &link); 780 ok(ret, "CertAddCertificateContextToStore failed\n"); 781 ok(link != NULL && link != context, "unexpected storeContext\n"); 782 ok(link->hCertStore == store, "unexpected hCertStore\n"); 783 784 ok(link->pbCertEncoded == context->pbCertEncoded, "unexpected pbCertEncoded\n"); 785 ok(link->cbCertEncoded == context->cbCertEncoded, "unexpected cbCertEncoded\n"); 786 ok(link->pCertInfo == context->pCertInfo, "unexpected pCertInfo\n"); 787 788 CertFreeCertificateContext(link); 789 CertFreeCertificateContext(context); 790 CertCloseStore(store, 0); 791 } 792 793 static BYTE subjectName3[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 794 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x52, 0x6f, 0x62, 0x20, 0x20, 0x4c, 0x61, 795 0x6e, 0x67, 0x00 }; 796 static const BYTE iTunesCert0[] = { 797 0x30,0x82,0x03,0xc4,0x30,0x82,0x03,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, 798 0x47,0xbf,0x19,0x95,0xdf,0x8d,0x52,0x46,0x43,0xf7,0xdb,0x6d,0x48,0x0d,0x31, 799 0xa4,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, 800 0x00,0x30,0x81,0x8b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, 801 0x5a,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0c,0x57,0x65, 802 0x73,0x74,0x65,0x72,0x6e,0x20,0x43,0x61,0x70,0x65,0x31,0x14,0x30,0x12,0x06, 803 0x03,0x55,0x04,0x07,0x13,0x0b,0x44,0x75,0x72,0x62,0x61,0x6e,0x76,0x69,0x6c, 804 0x6c,0x65,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x54,0x68, 805 0x61,0x77,0x74,0x65,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14, 806 0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, 807 0x61,0x74,0x69,0x6f,0x6e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13, 808 0x16,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x54,0x69,0x6d,0x65,0x73,0x74,0x61, 809 0x6d,0x70,0x69,0x6e,0x67,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x33,0x31, 810 0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x33,0x31, 811 0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x53,0x31,0x0b,0x30, 812 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06, 813 0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c, 814 0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13, 815 0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,0x6d,0x65,0x20, 816 0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,0x76,0x69,0x63, 817 0x65,0x73,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86, 818 0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30, 819 0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0xca,0xb2,0xa4,0xcc,0xcd,0x20, 820 0xaf,0x0a,0x7d,0x89,0xac,0x87,0x75,0xf0,0xb4,0x4e,0xf1,0xdf,0xc1,0x0f,0xbf, 821 0x67,0x61,0xbd,0xa3,0x64,0x1c,0xda,0xbb,0xf9,0xca,0x33,0xab,0x84,0x30,0x89, 822 0x58,0x7e,0x8c,0xdb,0x6b,0xdd,0x36,0x9e,0x0f,0xbf,0xd1,0xec,0x78,0xf2,0x77, 823 0xa6,0x7e,0x6f,0x3c,0xbf,0x93,0xaf,0x0d,0xba,0x68,0xf4,0x6c,0x94,0xca,0xbd, 824 0x52,0x2d,0xab,0x48,0x3d,0xf5,0xb6,0xd5,0x5d,0x5f,0x1b,0x02,0x9f,0xfa,0x2f, 825 0x6b,0x1e,0xa4,0xf7,0xa3,0x9a,0xa6,0x1a,0xc8,0x02,0xe1,0x7f,0x4c,0x52,0xe3, 826 0x0e,0x60,0xec,0x40,0x1c,0x7e,0xb9,0x0d,0xde,0x3f,0xc7,0xb4,0xdf,0x87,0xbd, 827 0x5f,0x7a,0x6a,0x31,0x2e,0x03,0x99,0x81,0x13,0xa8,0x47,0x20,0xce,0x31,0x73, 828 0x0d,0x57,0x2d,0xcd,0x78,0x34,0x33,0x95,0x12,0x99,0x12,0xb9,0xde,0x68,0x2f, 829 0xaa,0xe6,0xe3,0xc2,0x8a,0x8c,0x2a,0xc3,0x8b,0x21,0x87,0x66,0xbd,0x83,0x58, 830 0x57,0x6f,0x75,0xbf,0x3c,0xaa,0x26,0x87,0x5d,0xca,0x10,0x15,0x3c,0x9f,0x84, 831 0xea,0x54,0xc1,0x0a,0x6e,0xc4,0xfe,0xc5,0x4a,0xdd,0xb9,0x07,0x11,0x97,0x22, 832 0x7c,0xdb,0x3e,0x27,0xd1,0x1e,0x78,0xec,0x9f,0x31,0xc9,0xf1,0xe6,0x22,0x19, 833 0xdb,0xc4,0xb3,0x47,0x43,0x9a,0x1a,0x5f,0xa0,0x1e,0x90,0xe4,0x5e,0xf5,0xee, 834 0x7c,0xf1,0x7d,0xab,0x62,0x01,0x8f,0xf5,0x4d,0x0b,0xde,0xd0,0x22,0x56,0xa8, 835 0x95,0xcd,0xae,0x88,0x76,0xae,0xee,0xba,0x0d,0xf3,0xe4,0x4d,0xd9,0xa0,0xfb, 836 0x68,0xa0,0xae,0x14,0x3b,0xb3,0x87,0xc1,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3, 837 0x81,0xdb,0x30,0x81,0xd8,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07, 838 0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05, 839 0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73, 840 0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30, 841 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01, 842 0xff,0x02,0x01,0x00,0x30,0x41,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3a,0x30,0x38, 843 0x30,0x36,0xa0,0x34,0xa0,0x32,0x86,0x30,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, 844 0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f, 845 0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x54,0x69,0x6d,0x65,0x73,0x74,0x61, 846 0x6d,0x70,0x69,0x6e,0x67,0x43,0x41,0x2e,0x63,0x72,0x6c,0x30,0x13,0x06,0x03, 847 0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07, 848 0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03, 849 0x02,0x01,0x06,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,0x04,0x1d,0x30,0x1b,0xa4, 850 0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0c,0x54, 851 0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,0x33,0x30,0x0d,0x06,0x09, 852 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00, 853 0x4a,0x6b,0xf9,0xea,0x58,0xc2,0x44,0x1c,0x31,0x89,0x79,0x99,0x2b,0x96,0xbf, 854 0x82,0xac,0x01,0xd6,0x1c,0x4c,0xcd,0xb0,0x8a,0x58,0x6e,0xdf,0x08,0x29,0xa3, 855 0x5e,0xc8,0xca,0x93,0x13,0xe7,0x04,0x52,0x0d,0xef,0x47,0x27,0x2f,0x00,0x38, 856 0xb0,0xe4,0xc9,0x93,0x4e,0x9a,0xd4,0x22,0x62,0x15,0xf7,0x3f,0x37,0x21,0x4f, 857 0x70,0x31,0x80,0xf1,0x8b,0x38,0x87,0xb3,0xe8,0xe8,0x97,0x00,0xfe,0xcf,0x55, 858 0x96,0x4e,0x24,0xd2,0xa9,0x27,0x4e,0x7a,0xae,0xb7,0x61,0x41,0xf3,0x2a,0xce, 859 0xe7,0xc9,0xd9,0x5e,0xdd,0xbb,0x2b,0x85,0x3e,0xb5,0x9d,0xb5,0xd9,0xe1,0x57, 860 0xff,0xbe,0xb4,0xc5,0x7e,0xf5,0xcf,0x0c,0x9e,0xf0,0x97,0xfe,0x2b,0xd3,0x3b, 861 0x52,0x1b,0x1b,0x38,0x27,0xf7,0x3f,0x4a }; 862 static const BYTE iTunesCert1[] = { 863 0x30,0x82,0x03,0xff,0x30,0x82,0x02,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, 864 0x0d,0xe9,0x2b,0xf0,0xd4,0xd8,0x29,0x88,0x18,0x32,0x05,0x09,0x5e,0x9a,0x76, 865 0x88,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, 866 0x00,0x30,0x53,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, 867 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72, 868 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29, 869 0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e, 870 0x20,0x54,0x69,0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20, 871 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d, 872 0x30,0x33,0x31,0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d, 873 0x30,0x38,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x57, 874 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, 875 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69, 876 0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55, 877 0x04,0x03,0x13,0x26,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69, 878 0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72, 879 0x76,0x69,0x63,0x65,0x73,0x20,0x53,0x69,0x67,0x6e,0x65,0x72,0x30,0x82,0x01, 880 0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05, 881 0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00, 882 0xb2,0x50,0x28,0x48,0xdd,0xd3,0x68,0x7a,0x84,0x18,0x44,0x66,0x75,0x5d,0x7e, 883 0xc4,0xb8,0x9f,0x63,0x26,0xff,0x3d,0x43,0x9c,0x7c,0x11,0x38,0x10,0x25,0x55, 884 0x73,0xd9,0x75,0x27,0x69,0xfd,0x4e,0xb9,0x20,0x5c,0xd3,0x0a,0xf9,0xa0,0x1b, 885 0x2a,0xed,0x55,0x56,0x21,0x61,0xd8,0x1e,0xdb,0xe4,0xbc,0x33,0x6b,0xc7,0xef, 886 0xdd,0xa3,0x37,0x65,0x8e,0x1b,0x93,0x0c,0xb6,0x53,0x1e,0x5c,0x7c,0x66,0x35, 887 0x5f,0x05,0x8a,0x45,0xfe,0x76,0x4e,0xdf,0x53,0x80,0xa2,0x81,0x20,0x9d,0xae, 888 0x88,0x5c,0xa2,0x08,0xf7,0xe5,0x30,0xf9,0xee,0x22,0x37,0x4c,0x42,0x0a,0xce, 889 0xdf,0xc6,0x1f,0xc4,0xd6,0x55,0xe9,0x81,0x3f,0xb5,0x52,0xa3,0x2c,0xaa,0x01, 890 0x7a,0xf2,0xa2,0xaa,0x8d,0x35,0xfe,0x9f,0xe6,0x5d,0x6a,0x05,0x9f,0x3d,0x6b, 891 0xe3,0xbf,0x96,0xc0,0xfe,0xcc,0x60,0xf9,0x40,0xe7,0x07,0xa0,0x44,0xeb,0x81, 892 0x51,0x6e,0xa5,0x2a,0xf2,0xb6,0x8a,0x10,0x28,0xed,0x8f,0xdc,0x06,0xa0,0x86, 893 0x50,0x9a,0x7b,0x4a,0x08,0x0d,0x30,0x1d,0xca,0x10,0x9e,0x6b,0xf7,0xe9,0x58, 894 0xae,0x04,0xa9,0x40,0x99,0xb2,0x28,0xe8,0x8f,0x16,0xac,0x3c,0xe3,0x53,0x6f, 895 0x4b,0xd3,0x35,0x9d,0xb5,0x6f,0x64,0x1d,0xb3,0x96,0x2c,0xbb,0x3d,0xe7,0x79, 896 0xeb,0x6d,0x7a,0xf9,0x16,0xe6,0x26,0xad,0xaf,0xef,0x99,0x53,0xb7,0x40,0x2c, 897 0x95,0xb8,0x79,0xaa,0xfe,0xd4,0x52,0xab,0x29,0x74,0x7e,0x42,0xec,0x39,0x1e, 898 0xa2,0x6a,0x16,0xe6,0x59,0xbb,0x24,0x68,0xd8,0x00,0x80,0x43,0x10,0x87,0x80, 899 0x6b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xca,0x30,0x81,0xc7,0x30,0x34,0x06, 900 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24, 901 0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74, 902 0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69, 903 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01, 904 0xff,0x04,0x02,0x30,0x00,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30, 905 0x2a,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, 906 0x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63, 907 0x6f,0x6d,0x2f,0x74,0x73,0x73,0x2d,0x63,0x61,0x2e,0x63,0x72,0x6c,0x30,0x16, 908 0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b, 909 0x06,0x01,0x05,0x05,0x07,0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01, 910 0x01,0xff,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x24,0x06,0x03,0x55,0x1d,0x11, 911 0x04,0x1d,0x30,0x1b,0xa4,0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55, 912 0x04,0x03,0x13,0x0c,0x54,0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35, 913 0x34,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, 914 0x00,0x03,0x82,0x01,0x01,0x00,0x87,0x78,0x70,0xda,0x4e,0x52,0x01,0x20,0x5b, 915 0xe0,0x79,0xc9,0x82,0x30,0xc4,0xfd,0xb9,0x19,0x96,0xbd,0x91,0x00,0xc3,0xbd, 916 0xcd,0xcd,0xc6,0xf4,0x0e,0xd8,0xff,0xf9,0x4d,0xc0,0x33,0x62,0x30,0x11,0xc5, 917 0xf5,0x74,0x1b,0xd4,0x92,0xde,0x5f,0x9c,0x20,0x13,0xb1,0x7c,0x45,0xbe,0x50, 918 0xcd,0x83,0xe7,0x80,0x17,0x83,0xa7,0x27,0x93,0x67,0x13,0x46,0xfb,0xca,0xb8, 919 0x98,0x41,0x03,0xcc,0x9b,0x51,0x5b,0x05,0x8b,0x7f,0xa8,0x6f,0xf3,0x1b,0x50, 920 0x1b,0x24,0x2e,0xf2,0x69,0x8d,0x6c,0x22,0xf7,0xbb,0xca,0x16,0x95,0xed,0x0c, 921 0x74,0xc0,0x68,0x77,0xd9,0xeb,0x99,0x62,0x87,0xc1,0x73,0x90,0xf8,0x89,0x74, 922 0x7a,0x23,0xab,0xa3,0x98,0x7b,0x97,0xb1,0xf7,0x8f,0x29,0x71,0x4d,0x2e,0x75, 923 0x1b,0x48,0x41,0xda,0xf0,0xb5,0x0d,0x20,0x54,0xd6,0x77,0xa0,0x97,0x82,0x63, 924 0x69,0xfd,0x09,0xcf,0x8a,0xf0,0x75,0xbb,0x09,0x9b,0xd9,0xf9,0x11,0x55,0x26, 925 0x9a,0x61,0x32,0xbe,0x7a,0x02,0xb0,0x7b,0x86,0xbe,0xa2,0xc3,0x8b,0x22,0x2c, 926 0x78,0xd1,0x35,0x76,0xbc,0x92,0x73,0x5c,0xf9,0xb9,0xe6,0x4c,0x15,0x0a,0x23, 927 0xcc,0xe4,0xd2,0xd4,0x34,0x2e,0x49,0x40,0x15,0x3c,0x0f,0x60,0x7a,0x24,0xc6, 928 0xa5,0x66,0xef,0x96,0xcf,0x70,0xeb,0x3e,0xe7,0xf4,0x0d,0x7e,0xdc,0xd1,0x7c, 929 0xa3,0x76,0x71,0x69,0xc1,0x9c,0x4f,0x47,0x30,0x35,0x21,0xb1,0xa2,0xaf,0x1a, 930 0x62,0x3c,0x2b,0xd9,0x8e,0xaa,0x2a,0x07,0x7b,0xd8,0x18,0xb3,0x5c,0x7b,0xe2, 931 0x9d,0xa5,0x6f,0xfe,0x3c,0x89,0xad }; 932 static const BYTE iTunesCert2[] = { 933 0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, 934 0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75, 935 0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, 936 0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, 937 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72, 938 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35, 939 0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20, 940 0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20, 941 0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41, 942 0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30, 943 0x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30, 944 0x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b, 945 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15, 946 0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e, 947 0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b, 948 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73, 949 0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03, 950 0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75, 951 0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77, 952 0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d, 953 0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06, 954 0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20, 955 0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69, 956 0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,0x30,0x82, 957 0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01, 958 0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01, 959 0x00,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10, 960 0x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee, 961 0x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51, 962 0x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24, 963 0xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22, 964 0x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25, 965 0x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd, 966 0xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63, 967 0xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47, 968 0x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20, 969 0xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c, 970 0x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d, 971 0xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd, 972 0x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e, 973 0x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53, 974 0x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70, 975 0x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44, 976 0x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c, 977 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01, 978 0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30, 979 0x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17, 980 0x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01, 981 0x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76, 982 0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61, 983 0x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24, 984 0xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e, 985 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63, 986 0x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16, 987 0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b, 988 0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01, 989 0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48, 990 0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06, 991 0x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30, 992 0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43, 993 0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55, 994 0x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64, 995 0x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06, 996 0x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31, 997 0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30, 998 0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67, 999 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04, 1000 0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c, 1001 0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74, 1002 0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f, 1003 0x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6, 1004 0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86, 1005 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8, 1006 0x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c, 1007 0x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68, 1008 0xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96, 1009 0xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00, 1010 0xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0, 1011 0xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3, 1012 0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88, 1013 0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f, 1014 0x5e,0xf6,0x7a,0xb5 }; 1015 static const BYTE iTunesCert3[] = { 1016 0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, 1017 0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6, 1018 0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, 1019 0x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, 1020 0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65, 1021 0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30, 1022 0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67, 1023 0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b, 1024 0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d, 1025 0x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74, 1026 0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69, 1027 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30, 1028 0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72, 1029 0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43, 1030 0x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30, 1031 0x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30, 1032 0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32, 1033 0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03, 1034 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04, 1035 0x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12, 1036 0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74, 1037 0x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41, 1038 0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20, 1039 0x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35, 1040 0x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73, 1041 0x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74, 1042 0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64, 1043 0x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55, 1044 0x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75, 1045 0x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06, 1046 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, 1047 0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84, 1048 0xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49, 1049 0xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35, 1050 0x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57, 1051 0x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07, 1052 0xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd, 1053 0xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d, 1054 0x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55, 1055 0xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c, 1056 0x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30, 1057 0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55, 1058 0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03, 1059 0x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f, 1060 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30, 1061 0x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e, 1062 0x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63, 1063 0x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39, 1064 0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a, 1065 0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68, 1066 0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69, 1067 0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06, 1068 0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05, 1069 0x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01, 1070 0x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30, 1071 0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e, 1072 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06, 1073 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70, 1074 0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69, 1075 0x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f, 1076 0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63, 1077 0x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14, 1078 0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78, 1079 0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8, 1080 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06, 1081 0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00, 1082 0x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01, 1083 0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64, 1084 0xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10, 1085 0xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35, 1086 0x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03, 1087 0x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3, 1088 0xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76, 1089 0xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40, 1090 0xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4, 1091 0xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b, 1092 0x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c, 1093 0x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d, 1094 0x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5, 1095 0x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9, 1096 0x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13, 1097 0xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64, 1098 0xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5, 1099 0xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52, 1100 0x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a }; 1101 static BYTE iTunesIssuer[] = { 1102 0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06, 1103 0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04, 1104 0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c, 1105 0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55, 1106 0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e, 1107 0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f, 1108 0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13, 1109 0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,0x73, 1110 0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f, 1111 0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67, 1112 0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63, 1113 0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03, 1114 0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43, 1115 0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20, 1116 0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34, 1117 0x20,0x43,0x41 }; 1118 static BYTE iTunesSerialNum[] = { 1119 0x8d,0xf6,0x6a,0xdf,0xd2,0x40,0xfe,0xb6,0xa6,0x61,0x9b,0x9b, 1120 0xe0,0xa0,0x1a,0x0f }; 1121 1122 static void testFindCert(void) 1123 { 1124 HCERTSTORE store; 1125 PCCERT_CONTEXT context = NULL, subject; 1126 BOOL ret; 1127 CERT_INFO certInfo = { 0 }; 1128 CRYPT_HASH_BLOB blob; 1129 BYTE otherSerialNumber[] = { 2 }; 1130 DWORD count; 1131 static const WCHAR juan[] = { 'j','u','a','n',0 }; 1132 static const WCHAR lang[] = { 'L','A','N','G',0 }; 1133 static const WCHAR malcolm[] = { 'm','a','l','c','o','l','m',0 }; 1134 1135 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 1136 CERT_STORE_CREATE_NEW_FLAG, NULL); 1137 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError()); 1138 if (!store) 1139 return; 1140 1141 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1142 bigCert, sizeof(bigCert), CERT_STORE_ADD_NEW, NULL); 1143 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */), 1144 "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 1145 if (!ret && GetLastError() == OSS_DATA_ERROR) 1146 { 1147 skip("bigCert can't be decoded, skipping tests\n"); 1148 return; 1149 } 1150 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1151 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL); 1152 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1153 GetLastError()); 1154 /* This has the same name as bigCert */ 1155 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1156 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL); 1157 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1158 GetLastError()); 1159 1160 /* Crashes 1161 context = CertFindCertificateInStore(NULL, 0, 0, 0, NULL, NULL); 1162 */ 1163 1164 /* Check first cert's there, by issuer */ 1165 certInfo.Subject.pbData = subjectName; 1166 certInfo.Subject.cbData = sizeof(subjectName); 1167 certInfo.SerialNumber.pbData = serialNum; 1168 certInfo.SerialNumber.cbData = sizeof(serialNum); 1169 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1170 CERT_FIND_ISSUER_NAME, &certInfo.Subject, NULL); 1171 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n", 1172 GetLastError()); 1173 if (context) 1174 { 1175 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1176 CERT_FIND_ISSUER_NAME, &certInfo.Subject, context); 1177 ok(context != NULL, "Expected more than one cert\n"); 1178 if (context) 1179 { 1180 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 1181 0, CERT_FIND_ISSUER_NAME, &certInfo.Subject, context); 1182 ok(context == NULL, "Expected precisely two certs\n"); 1183 } 1184 } 1185 1186 /* Check second cert's there as well, by subject name */ 1187 certInfo.Subject.pbData = subjectName2; 1188 certInfo.Subject.cbData = sizeof(subjectName2); 1189 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1190 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, NULL); 1191 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n", 1192 GetLastError()); 1193 if (context) 1194 { 1195 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1196 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, context); 1197 ok(context == NULL, "Expected one cert only\n"); 1198 } 1199 1200 /* Strange but true: searching for the subject cert requires you to set 1201 * the issuer, not the subject 1202 */ 1203 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1204 CERT_FIND_SUBJECT_CERT, &certInfo, NULL); 1205 ok(context == NULL, "Expected no certificate\n"); 1206 certInfo.Subject.pbData = NULL; 1207 certInfo.Subject.cbData = 0; 1208 certInfo.Issuer.pbData = subjectName2; 1209 certInfo.Issuer.cbData = sizeof(subjectName2); 1210 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1211 CERT_FIND_SUBJECT_CERT, &certInfo, NULL); 1212 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n", 1213 GetLastError()); 1214 if (context) 1215 { 1216 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1217 CERT_FIND_SUBJECT_CERT, &certInfo, context); 1218 ok(context == NULL, "Expected one cert only\n"); 1219 } 1220 /* A non-matching serial number will not match. */ 1221 certInfo.SerialNumber.pbData = otherSerialNumber; 1222 certInfo.SerialNumber.cbData = sizeof(otherSerialNumber); 1223 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1224 CERT_FIND_SUBJECT_CERT, &certInfo, NULL); 1225 ok(context == NULL, "Expected no match\n"); 1226 /* No serial number will not match */ 1227 certInfo.SerialNumber.cbData = 0; 1228 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1229 CERT_FIND_SUBJECT_CERT, &certInfo, NULL); 1230 ok(context == NULL, "Expected no match\n"); 1231 /* A serial number still won't match if the name doesn't */ 1232 certInfo.SerialNumber.pbData = serialNum; 1233 certInfo.SerialNumber.cbData = sizeof(serialNum); 1234 certInfo.Issuer.pbData = subjectName3; 1235 certInfo.Issuer.cbData = sizeof(subjectName3); 1236 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1237 CERT_FIND_SUBJECT_CERT, &certInfo, NULL); 1238 ok(context == NULL, "Expected no match\n"); 1239 1240 /* The nice thing about hashes, they're unique */ 1241 blob.pbData = bigCertHash; 1242 blob.cbData = sizeof(bigCertHash); 1243 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1244 CERT_FIND_SHA1_HASH, &blob, NULL); 1245 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n", 1246 GetLastError()); 1247 if (context) 1248 { 1249 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1250 CERT_FIND_SHA1_HASH, &certInfo.Subject, context); 1251 ok(context == NULL, "Expected one cert only\n"); 1252 } 1253 1254 /* Searching for NULL string matches any context. */ 1255 count = 0; 1256 context = NULL; 1257 do { 1258 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1259 CERT_FIND_ISSUER_STR, NULL, context); 1260 if (context) 1261 count++; 1262 } while (context); 1263 ok(count == 3, "expected 3 contexts\n"); 1264 count = 0; 1265 context = NULL; 1266 do { 1267 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1268 CERT_FIND_ISSUER_STR, juan, context); 1269 if (context) 1270 count++; 1271 } while (context); 1272 ok(count == 2, "expected 2 contexts\n"); 1273 count = 0; 1274 context = NULL; 1275 do { 1276 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1277 CERT_FIND_ISSUER_STR, lang, context); 1278 if (context) 1279 count++; 1280 } while (context); 1281 ok(count == 3, "expected 3 contexts\n"); 1282 SetLastError(0xdeadbeef); 1283 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1284 CERT_FIND_ISSUER_STR, malcolm, NULL); 1285 ok(!context, "expected no certs\n"); 1286 ok(GetLastError() == CRYPT_E_NOT_FOUND, 1287 "expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 1288 1289 CertCloseStore(store, 0); 1290 1291 /* Another subject cert search, using iTunes's certs */ 1292 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 1293 CERT_STORE_CREATE_NEW_FLAG, NULL); 1294 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1295 iTunesCert0, sizeof(iTunesCert0), CERT_STORE_ADD_NEW, NULL); 1296 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1297 GetLastError()); 1298 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1299 iTunesCert1, sizeof(iTunesCert1), CERT_STORE_ADD_NEW, NULL); 1300 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1301 GetLastError()); 1302 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1303 iTunesCert2, sizeof(iTunesCert2), CERT_STORE_ADD_NEW, NULL); 1304 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1305 GetLastError()); 1306 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1307 iTunesCert3, sizeof(iTunesCert3), CERT_STORE_ADD_NEW, &subject); 1308 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1309 GetLastError()); 1310 1311 /* The certInfo's issuer does not match any subject, but the serial 1312 * number does match a cert whose issuer matches certInfo's issuer. 1313 * This yields a match. 1314 */ 1315 certInfo.SerialNumber.cbData = sizeof(iTunesSerialNum); 1316 certInfo.SerialNumber.pbData = iTunesSerialNum; 1317 certInfo.Issuer.cbData = sizeof(iTunesIssuer); 1318 certInfo.Issuer.pbData = iTunesIssuer; 1319 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1320 CERT_FIND_SUBJECT_CERT, &certInfo, NULL); 1321 ok(context != NULL, "Expected a match\n"); 1322 if (context) 1323 { 1324 ret = CertCompareCertificateName(context->dwCertEncodingType, 1325 &certInfo.Issuer, &context->pCertInfo->Subject); 1326 ok(!ret, "Expected subject name not to match\n"); 1327 ret = CertCompareCertificateName(context->dwCertEncodingType, 1328 &certInfo.Issuer, &context->pCertInfo->Issuer); 1329 ok(ret, "Expected issuer name to match\n"); 1330 ret = CertCompareIntegerBlob(&certInfo.SerialNumber, 1331 &context->pCertInfo->SerialNumber); 1332 ok(ret, "Expected serial number to match\n"); 1333 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1334 CERT_FIND_SUBJECT_CERT, &certInfo, context); 1335 ok(context == NULL, "Expected one cert only\n"); 1336 } 1337 1338 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, 1339 CERT_FIND_ISSUER_OF, subject, NULL); 1340 ok(context != NULL, "Expected an issuer\n"); 1341 if (context) 1342 { 1343 PCCERT_CONTEXT none = CertFindCertificateInStore(store, 1344 X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL); 1345 1346 ok(!none, "Expected no parent of issuer\n"); 1347 CertFreeCertificateContext(context); 1348 } 1349 CertFreeCertificateContext(subject); 1350 CertCloseStore(store, 0); 1351 } 1352 1353 static void testGetSubjectCert(void) 1354 { 1355 HCERTSTORE store; 1356 PCCERT_CONTEXT context1, context2; 1357 CERT_INFO info = { 0 }; 1358 BOOL ret; 1359 1360 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 1361 CERT_STORE_CREATE_NEW_FLAG, NULL); 1362 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError()); 1363 if (!store) 1364 return; 1365 1366 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1367 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); 1368 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */), 1369 "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 1370 if (!ret && GetLastError() == OSS_DATA_ERROR) 1371 { 1372 skip("bigCert can't be decoded, skipping tests\n"); 1373 return; 1374 } 1375 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1376 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, &context1); 1377 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1378 GetLastError()); 1379 ok(context1 != NULL, "Expected a context\n"); 1380 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1381 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL); 1382 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1383 GetLastError()); 1384 1385 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING, 1386 NULL); 1387 ok(!context2 && GetLastError() == E_INVALIDARG, 1388 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1389 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING, 1390 &info); 1391 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND, 1392 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 1393 info.SerialNumber.cbData = sizeof(serialNum); 1394 info.SerialNumber.pbData = serialNum; 1395 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING, 1396 &info); 1397 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND, 1398 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 1399 info.Issuer.cbData = sizeof(subjectName2); 1400 info.Issuer.pbData = subjectName2; 1401 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING, 1402 &info); 1403 ok(context2 != NULL, 1404 "CertGetSubjectCertificateFromStore failed: %08x\n", GetLastError()); 1405 /* Not only should this find a context, but it should be the same 1406 * (same address) as context1. 1407 */ 1408 ok(context1 == context2, "Expected identical context addresses\n"); 1409 CertFreeCertificateContext(context2); 1410 1411 CertFreeCertificateContext(context1); 1412 CertCloseStore(store, 0); 1413 } 1414 1415 /* This expires in 1970 or so */ 1416 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2, 1417 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6, 1418 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06, 1419 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30, 1420 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40, 1421 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 1422 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30, 1423 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 1424 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30, 1425 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40, 1426 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 1427 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 1428 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 1429 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29, 1430 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e, 1431 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5, 1432 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a, 1433 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b, 1434 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 1435 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0, 1436 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3, 1437 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31, 1438 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70, 1439 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef, 1440 0x49, 0xe5, 0xf9, 0x65, 0xf3 }; 1441 1442 /* This expires in 2036 or so */ 1443 static const BYTE childOfExpired[] = { 0x30, 0x81, 0xcc, 0x30, 0x78, 0xa0, 1444 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 1445 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 1446 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 1447 0x40, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 1448 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x35, 0x30, 0x35, 1449 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x35, 1450 0x30, 0x35, 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x30, 0x15, 0x31, 0x13, 1451 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 1452 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 1453 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 1454 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x20, 0x3b, 0xdb, 0x4d, 0x67, 0x50, 1455 0xec, 0x73, 0x9d, 0xf9, 0x85, 0x5d, 0x18, 0xe9, 0xb4, 0x98, 0xe3, 0x31, 0xb7, 1456 0x03, 0x0b, 0xc0, 0x39, 0x93, 0x56, 0x81, 0x0a, 0xfc, 0x78, 0xa8, 0x29, 0x42, 1457 0x5f, 0x69, 0xfb, 0xbc, 0x5b, 0xf2, 0xa6, 0x2a, 0xbe, 0x91, 0x2c, 0xfc, 0x89, 1458 0x69, 0x15, 0x18, 0x58, 0xe5, 0x02, 0x75, 0xf7, 0x2a, 0xb6, 0xa9, 0xfb, 0x47, 1459 0x6a, 0x6e, 0x0a, 0x9b, 0xe9, 0xdc }; 1460 /* chain10_0 -+ 1461 * +-> chain7_1 1462 * chain10_1 -+ 1463 * A chain with two issuers, only one of whose dates is valid. 1464 */ 1465 static const BYTE chain10_0[] = { 1466 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, 1467 0x4a,0x30,0x3a,0x42,0xa2,0x5a,0xb3,0x93,0x4d,0x94,0x06,0xad,0x6d,0x1c,0x34, 1468 0xe6,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, 1469 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, 1470 0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 1471 0x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, 1472 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, 1473 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, 1474 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, 1475 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, 1476 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, 1477 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, 1478 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, 1479 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, 1480 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, 1481 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, 1482 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, 1483 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, 1484 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81, 1485 0x81,0x00,0x85,0x6e,0x35,0x2f,0x2c,0x51,0x4f,0xd6,0x2a,0xe4,0x9e,0xd0,0x4b, 1486 0xe6,0x90,0xfd,0xf7,0x20,0xad,0x76,0x3f,0x93,0xea,0x7f,0x0d,0x1f,0xb3,0x8e, 1487 0xfd,0xe0,0xe1,0xd6,0xd7,0x9c,0x7d,0x46,0x6b,0x15,0x5c,0xe6,0xc9,0x62,0x3b, 1488 0x70,0x4a,0x4b,0xb2,0x82,0xe3,0x55,0x0c,0xc4,0x90,0x44,0x06,0x6c,0x86,0x1c, 1489 0x6d,0x47,0x12,0xda,0x33,0x95,0x5d,0x98,0x43,0xcb,0x7c,0xfa,0x2b,0xee,0xc4, 1490 0x2d,0xc8,0x95,0x33,0x89,0x08,0x3f,0x9f,0x87,0xea,0x20,0x04,0xaf,0x58,0x4b, 1491 0x9d,0xc0,0x7c,0x0a,0x1b,0x05,0x31,0x3b,0xbb,0x13,0x58,0x2e,0x3f,0x61,0x6b, 1492 0x10,0xb4,0xeb,0xb9,0x1a,0x30,0xfd,0xea,0xca,0x29,0x99,0x5f,0x42,0x2b,0x00, 1493 0xb0,0x08,0xc3,0xf0,0xb6,0xd6,0x6b,0xf9,0x35,0x95 }; 1494 static const BYTE chain10_1[] = { 1495 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, 1496 0xbf,0x99,0x4f,0x14,0x03,0x77,0x44,0xb8,0x49,0x02,0x70,0xa1,0xb8,0x9c,0xa7, 1497 0x24,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, 1498 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, 1499 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 1500 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, 1501 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, 1502 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, 1503 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, 1504 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, 1505 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, 1506 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, 1507 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, 1508 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, 1509 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, 1510 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, 1511 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, 1512 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, 1513 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81, 1514 0x81,0x00,0xa8,0xec,0x8c,0x34,0xe7,0x2c,0xdf,0x75,0x87,0xc4,0xf7,0xda,0x71, 1515 0x72,0x29,0xb2,0x48,0xa8,0x2a,0xec,0x7b,0x7d,0x19,0xb9,0x5f,0x1d,0xd9,0x91, 1516 0x2b,0xc4,0x28,0x7e,0xd6,0xb5,0x91,0x69,0xa5,0x8a,0x1a,0x1f,0x97,0x98,0x46, 1517 0x9d,0xdf,0x12,0xf6,0x45,0x62,0xad,0x60,0xb6,0xba,0xb0,0xfd,0xf5,0x9f,0xc6, 1518 0x98,0x05,0x4f,0x4d,0x48,0xdc,0xee,0x69,0xbe,0xb8,0xc4,0xc4,0xd7,0x1b,0xb1, 1519 0x1f,0x64,0xd6,0x45,0xa7,0xdb,0xb3,0x87,0x63,0x0f,0x54,0xe1,0x3a,0x6b,0x57, 1520 0x36,0xd7,0x68,0x65,0xcf,0xda,0x57,0x8d,0xcd,0x84,0x75,0x47,0x26,0x2c,0xef, 1521 0x1e,0x8f,0xc7,0x3b,0xee,0x5d,0x03,0xa6,0xdf,0x3a,0x20,0xb2,0xcc,0xc9,0x09, 1522 0x2c,0xfe,0x2b,0x79,0xb0,0xca,0x2c,0x9a,0x81,0x6b }; 1523 static const BYTE chain7_1[] = { 1524 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, 1525 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00, 1526 0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65, 1527 0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30, 1528 0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33, 1529 0x35,0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04, 1530 0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09, 1531 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00, 1532 0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33, 1533 0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc, 1534 0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48, 1535 0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47, 1536 0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05, 1537 0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a, 1538 0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85, 1539 0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3, 1540 0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3, 1541 0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d, 1542 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9f,0x69,0xfd,0x26,0xd5,0x4b, 1543 0xe0,0xab,0x12,0x21,0xb9,0xfc,0xf7,0xe0,0x0c,0x09,0x94,0xad,0x27,0xd7,0x9d, 1544 0xa3,0xcc,0x46,0x2a,0x25,0x9a,0x24,0xa7,0x31,0x58,0x78,0xf5,0xfc,0x30,0xe1, 1545 0x6d,0xfd,0x59,0xab,0xbe,0x69,0xa0,0xea,0xe3,0x7d,0x7a,0x7b,0xe5,0x85,0xeb, 1546 0x86,0x6a,0x84,0x3c,0x96,0x01,0x1a,0x70,0xa7,0xb8,0xcb,0xf2,0x11,0xe7,0x52, 1547 0x9c,0x58,0x2d,0xac,0x63,0xce,0x72,0x4b,0xad,0x62,0xa8,0x1d,0x75,0x96,0xe2, 1548 0x27,0xf5,0x6f,0xba,0x91,0xf8,0xf1,0xb0,0xbf,0x90,0x24,0x6d,0xba,0x5d,0xd7, 1549 0x39,0x63,0x3b,0x7c,0x04,0x5d,0x89,0x9d,0x1c,0xf2,0xf7,0xcc,0xdf,0x6e,0x8a, 1550 0x43,0xa9,0xdd,0x86,0x05,0xa2,0xf3,0x22,0x2d,0x1e,0x70,0xa1,0x59,0xd7,0xa5, 1551 0x94,0x7d }; 1552 1553 static void testGetIssuerCert(void) 1554 { 1555 BOOL ret; 1556 PCCERT_CONTEXT parent, child, cert1, cert2, cert3; 1557 DWORD flags = 0xffffffff, size; 1558 CERT_NAME_BLOB certsubject; 1559 BYTE *certencoded; 1560 WCHAR rootW[] = {'R', 'O', 'O', 'T', '\0'}, 1561 certname[] = {'C', 'N', '=', 'd', 'u', 'm', 'm', 'y', ',', ' ', 'T', '=', 'T', 'e', 's', 't', '\0'}; 1562 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 1563 CERT_STORE_CREATE_NEW_FLAG, NULL); 1564 1565 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1566 1567 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1568 expiredCert, sizeof(expiredCert), CERT_STORE_ADD_ALWAYS, NULL); 1569 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1570 GetLastError()); 1571 1572 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1573 childOfExpired, sizeof(childOfExpired), CERT_STORE_ADD_ALWAYS, &child); 1574 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", 1575 GetLastError()); 1576 1577 /* These crash: 1578 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, NULL); 1579 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, NULL); 1580 */ 1581 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, &flags); 1582 ok(!parent && GetLastError() == E_INVALIDARG, 1583 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1584 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, &flags); 1585 ok(!parent && GetLastError() == E_INVALIDARG, 1586 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1587 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); 1588 ok(!parent && GetLastError() == E_INVALIDARG, 1589 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1590 /* Confusing: the caller cannot set either of the 1591 * CERT_STORE_NO_*_FLAGs, as these are not checks, 1592 * they're results: 1593 */ 1594 flags = CERT_STORE_NO_CRL_FLAG | CERT_STORE_NO_ISSUER_FLAG; 1595 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); 1596 ok(!parent && GetLastError() == E_INVALIDARG, 1597 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1598 /* Perform no checks */ 1599 flags = 0; 1600 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); 1601 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n", 1602 GetLastError()); 1603 if (parent) 1604 CertFreeCertificateContext(parent); 1605 /* Check revocation and signature only */ 1606 flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG; 1607 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); 1608 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n", 1609 GetLastError()); 1610 /* Confusing: CERT_STORE_REVOCATION_FLAG succeeds when there is no CRL by 1611 * setting CERT_STORE_NO_CRL_FLAG. 1612 */ 1613 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG), 1614 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n", 1615 flags); 1616 if (parent) 1617 CertFreeCertificateContext(parent); 1618 /* Checking time validity is not productive, because while most Windows 1619 * versions return 0 (time valid) because the child is not expired, 1620 * Windows 2003 SP1 returns that it is expired. Thus the range of 1621 * possibilities is covered, and a test verifies nothing. 1622 */ 1623 1624 CertFreeCertificateContext(child); 1625 CertCloseStore(store, 0); 1626 1627 flags = 0; 1628 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 1629 CERT_STORE_CREATE_NEW_FLAG, NULL); 1630 /* With only the child certificate, no issuer will be found */ 1631 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1632 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child); 1633 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 1634 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); 1635 ok(parent == NULL, "Expected no issuer\n"); 1636 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError()); 1637 /* Adding an issuer allows one (and only one) issuer to be found */ 1638 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1639 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert1); 1640 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 1641 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); 1642 ok(parent == cert1, "Expected cert1 to be the issuer\n"); 1643 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags); 1644 ok(parent == NULL, "Expected only one issuer\n"); 1645 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError()); 1646 /* Adding a second issuer allows two issuers to be found - and the second 1647 * issuer is found before the first, implying certs are added to the head 1648 * of a list. 1649 */ 1650 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1651 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert2); 1652 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 1653 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); 1654 ok(parent == cert2, "Expected cert2 to be the first issuer\n"); 1655 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags); 1656 ok(parent == cert1, "Expected cert1 to be the second issuer\n"); 1657 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags); 1658 ok(parent == NULL, "Expected no more than two issuers\n"); 1659 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError()); 1660 CertFreeCertificateContext(child); 1661 CertFreeCertificateContext(cert1); 1662 CertFreeCertificateContext(cert2); 1663 CertCloseStore(store, 0); 1664 1665 /* Repeat the test, reversing the order in which issuers are added, 1666 * to show it's order-dependent. 1667 */ 1668 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 1669 CERT_STORE_CREATE_NEW_FLAG, NULL); 1670 /* With only the child certificate, no issuer will be found */ 1671 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1672 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child); 1673 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 1674 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); 1675 ok(parent == NULL, "Expected no issuer\n"); 1676 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError()); 1677 /* Adding an issuer allows one (and only one) issuer to be found */ 1678 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1679 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert1); 1680 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 1681 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); 1682 ok(parent == cert1, "Expected cert1 to be the issuer\n"); 1683 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags); 1684 ok(parent == NULL, "Expected only one issuer\n"); 1685 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError()); 1686 /* Adding a second issuer allows two issuers to be found - and the second 1687 * issuer is found before the first, implying certs are added to the head 1688 * of a list. 1689 */ 1690 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 1691 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert2); 1692 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 1693 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); 1694 ok(parent == cert2, "Expected cert2 to be the first issuer\n"); 1695 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags); 1696 ok(parent == cert1, "Expected cert1 to be the second issuer\n"); 1697 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags); 1698 ok(parent == NULL, "Expected no more than two issuers\n"); 1699 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError()); 1700 1701 /* Self-sign a certificate, add to the store and test getting the issuer */ 1702 size = 0; 1703 ok(CertStrToNameW(X509_ASN_ENCODING, certname, CERT_X500_NAME_STR, NULL, NULL, &size, NULL), 1704 "CertStrToName should have worked\n"); 1705 certencoded = HeapAlloc(GetProcessHeap(), 0, size); 1706 ok(CertStrToNameW(X509_ASN_ENCODING, certname, CERT_X500_NAME_STR, NULL, certencoded, &size, NULL), 1707 "CertStrToName should have worked\n"); 1708 certsubject.pbData = certencoded; 1709 certsubject.cbData = size; 1710 cert3 = CertCreateSelfSignCertificate(0, &certsubject, 0, NULL, NULL, NULL, NULL, NULL); 1711 ok(cert3 != NULL, "CertCreateSelfSignCertificate should have worked\n"); 1712 ret = CertAddCertificateContextToStore(store, cert3, CERT_STORE_ADD_REPLACE_EXISTING, 0); 1713 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); 1714 CertFreeCertificateContext(cert3); 1715 cert3 = CertEnumCertificatesInStore(store, NULL); 1716 ok(cert3 != NULL, "CertEnumCertificatesInStore should have worked\n"); 1717 SetLastError(0xdeadbeef); 1718 flags = 0; 1719 parent = CertGetIssuerCertificateFromStore(store, cert3, NULL, &flags); 1720 ok(!parent, "Expected NULL\n"); 1721 ok(GetLastError() == CRYPT_E_SELF_SIGNED, 1722 "Expected CRYPT_E_SELF_SIGNED, got %08X\n", GetLastError()); 1723 CertFreeCertificateContext(child); 1724 CertFreeCertificateContext(cert1); 1725 CertFreeCertificateContext(cert2); 1726 CertCloseStore(store, 0); 1727 HeapFree(GetProcessHeap(), 0, certencoded); 1728 1729 /* Test root storage self-signed certificate */ 1730 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, rootW); 1731 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError()); 1732 flags = 0; 1733 cert1 = CertEnumCertificatesInStore(store, NULL); 1734 ok(cert1 != NULL, "CertEnumCertificatesInStore should have worked\n"); 1735 SetLastError(0xdeadbeef); 1736 parent = CertGetIssuerCertificateFromStore(store, cert1, NULL, &flags); 1737 ok(!parent, "Expected NULL\n"); 1738 ok(GetLastError() == CRYPT_E_SELF_SIGNED, 1739 "Expected CRYPT_E_SELF_SIGNED, got %08X\n", GetLastError()); 1740 CertCloseStore(store, 0); 1741 } 1742 1743 static void testCryptHashCert(void) 1744 { 1745 static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 1746 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 1747 0x09 }; 1748 static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee, 1749 0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8, 1750 0xa2 }; 1751 static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:"; 1752 BOOL ret; 1753 BYTE hash[20]; 1754 DWORD hashLen = sizeof(hash); 1755 1756 /* NULL buffer and nonzero length crashes 1757 ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen); 1758 empty hash length also crashes 1759 ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL); 1760 */ 1761 /* Test empty hash */ 1762 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL, 1763 &hashLen); 1764 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError()); 1765 ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen); 1766 /* Test with empty buffer */ 1767 ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen); 1768 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError()); 1769 ok(!memcmp(hash, emptyHash, sizeof(emptyHash)), 1770 "Unexpected hash of nothing\n"); 1771 /* Test a known value */ 1772 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash, 1773 &hashLen); 1774 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError()); 1775 ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n"); 1776 } 1777 1778 static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen, 1779 const BYTE *sig, unsigned int sigLen) 1780 { 1781 HCRYPTHASH hash; 1782 BOOL ret = CryptCreateHash(csp, CALG_SHA1, 0, 0, &hash); 1783 1784 ok(ret, "CryptCreateHash failed: %08x\n", GetLastError()); 1785 if (ret) 1786 { 1787 BYTE mySig[64]; 1788 DWORD mySigSize = sizeof(mySig); 1789 1790 ret = CryptHashData(hash, toSign, toSignLen, 0); 1791 ok(ret, "CryptHashData failed: %08x\n", GetLastError()); 1792 /* use the A variant so the test can run on Win9x */ 1793 ret = CryptSignHashA(hash, AT_SIGNATURE, NULL, 0, mySig, &mySigSize); 1794 ok(ret, "CryptSignHash failed: %08x\n", GetLastError()); 1795 if (ret) 1796 { 1797 ok(mySigSize == sigLen, "Expected sig length %d, got %d\n", 1798 sigLen, mySigSize); 1799 ok(!memcmp(mySig, sig, sigLen), "Unexpected signature\n"); 1800 } 1801 CryptDestroyHash(hash); 1802 } 1803 } 1804 1805 /* Tests signing the certificate described by toBeSigned with the CSP passed in, 1806 * using the algorithm with OID sigOID. The CSP is assumed to be empty, and a 1807 * keyset named AT_SIGNATURE will be added to it. The signature will be stored 1808 * in sig. sigLen should be at least 64 bytes. 1809 */ 1810 static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned, 1811 LPCSTR sigOID, BYTE *sig, DWORD *sigLen) 1812 { 1813 BOOL ret; 1814 DWORD size = 0; 1815 CRYPT_ALGORITHM_IDENTIFIER algoID = { NULL, { 0, NULL } }; 1816 HCRYPTKEY key; 1817 1818 /* These all crash 1819 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL); 1820 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, &size); 1821 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData, 1822 NULL, NULL, NULL, &size); 1823 */ 1824 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData, 1825 &algoID, NULL, NULL, &size); 1826 ok(!ret && GetLastError() == NTE_BAD_ALGID, 1827 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError()); 1828 algoID.pszObjId = (LPSTR)sigOID; 1829 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData, 1830 &algoID, NULL, NULL, &size); 1831 ok(!ret && 1832 (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_ALGID), 1833 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n", 1834 GetLastError()); 1835 ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData, 1836 toBeSigned->cbData, &algoID, NULL, NULL, &size); 1837 ok(!ret && 1838 (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_ALGID), 1839 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n", 1840 GetLastError()); 1841 1842 /* No keys exist in the new CSP yet.. */ 1843 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData, 1844 toBeSigned->cbData, &algoID, NULL, NULL, &size); 1845 ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() == 1846 NTE_NO_KEY), "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %08x\n", 1847 GetLastError()); 1848 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key); 1849 ok(ret, "CryptGenKey failed: %08x\n", GetLastError()); 1850 if (ret) 1851 { 1852 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData, 1853 toBeSigned->cbData, &algoID, NULL, NULL, &size); 1854 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError()); 1855 ok(size <= *sigLen, "Expected size <= %d, got %d\n", *sigLen, size); 1856 if (ret) 1857 { 1858 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData, 1859 toBeSigned->cbData, &algoID, NULL, sig, &size); 1860 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError()); 1861 if (ret) 1862 { 1863 *sigLen = size; 1864 verifySig(csp, toBeSigned->pbData, toBeSigned->cbData, sig, 1865 size); 1866 } 1867 } 1868 CryptDestroyKey(key); 1869 } 1870 } 1871 1872 static void testVerifyCertSig(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned, 1873 LPCSTR sigOID, const BYTE *sig, DWORD sigLen) 1874 { 1875 CERT_SIGNED_CONTENT_INFO info; 1876 LPBYTE cert = NULL; 1877 DWORD size = 0; 1878 BOOL ret; 1879 1880 if (!pCryptEncodeObjectEx) 1881 { 1882 win_skip("no CryptEncodeObjectEx support\n"); 1883 return; 1884 } 1885 ret = CryptVerifyCertificateSignature(0, 0, NULL, 0, NULL); 1886 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 1887 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 1888 ret = CryptVerifyCertificateSignature(csp, 0, NULL, 0, NULL); 1889 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 1890 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 1891 ret = CryptVerifyCertificateSignature(csp, X509_ASN_ENCODING, NULL, 0, 1892 NULL); 1893 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 1894 GetLastError() == OSS_BAD_ARG), 1895 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError()); 1896 info.ToBeSigned.cbData = toBeSigned->cbData; 1897 info.ToBeSigned.pbData = toBeSigned->pbData; 1898 info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID; 1899 info.SignatureAlgorithm.Parameters.cbData = 0; 1900 info.Signature.cbData = sigLen; 1901 info.Signature.pbData = (BYTE *)sig; 1902 info.Signature.cUnusedBits = 0; 1903 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info, 1904 CRYPT_ENCODE_ALLOC_FLAG, NULL, &cert, &size); 1905 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1906 if (cert) 1907 { 1908 PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL; 1909 DWORD pubKeySize; 1910 1911 if (0) 1912 { 1913 /* Crashes prior to Vista */ 1914 ret = CryptVerifyCertificateSignature(csp, X509_ASN_ENCODING, 1915 cert, size, NULL); 1916 } 1917 CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, 1918 (LPSTR)sigOID, 0, NULL, NULL, &pubKeySize); 1919 pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, pubKeySize); 1920 if (pubKeyInfo) 1921 { 1922 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, 1923 X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo, 1924 &pubKeySize); 1925 ok(ret, "CryptExportKey failed: %08x\n", GetLastError()); 1926 if (ret) 1927 { 1928 ret = CryptVerifyCertificateSignature(csp, X509_ASN_ENCODING, 1929 cert, size, pubKeyInfo); 1930 ok(ret, "CryptVerifyCertificateSignature failed: %08x\n", 1931 GetLastError()); 1932 } 1933 HeapFree(GetProcessHeap(), 0, pubKeyInfo); 1934 } 1935 LocalFree(cert); 1936 } 1937 } 1938 1939 static void testVerifyCertSigEx(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned, 1940 LPCSTR sigOID, const BYTE *sig, DWORD sigLen) 1941 { 1942 CERT_SIGNED_CONTENT_INFO info; 1943 LPBYTE cert = NULL; 1944 DWORD size = 0; 1945 BOOL ret; 1946 1947 if (!pCryptVerifyCertificateSignatureEx) 1948 { 1949 win_skip("no CryptVerifyCertificateSignatureEx support\n"); 1950 return; 1951 } 1952 if (!pCryptEncodeObjectEx) 1953 { 1954 win_skip("no CryptEncodeObjectEx support\n"); 1955 return; 1956 } 1957 ret = pCryptVerifyCertificateSignatureEx(0, 0, 0, NULL, 0, NULL, 0, NULL); 1958 ok(!ret && GetLastError() == E_INVALIDARG, 1959 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1960 ret = pCryptVerifyCertificateSignatureEx(csp, 0, 0, NULL, 0, NULL, 0, NULL); 1961 ok(!ret && GetLastError() == E_INVALIDARG, 1962 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1963 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 0, NULL, 0, 1964 NULL, 0, NULL); 1965 ok(!ret && GetLastError() == E_INVALIDARG, 1966 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1967 /* This crashes 1968 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 1969 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, NULL, 0, NULL, 0, NULL); 1970 */ 1971 info.ToBeSigned.cbData = toBeSigned->cbData; 1972 info.ToBeSigned.pbData = toBeSigned->pbData; 1973 info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID; 1974 info.SignatureAlgorithm.Parameters.cbData = 0; 1975 info.Signature.cbData = sigLen; 1976 info.Signature.pbData = (BYTE *)sig; 1977 info.Signature.cUnusedBits = 0; 1978 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info, 1979 CRYPT_ENCODE_ALLOC_FLAG, NULL, &cert, &size); 1980 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1981 if (cert) 1982 { 1983 CRYPT_DATA_BLOB certBlob = { 0, NULL }; 1984 PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL; 1985 1986 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 1987 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL); 1988 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD, 1989 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); 1990 certBlob.cbData = 1; 1991 certBlob.pbData = (void *)0xdeadbeef; 1992 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 1993 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL); 1994 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION || 1995 GetLastError() == CRYPT_E_ASN1_EOD /* Win9x */ || 1996 GetLastError() == CRYPT_E_ASN1_BADTAG /* Win98 */), 1997 "Expected STATUS_ACCESS_VIOLATION, CRYPT_E_ASN1_EOD, OR CRYPT_E_ASN1_BADTAG, got %08x\n", 1998 GetLastError()); 1999 2000 certBlob.cbData = size; 2001 certBlob.pbData = cert; 2002 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 2003 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL); 2004 ok(!ret && GetLastError() == E_INVALIDARG, 2005 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2006 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 2007 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 2008 CRYPT_VERIFY_CERT_SIGN_ISSUER_NULL, NULL, 0, NULL); 2009 ok(!ret && GetLastError() == E_INVALIDARG, 2010 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2011 /* This crashes 2012 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 2013 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 2014 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, NULL, 0, NULL); 2015 */ 2016 CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, 2017 (LPSTR)sigOID, 0, NULL, NULL, &size); 2018 pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, size); 2019 if (pubKeyInfo) 2020 { 2021 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, 2022 X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo, &size); 2023 ok(ret, "CryptExportKey failed: %08x\n", GetLastError()); 2024 if (ret) 2025 { 2026 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 2027 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 2028 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pubKeyInfo, 0, NULL); 2029 ok(ret, "CryptVerifyCertificateSignatureEx failed: %08x\n", 2030 GetLastError()); 2031 } 2032 HeapFree(GetProcessHeap(), 0, pubKeyInfo); 2033 } 2034 LocalFree(cert); 2035 } 2036 } 2037 2038 static BYTE emptyCert[] = { 0x30, 0x00 }; 2039 2040 static void testCertSigs(void) 2041 { 2042 HCRYPTPROV csp; 2043 CRYPT_DATA_BLOB toBeSigned = { sizeof(emptyCert), emptyCert }; 2044 BOOL ret; 2045 BYTE sig[64]; 2046 DWORD sigSize = sizeof(sig); 2047 2048 /* Just in case a previous run failed, delete this thing */ 2049 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2050 CRYPT_DELETEKEYSET); 2051 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2052 CRYPT_NEWKEYSET); 2053 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError()); 2054 2055 testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, &sigSize); 2056 testVerifyCertSig(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize); 2057 testVerifyCertSigEx(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize); 2058 2059 CryptReleaseContext(csp, 0); 2060 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2061 CRYPT_DELETEKEYSET); 2062 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError()); 2063 } 2064 2065 static const BYTE md5SignedEmptyCert[] = { 2066 0x30,0x56,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36, 2067 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31, 2068 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07, 2069 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7, 2070 0x0d,0x02,0x05,0x05,0x00,0x03,0x11,0x00,0xfb,0x0f,0x66,0x82,0x66,0xd9,0xe5,0xf8, 2071 0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 }; 2072 static const BYTE md5SignedEmptyCertNoNull[] = { 2073 0x30,0x54,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36, 2074 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31, 2075 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07, 2076 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7, 2077 0x0d,0x02,0x05,0x03,0x11,0x00,0x04,0xd9,0xa5,0xe1,0x2b,0x55,0xa2,0xd8,0xf8,0xe5, 2078 0xd9,0x66,0x82,0x66,0x0f,0xfb }; 2079 2080 static void testSignAndEncodeCert(void) 2081 { 2082 static char oid_rsa_md5rsa[] = szOID_RSA_MD5RSA; 2083 static char oid_rsa_md5[] = szOID_RSA_MD5; 2084 BOOL ret; 2085 DWORD size; 2086 CRYPT_ALGORITHM_IDENTIFIER algID = { 0 }; 2087 CERT_INFO info = { 0 }; 2088 2089 /* Crash 2090 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL, 2091 NULL); 2092 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL, 2093 &size); 2094 */ 2095 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, &algID, NULL, NULL, 2096 &size); 2097 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2098 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2099 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, NULL, NULL, 2100 &algID, NULL, NULL, &size); 2101 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2102 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2103 ret = CryptSignAndEncodeCertificate(0, 0, 0, X509_CERT_TO_BE_SIGNED, NULL, 2104 &algID, NULL, NULL, &size); 2105 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2106 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2107 /* Crashes on some win9x boxes */ 2108 if (0) 2109 { 2110 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, 2111 X509_CERT_TO_BE_SIGNED, NULL, &algID, NULL, NULL, &size); 2112 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 2113 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 2114 } 2115 /* Crashes 2116 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, 2117 X509_CERT_TO_BE_SIGNED, &info, NULL, NULL, NULL, &size); 2118 */ 2119 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, 2120 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size); 2121 ok(!ret && 2122 (GetLastError() == NTE_BAD_ALGID || 2123 GetLastError() == OSS_BAD_PTR), /* win9x */ 2124 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError()); 2125 algID.pszObjId = oid_rsa_md5rsa; 2126 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, 2127 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size); 2128 ok(!ret && 2129 (GetLastError() == ERROR_INVALID_PARAMETER || 2130 GetLastError() == NTE_BAD_ALGID || 2131 GetLastError() == OSS_BAD_PTR), /* Win9x */ 2132 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n", 2133 GetLastError()); 2134 algID.pszObjId = oid_rsa_md5; 2135 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, 2136 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size); 2137 /* oid_rsa_md5 not present in some win2k */ 2138 if (ret) 2139 { 2140 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size); 2141 2142 if (buf) 2143 { 2144 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, 2145 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, buf, &size); 2146 ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n", 2147 GetLastError()); 2148 /* Tricky: because the NULL parameters may either be omitted or 2149 * included as an asn.1-encoded NULL (0x05,0x00), two different 2150 * values are allowed. 2151 */ 2152 ok(size == sizeof(md5SignedEmptyCert) || 2153 size == sizeof(md5SignedEmptyCertNoNull), "Unexpected size %d\n", 2154 size); 2155 if (size == sizeof(md5SignedEmptyCert)) 2156 ok(!memcmp(buf, md5SignedEmptyCert, size), 2157 "Unexpected value\n"); 2158 else if (size == sizeof(md5SignedEmptyCertNoNull)) 2159 ok(!memcmp(buf, md5SignedEmptyCertNoNull, size), 2160 "Unexpected value\n"); 2161 HeapFree(GetProcessHeap(), 0, buf); 2162 } 2163 } 2164 } 2165 2166 static void testCreateSelfSignCert(void) 2167 { 2168 PCCERT_CONTEXT context; 2169 CERT_NAME_BLOB name = { sizeof(subjectName), subjectName }; 2170 HCRYPTPROV csp; 2171 BOOL ret; 2172 HCRYPTKEY key; 2173 CRYPT_KEY_PROV_INFO info; 2174 2175 if (!pCertCreateSelfSignCertificate) 2176 { 2177 win_skip("CertCreateSelfSignCertificate() is not available\n"); 2178 return; 2179 } 2180 2181 /* This crashes: 2182 context = pCertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL, 2183 NULL); 2184 * Calling this with no first parameter creates a new key container, which 2185 * lasts beyond the test, so I don't test that. Nb: the generated key 2186 * name is a GUID. 2187 context = pCertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL, 2188 NULL); 2189 */ 2190 2191 /* Acquire a CSP */ 2192 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2193 CRYPT_DELETEKEYSET); 2194 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2195 CRYPT_NEWKEYSET); 2196 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError()); 2197 2198 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL, 2199 NULL, NULL); 2200 ok(!context && GetLastError() == NTE_NO_KEY, 2201 "Expected NTE_NO_KEY, got %08x\n", GetLastError()); 2202 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key); 2203 ok(ret, "CryptGenKey failed: %08x\n", GetLastError()); 2204 if (ret) 2205 { 2206 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL, 2207 NULL, NULL); 2208 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n", 2209 GetLastError()); 2210 if (context) 2211 { 2212 DWORD size = 0; 2213 2214 /* The context must have a key provider info property */ 2215 ret = CertGetCertificateContextProperty(context, 2216 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size); 2217 ok(ret && size, "Expected non-zero key provider info\n"); 2218 if (size) 2219 { 2220 PCRYPT_KEY_PROV_INFO pInfo = HeapAlloc(GetProcessHeap(), 0, size); 2221 2222 if (pInfo) 2223 { 2224 ret = CertGetCertificateContextProperty(context, 2225 CERT_KEY_PROV_INFO_PROP_ID, pInfo, &size); 2226 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 2227 GetLastError()); 2228 if (ret) 2229 { 2230 /* Sanity-check the key provider */ 2231 ok(!lstrcmpW(pInfo->pwszContainerName, cspNameW), 2232 "Unexpected key container\n"); 2233 ok(!lstrcmpW(pInfo->pwszProvName, MS_DEF_PROV_W), 2234 "Unexpected provider\n"); 2235 ok(pInfo->dwKeySpec == AT_SIGNATURE, 2236 "Expected AT_SIGNATURE, got %d\n", pInfo->dwKeySpec); 2237 } 2238 HeapFree(GetProcessHeap(), 0, pInfo); 2239 } 2240 } 2241 2242 CertFreeCertificateContext(context); 2243 } 2244 2245 CryptDestroyKey(key); 2246 } 2247 2248 CryptReleaseContext(csp, 0); 2249 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2250 CRYPT_DELETEKEYSET); 2251 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError()); 2252 2253 /* Do the same test with a CSP, AT_KEYEXCHANGE and key info */ 2254 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2255 CRYPT_DELETEKEYSET); 2256 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2257 CRYPT_NEWKEYSET); 2258 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError()); 2259 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key); 2260 ok(ret, "CryptGenKey failed: %08x\n", GetLastError()); 2261 2262 memset(&info,0,sizeof(info)); 2263 info.dwProvType = PROV_RSA_FULL; 2264 info.dwKeySpec = AT_KEYEXCHANGE; 2265 info.pwszProvName = (LPWSTR) MS_DEF_PROV_W; 2266 info.pwszContainerName = cspNameW; 2267 /* This should fail because the CSP doesn't have the specified key. */ 2268 SetLastError(0xdeadbeef); 2269 context = pCertCreateSelfSignCertificate(csp, &name, 0, &info, NULL, NULL, 2270 NULL, NULL); 2271 ok(context == NULL, "expected failure\n"); 2272 if (context != NULL) 2273 CertFreeCertificateContext(context); 2274 else 2275 ok(GetLastError() == NTE_NO_KEY, "expected NTE_NO_KEY, got %08x\n", 2276 GetLastError()); 2277 /* Again, with a CSP, AT_SIGNATURE and key info */ 2278 info.dwKeySpec = AT_SIGNATURE; 2279 SetLastError(0xdeadbeef); 2280 context = pCertCreateSelfSignCertificate(csp, &name, 0, &info, NULL, NULL, 2281 NULL, NULL); 2282 ok(context != NULL, 2283 "CertCreateSelfSignCertificate failed: %08x\n", GetLastError()); 2284 if (context) 2285 { 2286 DWORD size = 0; 2287 2288 /* The context must have a key provider info property */ 2289 ret = CertGetCertificateContextProperty(context, 2290 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size); 2291 ok(ret && size, "Expected non-zero key provider info\n"); 2292 if (size) 2293 { 2294 PCRYPT_KEY_PROV_INFO pInfo = HeapAlloc(GetProcessHeap(), 0, size); 2295 2296 if (pInfo) 2297 { 2298 ret = CertGetCertificateContextProperty(context, 2299 CERT_KEY_PROV_INFO_PROP_ID, pInfo, &size); 2300 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 2301 GetLastError()); 2302 if (ret) 2303 { 2304 /* Sanity-check the key provider */ 2305 ok(!lstrcmpW(pInfo->pwszContainerName, cspNameW), 2306 "Unexpected key container\n"); 2307 ok(!lstrcmpW(pInfo->pwszProvName, MS_DEF_PROV_W), 2308 "Unexpected provider\n"); 2309 ok(pInfo->dwKeySpec == AT_SIGNATURE, 2310 "Expected AT_SIGNATURE, got %d\n", pInfo->dwKeySpec); 2311 } 2312 HeapFree(GetProcessHeap(), 0, pInfo); 2313 } 2314 } 2315 2316 CertFreeCertificateContext(context); 2317 } 2318 CryptDestroyKey(key); 2319 2320 CryptReleaseContext(csp, 0); 2321 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2322 CRYPT_DELETEKEYSET); 2323 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError()); 2324 2325 /* Do the same test with no CSP, AT_KEYEXCHANGE and key info */ 2326 info.dwKeySpec = AT_KEYEXCHANGE; 2327 context = pCertCreateSelfSignCertificate(0, &name, 0, &info, NULL, NULL, 2328 NULL, NULL); 2329 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n", 2330 GetLastError()); 2331 if (context) 2332 { 2333 DWORD size = 0; 2334 2335 /* The context must have a key provider info property */ 2336 ret = CertGetCertificateContextProperty(context, 2337 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size); 2338 ok(ret && size, "Expected non-zero key provider info\n"); 2339 if (size) 2340 { 2341 PCRYPT_KEY_PROV_INFO pInfo = HeapAlloc(GetProcessHeap(), 0, size); 2342 2343 if (pInfo) 2344 { 2345 ret = CertGetCertificateContextProperty(context, 2346 CERT_KEY_PROV_INFO_PROP_ID, pInfo, &size); 2347 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 2348 GetLastError()); 2349 if (ret) 2350 { 2351 /* Sanity-check the key provider */ 2352 ok(!lstrcmpW(pInfo->pwszContainerName, cspNameW), 2353 "Unexpected key container\n"); 2354 ok(!lstrcmpW(pInfo->pwszProvName, MS_DEF_PROV_W), 2355 "Unexpected provider\n"); 2356 ok(pInfo->dwKeySpec == AT_KEYEXCHANGE, 2357 "Expected AT_KEYEXCHANGE, got %d\n", pInfo->dwKeySpec); 2358 } 2359 HeapFree(GetProcessHeap(), 0, pInfo); 2360 } 2361 } 2362 2363 CertFreeCertificateContext(context); 2364 } 2365 2366 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2367 CRYPT_DELETEKEYSET); 2368 2369 /* Acquire a CSP and generate an AT_KEYEXCHANGE key in it. */ 2370 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2371 CRYPT_DELETEKEYSET); 2372 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2373 CRYPT_NEWKEYSET); 2374 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError()); 2375 2376 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL, 2377 NULL, NULL); 2378 ok(!context && GetLastError() == NTE_NO_KEY, 2379 "Expected NTE_NO_KEY, got %08x\n", GetLastError()); 2380 ret = CryptGenKey(csp, AT_KEYEXCHANGE, 0, &key); 2381 ok(ret, "CryptGenKey failed: %08x\n", GetLastError()); 2382 CryptDestroyKey(key); 2383 2384 memset(&info,0,sizeof(info)); 2385 info.dwProvType = PROV_RSA_FULL; 2386 info.dwKeySpec = AT_SIGNATURE; 2387 info.pwszProvName = (LPWSTR) MS_DEF_PROV_W; 2388 info.pwszContainerName = cspNameW; 2389 /* This should fail because the CSP doesn't have the specified key. */ 2390 SetLastError(0xdeadbeef); 2391 context = pCertCreateSelfSignCertificate(csp, &name, 0, &info, NULL, NULL, 2392 NULL, NULL); 2393 ok(context == NULL, "expected failure\n"); 2394 if (context != NULL) 2395 CertFreeCertificateContext(context); 2396 else 2397 ok(GetLastError() == NTE_NO_KEY, "expected NTE_NO_KEY, got %08x\n", 2398 GetLastError()); 2399 /* Again, with a CSP, AT_KEYEXCHANGE and key info. This succeeds because the 2400 * CSP has an AT_KEYEXCHANGE key in it. 2401 */ 2402 info.dwKeySpec = AT_KEYEXCHANGE; 2403 SetLastError(0xdeadbeef); 2404 context = pCertCreateSelfSignCertificate(csp, &name, 0, &info, NULL, NULL, 2405 NULL, NULL); 2406 ok(context != NULL, 2407 "CertCreateSelfSignCertificate failed: %08x\n", GetLastError()); 2408 if (context) 2409 { 2410 DWORD size = 0; 2411 2412 /* The context must have a key provider info property */ 2413 ret = CertGetCertificateContextProperty(context, 2414 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size); 2415 ok(ret && size, "Expected non-zero key provider info\n"); 2416 if (size) 2417 { 2418 PCRYPT_KEY_PROV_INFO pInfo = HeapAlloc(GetProcessHeap(), 0, size); 2419 2420 if (pInfo) 2421 { 2422 ret = CertGetCertificateContextProperty(context, 2423 CERT_KEY_PROV_INFO_PROP_ID, pInfo, &size); 2424 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", 2425 GetLastError()); 2426 if (ret) 2427 { 2428 /* Sanity-check the key provider */ 2429 ok(!lstrcmpW(pInfo->pwszContainerName, cspNameW), 2430 "Unexpected key container\n"); 2431 ok(!lstrcmpW(pInfo->pwszProvName, MS_DEF_PROV_W), 2432 "Unexpected provider\n"); 2433 ok(pInfo->dwKeySpec == AT_KEYEXCHANGE, 2434 "Expected AT_KEYEXCHANGE, got %d\n", pInfo->dwKeySpec); 2435 } 2436 HeapFree(GetProcessHeap(), 0, pInfo); 2437 } 2438 } 2439 2440 CertFreeCertificateContext(context); 2441 } 2442 2443 CryptReleaseContext(csp, 0); 2444 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 2445 CRYPT_DELETEKEYSET); 2446 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError()); 2447 2448 } 2449 2450 static void testIntendedKeyUsage(void) 2451 { 2452 BOOL ret; 2453 CERT_INFO info = { 0 }; 2454 static char oid_key_usage[] = szOID_KEY_USAGE; 2455 /* A couple "key usages". Really they're just encoded bits which aren't 2456 * necessarily restricted to the defined key usage values. 2457 */ 2458 static BYTE usage1[] = { 0x03,0x03,0x00,0xff,0xff }; 2459 static BYTE usage2[] = { 0x03,0x03,0x01,0xff,0xfe }; 2460 static const BYTE expected_usage1[] = { 0xff,0xff,0x00,0x00 }; 2461 static const BYTE expected_usage2[] = { 0xff,0xfe,0x00,0x00 }; 2462 CERT_EXTENSION ext = { oid_key_usage, TRUE, { sizeof(usage1), usage1 } }; 2463 BYTE usage_bytes[4]; 2464 2465 if (0) 2466 { 2467 /* Crash */ 2468 CertGetIntendedKeyUsage(0, NULL, NULL, 0); 2469 } 2470 ret = CertGetIntendedKeyUsage(0, &info, NULL, 0); 2471 ok(!ret, "expected failure\n"); 2472 ret = CertGetIntendedKeyUsage(0, &info, usage_bytes, sizeof(usage_bytes)); 2473 ok(!ret, "expected failure\n"); 2474 ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, NULL, 0); 2475 ok(!ret, "expected failure\n"); 2476 ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, usage_bytes, 2477 sizeof(usage_bytes)); 2478 ok(!ret, "expected failure\n"); 2479 info.cExtension = 1; 2480 info.rgExtension = &ext; 2481 ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, NULL, 0); 2482 ok(!ret, "expected failure\n"); 2483 /* The unused bytes are filled with 0. */ 2484 ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, usage_bytes, 2485 sizeof(usage_bytes)); 2486 ok(ret, "CertGetIntendedKeyUsage failed: %08x\n", GetLastError()); 2487 ok(!memcmp(usage_bytes, expected_usage1, sizeof(expected_usage1)), 2488 "unexpected value\n"); 2489 /* The usage bytes are copied in big-endian order. */ 2490 ext.Value.cbData = sizeof(usage2); 2491 ext.Value.pbData = usage2; 2492 ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, usage_bytes, 2493 sizeof(usage_bytes)); 2494 ok(ret, "CertGetIntendedKeyUsage failed: %08x\n", GetLastError()); 2495 ok(!memcmp(usage_bytes, expected_usage2, sizeof(expected_usage2)), 2496 "unexpected value\n"); 2497 } 2498 2499 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING, 2500 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA }; 2501 2502 static void testKeyUsage(void) 2503 { 2504 BOOL ret; 2505 PCCERT_CONTEXT context; 2506 DWORD size; 2507 2508 /* Test base cases */ 2509 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, NULL); 2510 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 2511 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 2512 size = 1; 2513 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size); 2514 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 2515 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 2516 size = 0; 2517 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size); 2518 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 2519 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 2520 /* These crash 2521 ret = CertSetEnhancedKeyUsage(NULL, NULL); 2522 usage.cUsageIdentifier = 0; 2523 ret = CertSetEnhancedKeyUsage(NULL, &usage); 2524 */ 2525 /* Test with a cert with no enhanced key usage extension */ 2526 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, 2527 sizeof(bigCert)); 2528 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n", 2529 GetLastError()); 2530 if (context) 2531 { 2532 static const char oid[] = "1.2.3.4"; 2533 BYTE buf[sizeof(CERT_ENHKEY_USAGE) + 2 * (sizeof(LPSTR) + sizeof(oid))]; 2534 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf; 2535 2536 ret = CertGetEnhancedKeyUsage(context, 0, NULL, NULL); 2537 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 2538 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 2539 size = 1; 2540 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &size); 2541 if (ret) 2542 { 2543 /* Windows 2000, ME, or later: even though it succeeded, we expect 2544 * CRYPT_E_NOT_FOUND, which indicates there is no enhanced key 2545 * usage set for this cert (which implies it's valid for all uses.) 2546 */ 2547 ok(GetLastError() == CRYPT_E_NOT_FOUND, 2548 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 2549 ok(size == sizeof(CERT_ENHKEY_USAGE), "Wrong size %d\n", size); 2550 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size); 2551 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2552 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n", 2553 pUsage->cUsageIdentifier); 2554 } 2555 else 2556 { 2557 /* Windows NT, 95, or 98: it fails, and the last error is 2558 * CRYPT_E_NOT_FOUND. 2559 */ 2560 ok(GetLastError() == CRYPT_E_NOT_FOUND, 2561 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 2562 } 2563 /* I can add a usage identifier when no key usage has been set */ 2564 ret = CertAddEnhancedKeyUsageIdentifier(context, oid); 2565 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n", 2566 GetLastError()); 2567 size = sizeof(buf); 2568 ret = CertGetEnhancedKeyUsage(context, 2569 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size); 2570 ok(ret && GetLastError() == 0, 2571 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2572 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n", 2573 pUsage->cUsageIdentifier); 2574 if (pUsage->cUsageIdentifier) 2575 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid), 2576 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]); 2577 /* Now set an empty key usage */ 2578 pUsage->cUsageIdentifier = 0; 2579 ret = CertSetEnhancedKeyUsage(context, pUsage); 2580 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2581 /* Shouldn't find it in the cert */ 2582 size = sizeof(buf); 2583 ret = CertGetEnhancedKeyUsage(context, 2584 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size); 2585 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 2586 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 2587 /* Should find it as an extended property */ 2588 ret = CertGetEnhancedKeyUsage(context, 2589 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size); 2590 ok(ret && GetLastError() == 0, 2591 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2592 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n", 2593 pUsage->cUsageIdentifier); 2594 /* Should find it as either */ 2595 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size); 2596 ok(ret && GetLastError() == 0, 2597 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2598 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n", 2599 pUsage->cUsageIdentifier); 2600 /* Add a usage identifier */ 2601 ret = CertAddEnhancedKeyUsageIdentifier(context, oid); 2602 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n", 2603 GetLastError()); 2604 size = sizeof(buf); 2605 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size); 2606 ok(ret && GetLastError() == 0, 2607 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2608 ok(pUsage->cUsageIdentifier == 1, "Expected 1 identifier, got %d\n", 2609 pUsage->cUsageIdentifier); 2610 if (pUsage->cUsageIdentifier) 2611 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid), 2612 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]); 2613 /* Re-adding the same usage identifier succeeds, though it only adds 2614 * a duplicate usage identifier on versions prior to Vista 2615 */ 2616 ret = CertAddEnhancedKeyUsageIdentifier(context, oid); 2617 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n", 2618 GetLastError()); 2619 size = sizeof(buf); 2620 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size); 2621 ok(ret && GetLastError() == 0, 2622 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2623 ok(pUsage->cUsageIdentifier == 1 || pUsage->cUsageIdentifier == 2, 2624 "Expected 1 or 2 identifiers, got %d\n", pUsage->cUsageIdentifier); 2625 if (pUsage->cUsageIdentifier) 2626 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid), 2627 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]); 2628 if (pUsage->cUsageIdentifier >= 2) 2629 ok(!strcmp(pUsage->rgpszUsageIdentifier[1], oid), 2630 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[1]); 2631 /* Now set a NULL extended property--this deletes the property. */ 2632 ret = CertSetEnhancedKeyUsage(context, NULL); 2633 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2634 SetLastError(0xbaadcafe); 2635 size = sizeof(buf); 2636 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size); 2637 ok(ret || broken(!ret && GetLastError() == CRYPT_E_NOT_FOUND /* NT4 */), 2638 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2639 ok(GetLastError() == CRYPT_E_NOT_FOUND, 2640 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 2641 2642 CertFreeCertificateContext(context); 2643 } 2644 /* Now test with a cert with an enhanced key usage extension */ 2645 context = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage, 2646 sizeof(certWithUsage)); 2647 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n", 2648 GetLastError()); 2649 if (context) 2650 { 2651 LPBYTE buf = NULL; 2652 DWORD bufSize = 0, i; 2653 2654 /* The size may depend on what flags are used to query it, so I 2655 * realloc the buffer for each test. 2656 */ 2657 ret = CertGetEnhancedKeyUsage(context, 2658 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize); 2659 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2660 buf = HeapAlloc(GetProcessHeap(), 0, bufSize); 2661 if (buf) 2662 { 2663 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf; 2664 2665 /* Should find it in the cert */ 2666 size = bufSize; 2667 ret = CertGetEnhancedKeyUsage(context, 2668 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size); 2669 ok(ret && GetLastError() == 0, 2670 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2671 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n", 2672 pUsage->cUsageIdentifier); 2673 for (i = 0; i < pUsage->cUsageIdentifier; i++) 2674 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]), 2675 "Expected %s, got %s\n", keyUsages[i], 2676 pUsage->rgpszUsageIdentifier[i]); 2677 HeapFree(GetProcessHeap(), 0, buf); 2678 } 2679 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize); 2680 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2681 buf = HeapAlloc(GetProcessHeap(), 0, bufSize); 2682 if (buf) 2683 { 2684 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf; 2685 2686 /* Should find it as either */ 2687 size = bufSize; 2688 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size); 2689 /* In Windows, GetLastError returns CRYPT_E_NOT_FOUND not found 2690 * here, even though the return is successful and the usage id 2691 * count is positive. I don't enforce that here. 2692 */ 2693 ok(ret, 2694 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2695 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n", 2696 pUsage->cUsageIdentifier); 2697 for (i = 0; i < pUsage->cUsageIdentifier; i++) 2698 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]), 2699 "Expected %s, got %s\n", keyUsages[i], 2700 pUsage->rgpszUsageIdentifier[i]); 2701 HeapFree(GetProcessHeap(), 0, buf); 2702 } 2703 /* Shouldn't find it as an extended property */ 2704 ret = CertGetEnhancedKeyUsage(context, 2705 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &size); 2706 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, 2707 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 2708 /* Adding a usage identifier overrides the cert's usage!? */ 2709 ret = CertAddEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA); 2710 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n", 2711 GetLastError()); 2712 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize); 2713 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2714 buf = HeapAlloc(GetProcessHeap(), 0, bufSize); 2715 if (buf) 2716 { 2717 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf; 2718 2719 /* Should find it as either */ 2720 size = bufSize; 2721 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size); 2722 ok(ret, 2723 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2724 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n", 2725 pUsage->cUsageIdentifier); 2726 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], szOID_RSA_RSA), 2727 "Expected %s, got %s\n", szOID_RSA_RSA, 2728 pUsage->rgpszUsageIdentifier[0]); 2729 HeapFree(GetProcessHeap(), 0, buf); 2730 } 2731 /* But querying the cert directly returns its usage */ 2732 ret = CertGetEnhancedKeyUsage(context, 2733 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize); 2734 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2735 buf = HeapAlloc(GetProcessHeap(), 0, bufSize); 2736 if (buf) 2737 { 2738 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf; 2739 2740 size = bufSize; 2741 ret = CertGetEnhancedKeyUsage(context, 2742 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size); 2743 ok(ret, 2744 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2745 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n", 2746 pUsage->cUsageIdentifier); 2747 for (i = 0; i < pUsage->cUsageIdentifier; i++) 2748 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]), 2749 "Expected %s, got %s\n", keyUsages[i], 2750 pUsage->rgpszUsageIdentifier[i]); 2751 HeapFree(GetProcessHeap(), 0, buf); 2752 } 2753 /* And removing the only usage identifier in the extended property 2754 * results in the cert's key usage being found. 2755 */ 2756 ret = CertRemoveEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA); 2757 ok(ret, "CertRemoveEnhancedKeyUsage failed: %08x\n", GetLastError()); 2758 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize); 2759 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2760 buf = HeapAlloc(GetProcessHeap(), 0, bufSize); 2761 if (buf) 2762 { 2763 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf; 2764 2765 /* Should find it as either */ 2766 size = bufSize; 2767 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size); 2768 ok(ret, 2769 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); 2770 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n", 2771 pUsage->cUsageIdentifier); 2772 for (i = 0; i < pUsage->cUsageIdentifier; i++) 2773 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]), 2774 "Expected %s, got %s\n", keyUsages[i], 2775 pUsage->rgpszUsageIdentifier[i]); 2776 HeapFree(GetProcessHeap(), 0, buf); 2777 } 2778 2779 CertFreeCertificateContext(context); 2780 } 2781 } 2782 2783 static const BYTE cert2WithUsage[] = { 2784 0x30,0x81,0x89,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 2785 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 2786 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 2787 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 2788 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 2789 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 2790 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x25,0x30,0x23, 2791 0x30,0x21,0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x17,0x30,0x15,0x06, 2792 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x2a,0x86,0x48,0x86, 2793 0xf7,0x0d,0x01,0x01,0x01 }; 2794 2795 static void testGetValidUsages(void) 2796 { 2797 static const LPCSTR expectedOIDs[] = { 2798 "1.3.6.1.5.5.7.3.3", 2799 "1.3.6.1.5.5.7.3.2", 2800 "1.2.840.113549.1.1.1", 2801 }; 2802 static const LPCSTR expectedOIDs2[] = { 2803 "1.3.6.1.5.5.7.3.2", 2804 "1.2.840.113549.1.1.1", 2805 }; 2806 BOOL ret; 2807 int numOIDs; 2808 DWORD size; 2809 LPSTR *oids = NULL; 2810 PCCERT_CONTEXT contexts[3]; 2811 2812 if (!pCertGetValidUsages) 2813 { 2814 win_skip("CertGetValidUsages() is not available\n"); 2815 return; 2816 } 2817 2818 /* Crash 2819 ret = pCertGetValidUsages(0, NULL, NULL, NULL, NULL); 2820 ret = pCertGetValidUsages(0, NULL, NULL, NULL, &size); 2821 */ 2822 contexts[0] = NULL; 2823 numOIDs = size = 0xdeadbeef; 2824 SetLastError(0xdeadbeef); 2825 ret = pCertGetValidUsages(1, &contexts[0], &numOIDs, NULL, &size); 2826 ok(ret, "CertGetValidUsages failed: %d\n", GetLastError()); 2827 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs); 2828 ok(size == 0, "Expected size 0, got %d\n", size); 2829 contexts[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, 2830 sizeof(bigCert)); 2831 contexts[1] = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage, 2832 sizeof(certWithUsage)); 2833 contexts[2] = CertCreateCertificateContext(X509_ASN_ENCODING, 2834 cert2WithUsage, sizeof(cert2WithUsage)); 2835 numOIDs = size = 0xdeadbeef; 2836 ret = pCertGetValidUsages(0, NULL, &numOIDs, NULL, &size); 2837 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError()); 2838 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs); 2839 ok(size == 0, "Expected size 0, got %d\n", size); 2840 numOIDs = size = 0xdeadbeef; 2841 ret = pCertGetValidUsages(1, contexts, &numOIDs, NULL, &size); 2842 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError()); 2843 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs); 2844 ok(size == 0, "Expected size 0, got %d\n", size); 2845 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, NULL, &size); 2846 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError()); 2847 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs); 2848 ok(size, "Expected non-zero size\n"); 2849 oids = HeapAlloc(GetProcessHeap(), 0, size); 2850 if (oids) 2851 { 2852 int i; 2853 DWORD smallSize = 1; 2854 2855 SetLastError(0xdeadbeef); 2856 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &smallSize); 2857 ok(!ret && GetLastError() == ERROR_MORE_DATA, 2858 "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); 2859 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size); 2860 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError()); 2861 for (i = 0; i < numOIDs; i++) 2862 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n", 2863 oids[i]); 2864 HeapFree(GetProcessHeap(), 0, oids); 2865 } 2866 numOIDs = 0xdeadbeef; 2867 /* Oddly enough, this crashes when the number of contexts is not 1: 2868 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size); 2869 * but setting size to 0 allows it to succeed: 2870 */ 2871 size = 0; 2872 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size); 2873 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError()); 2874 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs); 2875 ok(size, "Expected non-zero size\n"); 2876 oids = HeapAlloc(GetProcessHeap(), 0, size); 2877 if (oids) 2878 { 2879 int i; 2880 2881 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size); 2882 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError()); 2883 for (i = 0; i < numOIDs; i++) 2884 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n", 2885 oids[i]); 2886 HeapFree(GetProcessHeap(), 0, oids); 2887 } 2888 numOIDs = 0xdeadbeef; 2889 size = 0; 2890 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, NULL, &size); 2891 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError()); 2892 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs); 2893 ok(size, "Expected non-zero size\n"); 2894 oids = HeapAlloc(GetProcessHeap(), 0, size); 2895 if (oids) 2896 { 2897 int i; 2898 2899 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, oids, &size); 2900 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError()); 2901 for (i = 0; i < numOIDs; i++) 2902 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n", 2903 oids[i]); 2904 HeapFree(GetProcessHeap(), 0, oids); 2905 } 2906 numOIDs = 0xdeadbeef; 2907 size = 0; 2908 ret = pCertGetValidUsages(3, contexts, &numOIDs, NULL, &size); 2909 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError()); 2910 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs); 2911 ok(size, "Expected non-zero size\n"); 2912 oids = HeapAlloc(GetProcessHeap(), 0, size); 2913 if (oids) 2914 { 2915 int i; 2916 2917 ret = pCertGetValidUsages(3, contexts, &numOIDs, oids, &size); 2918 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError()); 2919 for (i = 0; i < numOIDs; i++) 2920 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n", 2921 oids[i]); 2922 HeapFree(GetProcessHeap(), 0, oids); 2923 } 2924 CertFreeCertificateContext(contexts[0]); 2925 CertFreeCertificateContext(contexts[1]); 2926 CertFreeCertificateContext(contexts[2]); 2927 } 2928 2929 static BYTE cn[] = { 2930 0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75, 2931 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67 }; 2932 static BYTE cnWithLeadingSpace[] = { 2933 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x20,0x4a, 2934 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67 }; 2935 static BYTE cnWithTrailingSpace[] = { 2936 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75, 2937 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x20 }; 2938 static BYTE cnWithIntermediateSpace[] = { 2939 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75, 2940 0x61,0x6e,0x20,0x20,0x4c,0x61,0x6e,0x67 }; 2941 static BYTE cnThenO[] = { 2942 0x30,0x2d,0x31,0x2b,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75, 2943 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x30,0x17,0x06,0x03,0x55,0x04,0x0a,0x13, 2944 0x10,0x54,0x68,0x65,0x20,0x57,0x69,0x6e,0x65,0x20,0x50,0x72,0x6f,0x6a,0x65, 2945 0x63,0x74 }; 2946 static BYTE oThenCN[] = { 2947 0x30,0x2d,0x31,0x2b,0x30,0x10,0x06,0x03,0x55,0x04,0x0a,0x13,0x09,0x4a,0x75, 2948 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13, 2949 0x10,0x54,0x68,0x65,0x20,0x57,0x69,0x6e,0x65,0x20,0x50,0x72,0x6f,0x6a,0x65, 2950 0x63,0x74 }; 2951 2952 static void testCompareCertName(void) 2953 { 2954 static BYTE bogus[] = { 1, 2, 3, 4 }; 2955 static BYTE bogusPrime[] = { 0, 1, 2, 3, 4 }; 2956 static BYTE emptyPrime[] = { 0x30, 0x00, 0x01 }; 2957 BOOL ret; 2958 CERT_NAME_BLOB blob1, blob2; 2959 2960 /* crashes 2961 ret = CertCompareCertificateName(0, NULL, NULL); 2962 */ 2963 /* An empty name checks against itself.. */ 2964 blob1.pbData = emptyCert; 2965 blob1.cbData = sizeof(emptyCert); 2966 ret = CertCompareCertificateName(0, &blob1, &blob1); 2967 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError()); 2968 /* It doesn't have to be a valid encoded name.. */ 2969 blob1.pbData = bogus; 2970 blob1.cbData = sizeof(bogus); 2971 ret = CertCompareCertificateName(0, &blob1, &blob1); 2972 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError()); 2973 /* Leading zeroes matter.. */ 2974 blob2.pbData = bogusPrime; 2975 blob2.cbData = sizeof(bogusPrime); 2976 ret = CertCompareCertificateName(0, &blob1, &blob2); 2977 ok(!ret, "Expected failure\n"); 2978 /* As do trailing extra bytes. */ 2979 blob2.pbData = emptyPrime; 2980 blob2.cbData = sizeof(emptyPrime); 2981 ret = CertCompareCertificateName(0, &blob1, &blob2); 2982 ok(!ret, "Expected failure\n"); 2983 /* Tests to show that CertCompareCertificateName doesn't decode the name 2984 * to remove spaces, or to do an order-independent comparison. 2985 */ 2986 /* Compare CN="Juan Lang" with CN=" Juan Lang" */ 2987 blob1.pbData = cn; 2988 blob1.cbData = sizeof(cn); 2989 blob2.pbData = cnWithLeadingSpace; 2990 blob2.cbData = sizeof(cnWithLeadingSpace); 2991 ret = CertCompareCertificateName(0, &blob1, &blob2); 2992 ok(!ret, "Expected failure\n"); 2993 ret = CertCompareCertificateName(X509_ASN_ENCODING, &blob1, &blob2); 2994 ok(!ret, "Expected failure\n"); 2995 /* Compare CN="Juan Lang" with CN="Juan Lang " */ 2996 blob2.pbData = cnWithTrailingSpace; 2997 blob2.cbData = sizeof(cnWithTrailingSpace); 2998 ret = CertCompareCertificateName(0, &blob1, &blob2); 2999 ok(!ret, "Expected failure\n"); 3000 ret = CertCompareCertificateName(X509_ASN_ENCODING, &blob1, &blob2); 3001 ok(!ret, "Expected failure\n"); 3002 /* Compare CN="Juan Lang" with CN="Juan Lang" */ 3003 blob2.pbData = cnWithIntermediateSpace; 3004 blob2.cbData = sizeof(cnWithIntermediateSpace); 3005 ret = CertCompareCertificateName(0, &blob1, &blob2); 3006 ok(!ret, "Expected failure\n"); 3007 ret = CertCompareCertificateName(X509_ASN_ENCODING, &blob1, &blob2); 3008 ok(!ret, "Expected failure\n"); 3009 /* Compare 'CN="Juan Lang", O="The Wine Project"' with 3010 * 'O="The Wine Project", CN="Juan Lang"' 3011 */ 3012 blob1.pbData = cnThenO; 3013 blob1.cbData = sizeof(cnThenO); 3014 blob2.pbData = oThenCN; 3015 blob2.cbData = sizeof(oThenCN); 3016 ret = CertCompareCertificateName(0, &blob1, &blob2); 3017 ok(!ret, "Expected failure\n"); 3018 ret = CertCompareCertificateName(X509_ASN_ENCODING, &blob1, &blob2); 3019 ok(!ret, "Expected failure\n"); 3020 } 3021 3022 static void testIsRDNAttrsInCertificateName(void) 3023 { 3024 static char oid_1_2_3[] = "1.2.3"; 3025 static char oid_common_name[] = szOID_COMMON_NAME; 3026 static char oid_organization[] = szOID_ORGANIZATION_NAME; 3027 static char juan[] = "Juan Lang"; 3028 static char juan_with_leading_space[] = " Juan Lang"; 3029 static char juan_with_intermediate_space[] = "Juan Lang"; 3030 static char juan_with_trailing_space[] = "Juan Lang "; 3031 static char juan_lower_case[] = "juan lang"; 3032 static WCHAR juanW[] = { 'J','u','a','n',' ','L','a','n','g',0 }; 3033 static char the_wine_project[] = "The Wine Project"; 3034 BOOL ret; 3035 CERT_NAME_BLOB name; 3036 CERT_RDN_ATTR attr[2]; 3037 CERT_RDN rdn = { 0, NULL }; 3038 3039 name.cbData = sizeof(cn); 3040 name.pbData = cn; 3041 if (0) 3042 { 3043 /* Crash */ 3044 CertIsRDNAttrsInCertificateName(0, 0, NULL, NULL); 3045 CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, NULL); 3046 } 3047 SetLastError(0xdeadbeef); 3048 ret = CertIsRDNAttrsInCertificateName(0, 0, &name, NULL); 3049 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 3050 "expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 3051 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3052 ok(ret, "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError()); 3053 attr[0].pszObjId = oid_1_2_3; 3054 rdn.rgRDNAttr = attr; 3055 rdn.cRDNAttr = 1; 3056 SetLastError(0xdeadbeef); 3057 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3058 ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, 3059 "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); 3060 attr[0].pszObjId = oid_common_name; 3061 attr[0].dwValueType = CERT_RDN_PRINTABLE_STRING; 3062 attr[0].Value.cbData = strlen(juan); 3063 attr[0].Value.pbData = (BYTE *)juan; 3064 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3065 ok(ret, "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError()); 3066 /* Again, spaces are not removed for name comparison. */ 3067 attr[0].Value.cbData = strlen(juan_with_leading_space); 3068 attr[0].Value.pbData = (BYTE *)juan_with_leading_space; 3069 SetLastError(0xdeadbeef); 3070 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3071 ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, 3072 "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); 3073 attr[0].Value.cbData = strlen(juan_with_intermediate_space); 3074 attr[0].Value.pbData = (BYTE *)juan_with_intermediate_space; 3075 SetLastError(0xdeadbeef); 3076 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3077 ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, 3078 "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); 3079 attr[0].Value.cbData = strlen(juan_with_trailing_space); 3080 attr[0].Value.pbData = (BYTE *)juan_with_trailing_space; 3081 SetLastError(0xdeadbeef); 3082 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3083 ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, 3084 "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); 3085 /* The lower case name isn't matched unless a case insensitive match is 3086 * specified. 3087 */ 3088 attr[0].Value.cbData = strlen(juan_lower_case); 3089 attr[0].Value.pbData = (BYTE *)juan_lower_case; 3090 SetLastError(0xdeadbeef); 3091 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3092 ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, 3093 "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); 3094 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 3095 CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG, &name, &rdn); 3096 ok(ret || 3097 broken(!ret && GetLastError() == CRYPT_E_NO_MATCH), /* Older crypt32 */ 3098 "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError()); 3099 /* The values don't match unless they have the same RDN type */ 3100 attr[0].dwValueType = CERT_RDN_UNICODE_STRING; 3101 attr[0].Value.cbData = lstrlenW(juanW) * sizeof(WCHAR); 3102 attr[0].Value.pbData = (BYTE *)juanW; 3103 SetLastError(0xdeadbeef); 3104 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3105 ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, 3106 "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); 3107 SetLastError(0xdeadbeef); 3108 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 3109 CERT_UNICODE_IS_RDN_ATTRS_FLAG, &name, &rdn); 3110 ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, 3111 "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); 3112 attr[0].dwValueType = CERT_RDN_IA5_STRING; 3113 attr[0].Value.cbData = strlen(juan); 3114 attr[0].Value.pbData = (BYTE *)juan; 3115 SetLastError(0xdeadbeef); 3116 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3117 ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, 3118 "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); 3119 /* All attributes must be present */ 3120 attr[0].dwValueType = CERT_RDN_PRINTABLE_STRING; 3121 attr[0].Value.cbData = strlen(juan); 3122 attr[0].Value.pbData = (BYTE *)juan; 3123 attr[1].pszObjId = oid_organization; 3124 attr[1].dwValueType = CERT_RDN_PRINTABLE_STRING; 3125 attr[1].Value.cbData = strlen(the_wine_project); 3126 attr[1].Value.pbData = (BYTE *)the_wine_project; 3127 rdn.cRDNAttr = 2; 3128 SetLastError(0xdeadbeef); 3129 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3130 ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, 3131 "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); 3132 /* Order also matters */ 3133 name.pbData = cnThenO; 3134 name.cbData = sizeof(cnThenO); 3135 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3136 ok(ret, "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError()); 3137 name.pbData = oThenCN; 3138 name.cbData = sizeof(oThenCN); 3139 SetLastError(0xdeadbeef); 3140 ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); 3141 ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, 3142 "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); 3143 } 3144 3145 static BYTE int1[] = { 0x88, 0xff, 0xff, 0xff }; 3146 static BYTE int2[] = { 0x88, 0xff }; 3147 static BYTE int3[] = { 0x23, 0xff }; 3148 static BYTE int4[] = { 0x7f, 0x00 }; 3149 static BYTE int5[] = { 0x7f }; 3150 static BYTE int6[] = { 0x80, 0x00, 0x00, 0x00 }; 3151 static BYTE int7[] = { 0x80, 0x00 }; 3152 3153 static struct IntBlobTest 3154 { 3155 CRYPT_INTEGER_BLOB blob1; 3156 CRYPT_INTEGER_BLOB blob2; 3157 BOOL areEqual; 3158 } intBlobs[] = { 3159 { { sizeof(int1), int1 }, { sizeof(int2), int2 }, TRUE }, 3160 { { sizeof(int3), int3 }, { sizeof(int3), int3 }, TRUE }, 3161 { { sizeof(int4), int4 }, { sizeof(int5), int5 }, TRUE }, 3162 { { sizeof(int6), int6 }, { sizeof(int7), int7 }, TRUE }, 3163 { { sizeof(int1), int1 }, { sizeof(int7), int7 }, FALSE }, 3164 }; 3165 3166 static void testCompareIntegerBlob(void) 3167 { 3168 DWORD i; 3169 BOOL ret; 3170 3171 for (i = 0; i < sizeof(intBlobs) / sizeof(intBlobs[0]); i++) 3172 { 3173 ret = CertCompareIntegerBlob(&intBlobs[i].blob1, &intBlobs[i].blob2); 3174 ok(ret == intBlobs[i].areEqual, 3175 "%d: expected blobs %s compare\n", i, intBlobs[i].areEqual ? 3176 "to" : "not to"); 3177 } 3178 } 3179 3180 static void testComparePublicKeyInfo(void) 3181 { 3182 BOOL ret; 3183 CERT_PUBLIC_KEY_INFO info1 = { { 0 } }, info2 = { { 0 } }; 3184 static CHAR oid_rsa_rsa[] = szOID_RSA_RSA; 3185 static CHAR oid_rsa_sha1rsa[] = szOID_RSA_SHA1RSA; 3186 static CHAR oid_x957_dsa[] = szOID_X957_DSA; 3187 static BYTE bits1[] = { 1, 0 }; 3188 static BYTE bits2[] = { 0 }; 3189 static BYTE bits3[] = { 1 }; 3190 static BYTE bits4[] = { 0x30,8, 2,1,0x81, 2,3,1,0,1 }; 3191 static BYTE bits5[] = { 0x30,9, 2,2,0,0x81, 2,3,1,0,1 }; 3192 static BYTE bits6[] = { 0x30,9, 2,2,0,0x82, 2,3,1,0,1 }; 3193 3194 /* crashes 3195 ret = CertComparePublicKeyInfo(0, NULL, NULL); 3196 */ 3197 /* Empty public keys compare */ 3198 ret = CertComparePublicKeyInfo(0, &info1, &info2); 3199 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError()); 3200 /* Different OIDs appear to compare */ 3201 info1.Algorithm.pszObjId = oid_rsa_rsa; 3202 info2.Algorithm.pszObjId = oid_rsa_sha1rsa; 3203 ret = CertComparePublicKeyInfo(0, &info1, &info2); 3204 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError()); 3205 info2.Algorithm.pszObjId = oid_x957_dsa; 3206 ret = CertComparePublicKeyInfo(0, &info1, &info2); 3207 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError()); 3208 info1.PublicKey.cbData = sizeof(bits1); 3209 info1.PublicKey.pbData = bits1; 3210 info1.PublicKey.cUnusedBits = 0; 3211 info2.PublicKey.cbData = sizeof(bits1); 3212 info2.PublicKey.pbData = bits1; 3213 info2.PublicKey.cUnusedBits = 0; 3214 ret = CertComparePublicKeyInfo(0, &info1, &info2); 3215 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError()); 3216 info2.Algorithm.pszObjId = oid_rsa_rsa; 3217 info1.PublicKey.cbData = sizeof(bits4); 3218 info1.PublicKey.pbData = bits4; 3219 info1.PublicKey.cUnusedBits = 0; 3220 info2.PublicKey.cbData = sizeof(bits5); 3221 info2.PublicKey.pbData = bits5; 3222 info2.PublicKey.cUnusedBits = 0; 3223 ret = CertComparePublicKeyInfo(0, &info1, &info2); 3224 ok(!ret, "CertComparePublicKeyInfo: as raw binary: keys should be unequal\n"); 3225 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2); 3226 ok(ret || 3227 broken(!ret), /* win9x */ 3228 "CertComparePublicKeyInfo: as ASN.1 encoded: keys should be equal\n"); 3229 info1.PublicKey.cUnusedBits = 1; 3230 info2.PublicKey.cUnusedBits = 5; 3231 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2); 3232 ok(ret || 3233 broken(!ret), /* win9x */ 3234 "CertComparePublicKeyInfo: ASN.1 encoding should ignore cUnusedBits\n"); 3235 info1.PublicKey.cUnusedBits = 0; 3236 info2.PublicKey.cUnusedBits = 0; 3237 info1.PublicKey.cbData--; /* kill one byte, make ASN.1 encoded data invalid */ 3238 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2); 3239 ok(!ret, "CertComparePublicKeyInfo: comparing bad ASN.1 encoded key should fail\n"); 3240 /* Even though they compare in their used bits, these do not compare */ 3241 info1.PublicKey.cbData = sizeof(bits2); 3242 info1.PublicKey.pbData = bits2; 3243 info1.PublicKey.cUnusedBits = 0; 3244 info2.PublicKey.cbData = sizeof(bits3); 3245 info2.PublicKey.pbData = bits3; 3246 info2.PublicKey.cUnusedBits = 1; 3247 ret = CertComparePublicKeyInfo(0, &info1, &info2); 3248 /* Simple (non-comparing) case */ 3249 ok(!ret, "Expected keys not to compare\n"); 3250 info2.PublicKey.cbData = sizeof(bits1); 3251 info2.PublicKey.pbData = bits1; 3252 info2.PublicKey.cUnusedBits = 0; 3253 ret = CertComparePublicKeyInfo(0, &info1, &info2); 3254 ok(!ret, "Expected keys not to compare\n"); 3255 /* ASN.1 encoded non-comparing case */ 3256 info1.PublicKey.cbData = sizeof(bits5); 3257 info1.PublicKey.pbData = bits5; 3258 info1.PublicKey.cUnusedBits = 0; 3259 info2.PublicKey.cbData = sizeof(bits6); 3260 info2.PublicKey.pbData = bits6; 3261 info2.PublicKey.cUnusedBits = 0; 3262 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2); 3263 ok(!ret, "CertComparePublicKeyInfo: different keys should be unequal\n"); 3264 } 3265 3266 static void testHashPublicKeyInfo(void) 3267 { 3268 BOOL ret; 3269 CERT_PUBLIC_KEY_INFO info = { { 0 } }; 3270 DWORD len; 3271 3272 /* Crash 3273 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, NULL); 3274 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, &info, NULL, NULL); 3275 */ 3276 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, &len); 3277 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 3278 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 3279 /* Crashes on some win9x boxes */ 3280 if (0) 3281 { 3282 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, NULL, NULL, &len); 3283 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 3284 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 3285 } 3286 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, NULL, &len); 3287 ok(ret || 3288 broken(!ret), /* win9x */ 3289 "CryptHashPublicKeyInfo failed: %08x\n", GetLastError()); 3290 if (ret) 3291 { 3292 ok(len == 16, "Expected hash size 16, got %d\n", len); 3293 if (len == 16) 3294 { 3295 static const BYTE emptyHash[] = { 0xb8,0x51,0x3a,0x31,0x0e,0x9f,0x40, 3296 0x36,0x9c,0x92,0x45,0x1b,0x9d,0xc8,0xf9,0xf6 }; 3297 BYTE buf[16]; 3298 3299 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, buf, 3300 &len); 3301 ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError()); 3302 ok(!memcmp(buf, emptyHash, len), "Unexpected hash\n"); 3303 } 3304 } 3305 } 3306 3307 static const BYTE md5SignedEmptyCertHash[] = { 0xfb,0x0f,0x66,0x82,0x66,0xd9, 3308 0xe5,0xf8,0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 }; 3309 3310 static void testHashToBeSigned(void) 3311 { 3312 BOOL ret; 3313 DWORD size; 3314 BYTE hash[16]; 3315 3316 /* Crash */ 3317 if (0) 3318 { 3319 CryptHashToBeSigned(0, 0, NULL, 0, NULL, NULL); 3320 } 3321 SetLastError(0xdeadbeef); 3322 ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, &size); 3323 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 3324 "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); 3325 SetLastError(0xdeadbeef); 3326 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, NULL, 0, NULL, &size); 3327 ok(!ret && 3328 (GetLastError() == CRYPT_E_ASN1_EOD || 3329 GetLastError() == OSS_BAD_ARG), /* win9x */ 3330 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); 3331 /* Can't sign anything: has to be asn.1 encoded, at least */ 3332 SetLastError(0xdeadbeef); 3333 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, int1, sizeof(int1), 3334 NULL, &size); 3335 ok(!ret && 3336 (GetLastError() == CRYPT_E_ASN1_BADTAG || 3337 GetLastError() == OSS_MORE_INPUT), /* win9x */ 3338 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); 3339 /* Can't be empty, either */ 3340 SetLastError(0xdeadbeef); 3341 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, emptyCert, 3342 sizeof(emptyCert), NULL, &size); 3343 ok(!ret && 3344 (GetLastError() == CRYPT_E_ASN1_CORRUPT || 3345 GetLastError() == OSS_DATA_ERROR), /* win9x */ 3346 "expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError()); 3347 /* Signing a cert works */ 3348 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert, 3349 sizeof(md5SignedEmptyCert), NULL, &size); 3350 ok(ret || 3351 broken(!ret), /* win9x */ 3352 "CryptHashToBeSigned failed: %08x\n", GetLastError()); 3353 if (ret) 3354 { 3355 ok(size == sizeof(md5SignedEmptyCertHash), "unexpected size %d\n", size); 3356 } 3357 3358 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert, 3359 sizeof(md5SignedEmptyCert), hash, &size); 3360 ok(ret || broken(!ret && GetLastError() == NTE_BAD_ALGID) /* NT4 */, 3361 "CryptHashToBeSigned failed: %08x\n", GetLastError()); 3362 3363 ok(!memcmp(hash, md5SignedEmptyCertHash, size), "unexpected value\n"); 3364 } 3365 3366 static void testCompareCert(void) 3367 { 3368 CERT_INFO info1 = { 0 }, info2 = { 0 }; 3369 BOOL ret; 3370 3371 /* Crashes */ 3372 if (0) 3373 CertCompareCertificate(X509_ASN_ENCODING, NULL, NULL); 3374 3375 /* Certs with the same issuer and serial number are equal, even if they 3376 * differ in other respects (like subject). 3377 */ 3378 info1.SerialNumber.pbData = serialNum; 3379 info1.SerialNumber.cbData = sizeof(serialNum); 3380 info1.Issuer.pbData = subjectName; 3381 info1.Issuer.cbData = sizeof(subjectName); 3382 info1.Subject.pbData = subjectName2; 3383 info1.Subject.cbData = sizeof(subjectName2); 3384 info2.SerialNumber.pbData = serialNum; 3385 info2.SerialNumber.cbData = sizeof(serialNum); 3386 info2.Issuer.pbData = subjectName; 3387 info2.Issuer.cbData = sizeof(subjectName); 3388 info2.Subject.pbData = subjectName; 3389 info2.Subject.cbData = sizeof(subjectName); 3390 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2); 3391 ok(ret, "Expected certs to be equal\n"); 3392 3393 info2.Issuer.pbData = subjectName2; 3394 info2.Issuer.cbData = sizeof(subjectName2); 3395 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2); 3396 ok(!ret, "Expected certs not to be equal\n"); 3397 } 3398 3399 static void testVerifySubjectCert(void) 3400 { 3401 BOOL ret; 3402 DWORD flags; 3403 PCCERT_CONTEXT context1, context2; 3404 3405 /* Crashes 3406 ret = CertVerifySubjectCertificateContext(NULL, NULL, NULL); 3407 */ 3408 flags = 0; 3409 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags); 3410 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n", 3411 GetLastError()); 3412 flags = CERT_STORE_NO_CRL_FLAG; 3413 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags); 3414 ok(!ret && GetLastError() == E_INVALIDARG, 3415 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3416 3417 flags = 0; 3418 context1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, 3419 sizeof(bigCert)); 3420 ret = CertVerifySubjectCertificateContext(NULL, context1, &flags); 3421 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n", 3422 GetLastError()); 3423 ret = CertVerifySubjectCertificateContext(context1, NULL, &flags); 3424 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n", 3425 GetLastError()); 3426 ret = CertVerifySubjectCertificateContext(context1, context1, &flags); 3427 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n", 3428 GetLastError()); 3429 3430 context2 = CertCreateCertificateContext(X509_ASN_ENCODING, 3431 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject)); 3432 SetLastError(0xdeadbeef); 3433 ret = CertVerifySubjectCertificateContext(context1, context2, &flags); 3434 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n", 3435 GetLastError()); 3436 flags = CERT_STORE_REVOCATION_FLAG; 3437 ret = CertVerifySubjectCertificateContext(context1, context2, &flags); 3438 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n", 3439 GetLastError()); 3440 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG), 3441 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n", 3442 flags); 3443 flags = CERT_STORE_SIGNATURE_FLAG; 3444 ret = CertVerifySubjectCertificateContext(context1, context2, &flags); 3445 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n", 3446 GetLastError()); 3447 ok(flags == CERT_STORE_SIGNATURE_FLAG, 3448 "Expected CERT_STORE_SIGNATURE_FLAG, got %08x\n", flags); 3449 CertFreeCertificateContext(context2); 3450 3451 CertFreeCertificateContext(context1); 3452 } 3453 3454 static const BYTE rootWithKeySignAndCRLSign[] = { 3455 0x30,0x82,0x01,0xdf,0x30,0x82,0x01,0x4c,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, 3456 0x5b,0xc7,0x0b,0x27,0x99,0xbb,0x2e,0x99,0x47,0x9d,0x45,0x4e,0x7c,0x1a,0xca, 3457 0xe8,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, 3458 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, 3459 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 3460 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, 3461 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, 3462 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, 3463 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, 3464 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, 3465 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, 3466 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, 3467 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, 3468 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, 3469 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, 3470 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, 3471 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, 3472 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, 3473 0x00,0x01,0xa3,0x42,0x30,0x40,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, 3474 0xff,0x04,0x04,0x03,0x02,0x00,0x06,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, 3475 0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d, 3476 0x0e,0x04,0x16,0x04,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0, 3477 0x58,0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x09,0x06,0x05,0x2b, 3478 0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,0x81,0x00,0x74,0xcb,0x21,0xfd,0x2d, 3479 0x25,0xdc,0xa5,0xaa,0xa1,0x26,0xdc,0x8b,0x40,0x11,0x64,0xae,0x5c,0x71,0x3c, 3480 0x28,0xbc,0xf9,0xb3,0xcb,0xa5,0x94,0xb2,0x8d,0x4c,0x23,0x2b,0x9b,0xde,0x2c, 3481 0x4c,0x30,0x04,0xc6,0x88,0x10,0x2f,0x53,0xfd,0x6c,0x82,0xf1,0x13,0xfb,0xda, 3482 0x27,0x75,0x25,0x48,0xe4,0x72,0x09,0x2a,0xee,0xb4,0x1e,0xc9,0x55,0xf5,0xf7, 3483 0x82,0x91,0xd8,0x4b,0xe4,0x3a,0xfe,0x97,0x87,0xdf,0xfb,0x15,0x5a,0x12,0x3e, 3484 0x12,0xe6,0xad,0x40,0x0b,0xcf,0xee,0x1a,0x44,0xe0,0x83,0xb2,0x67,0x94,0xd4, 3485 0x2e,0x7c,0xf2,0x06,0x9d,0xb3,0x3b,0x7e,0x2f,0xda,0x25,0x66,0x7e,0xa7,0x1f, 3486 0x45,0xd4,0xf5,0xe3,0xdf,0x2a,0xf1,0x18,0x28,0x20,0xb5,0xf8,0xf5,0x8d,0x7a, 3487 0x2e,0x84,0xee }; 3488 static const BYTE eeCert[] = { 3489 0x30,0x82,0x01,0xb9,0x30,0x82,0x01,0x22,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, 3490 0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, 3491 0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, 3492 0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30, 3493 0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30, 3494 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, 3495 0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, 3496 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, 3497 0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, 3498 0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, 3499 0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, 3500 0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, 3501 0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, 3502 0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, 3503 0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, 3504 0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, 3505 0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, 3506 0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x1f,0x06,0x03,0x55, 3507 0x1d,0x23,0x04,0x18,0x30,0x18,0x80,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2, 3508 0x28,0x89,0xa0,0x58,0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x0d, 3509 0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81, 3510 0x81,0x00,0x8a,0x49,0xa9,0x86,0x5e,0xc9,0x33,0x7e,0xfd,0xab,0x64,0x1f,0x6d, 3511 0x00,0xd7,0x9b,0xec,0xd1,0x5b,0x38,0xcc,0xd6,0xf3,0xf2,0xb4,0x75,0x70,0x00, 3512 0x82,0x9d,0x37,0x58,0xe1,0xcd,0x2c,0x61,0xb3,0x28,0xe7,0x8a,0x00,0xbe,0x6e, 3513 0xca,0xe8,0x55,0xd5,0xad,0x3a,0xea,0xaf,0x13,0x20,0x1c,0x44,0xfc,0xb4,0xf9, 3514 0x29,0x2b,0xdc,0x8a,0x2d,0x1b,0x27,0x9e,0xb9,0x3b,0x4a,0x71,0x9d,0x47,0x7d, 3515 0xf7,0x92,0x6b,0x21,0x7f,0xfa,0x88,0x79,0x94,0x33,0xf6,0xdd,0x92,0x04,0x92, 3516 0xd6,0x5e,0x0a,0x74,0xf2,0x85,0xa6,0xd5,0x3c,0x28,0xc0,0x89,0x5d,0xda,0xf3, 3517 0xa6,0x01,0xc2,0xe9,0xa3,0xc1,0xb7,0x21,0x08,0xba,0x18,0x07,0x45,0xeb,0x77, 3518 0x7d,0xcd,0xc6,0xe7,0x2a,0x7b,0x46,0xd2,0x3d,0xb5 }; 3519 static const BYTE rootSignedCRL[] = { 3520 0x30,0x82,0x01,0x1f,0x30,0x81,0x89,0x02,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a, 3521 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x10,0x31,0x0e,0x30, 3522 0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x17,0x0d, 3523 0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d, 3524 0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x14, 3525 0x30,0x12,0x02,0x01,0x01,0x17,0x0d,0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30, 3526 0x30,0x30,0x30,0x30,0x5a,0xa0,0x2f,0x30,0x2d,0x30,0x0a,0x06,0x03,0x55,0x1d, 3527 0x14,0x04,0x03,0x02,0x01,0x01,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18, 3528 0x30,0x18,0x80,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0,0x58, 3529 0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x0d,0x06,0x09,0x2a,0x86, 3530 0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xa3,0xcf, 3531 0x17,0x5d,0x7a,0x08,0xab,0x11,0x1a,0xbd,0x5c,0xde,0x9a,0x22,0x92,0x38,0xe6, 3532 0x96,0xcc,0xb1,0xc5,0x42,0x86,0xa6,0xae,0xad,0xa3,0x1a,0x2b,0xa0,0xb0,0x65, 3533 0xaa,0x9c,0xd7,0x2d,0x44,0x8c,0xae,0x61,0xc7,0x30,0x17,0x89,0x84,0x3b,0x4a, 3534 0x8f,0x17,0x08,0x06,0x37,0x1c,0xf7,0x2d,0x4e,0x47,0x07,0x61,0x50,0xd9,0x06, 3535 0xd1,0x46,0xed,0x0a,0xbb,0xc3,0x9b,0x36,0x0b,0xa7,0x27,0x2f,0x2b,0x55,0xce, 3536 0x2a,0xa5,0x60,0xc6,0x53,0x28,0xe8,0xee,0xad,0x0e,0x2b,0xe8,0xd7,0x5f,0xc9, 3537 0xa5,0xed,0xf9,0x77,0xb0,0x3c,0x81,0xcf,0xcc,0x49,0xb2,0x1a,0xc3,0xfd,0x34, 3538 0xd5,0xbc,0xb0,0xd5,0xa5,0x9c,0x1b,0x72,0xc3,0x0f,0xa3,0xe3,0x3c,0xf0,0xc3, 3539 0x91,0xe8,0x93,0x4f,0xd4,0x2f }; 3540 3541 static void testVerifyRevocation(void) 3542 { 3543 BOOL ret; 3544 CERT_REVOCATION_STATUS status = { 0 }; 3545 PCCERT_CONTEXT certs[2]; 3546 CERT_REVOCATION_PARA revPara = { sizeof(revPara), 0 }; 3547 3548 /* Crash 3549 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL); 3550 */ 3551 SetLastError(0xdeadbeef); 3552 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status); 3553 ok(!ret && GetLastError() == E_INVALIDARG, 3554 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3555 status.cbSize = sizeof(status); 3556 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status); 3557 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError()); 3558 ret = CertVerifyRevocation(0, 2, 0, NULL, 0, NULL, &status); 3559 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError()); 3560 ret = CertVerifyRevocation(2, 0, 0, NULL, 0, NULL, &status); 3561 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError()); 3562 certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, 3563 sizeof(bigCert)); 3564 SetLastError(0xdeadbeef); 3565 ret = CertVerifyRevocation(0, 0, 1, (void **)certs, 0, NULL, &status); 3566 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL, 3567 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError()); 3568 SetLastError(0xdeadbeef); 3569 ret = CertVerifyRevocation(0, 2, 1, (void **)certs, 0, NULL, &status); 3570 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL, 3571 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError()); 3572 3573 CertFreeCertificateContext(certs[0]); 3574 3575 certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, 3576 rootWithKeySignAndCRLSign, sizeof(rootWithKeySignAndCRLSign)); 3577 certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, 3578 eeCert, sizeof(eeCert)); 3579 /* The root cert itself can't be checked for revocation */ 3580 SetLastError(0xdeadbeef); 3581 ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 3582 1, (void **)certs, 0, NULL, &status); 3583 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 3584 { 3585 win_skip("CERT_CONTEXT_REVOCATION_TYPE unsupported, skipping\n"); 3586 return; 3587 } 3588 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, 3589 "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); 3590 ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, 3591 "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); 3592 ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); 3593 /* Neither can the end cert */ 3594 SetLastError(0xdeadbeef); 3595 ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 3596 1, (void **)&certs[1], 0, NULL, &status); 3597 ok(!ret && (GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* Win9x */ || 3598 GetLastError() == CRYPT_E_REVOCATION_OFFLINE), 3599 "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n", 3600 GetLastError()); 3601 ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK /* Win9x */ || 3602 status.dwError == CRYPT_E_REVOCATION_OFFLINE, 3603 "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n", 3604 status.dwError); 3605 ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); 3606 /* Both certs together can't, either (they're not CRLs) */ 3607 SetLastError(0xdeadbeef); 3608 ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 3609 2, (void **)certs, 0, NULL, &status); 3610 ok(!ret && (GetLastError() == CRYPT_E_NO_REVOCATION_CHECK || 3611 GetLastError() == CRYPT_E_REVOCATION_OFFLINE /* WinME */), 3612 "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n", 3613 GetLastError()); 3614 ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK || 3615 status.dwError == CRYPT_E_REVOCATION_OFFLINE /* WinME */, 3616 "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n", 3617 status.dwError); 3618 ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); 3619 /* Now add a CRL to the hCrlStore */ 3620 revPara.hCrlStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 3621 CERT_STORE_CREATE_NEW_FLAG, NULL); 3622 CertAddEncodedCRLToStore(revPara.hCrlStore, X509_ASN_ENCODING, 3623 rootSignedCRL, sizeof(rootSignedCRL), CERT_STORE_ADD_ALWAYS, NULL); 3624 SetLastError(0xdeadbeef); 3625 ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 3626 2, (void **)certs, 0, &revPara, &status); 3627 ok(!ret && (GetLastError() == CRYPT_E_NO_REVOCATION_CHECK || 3628 GetLastError() == CRYPT_E_REVOCATION_OFFLINE /* WinME */), 3629 "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n", 3630 GetLastError()); 3631 ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK || 3632 status.dwError == CRYPT_E_REVOCATION_OFFLINE /* WinME */, 3633 "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n", 3634 status.dwError); 3635 ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); 3636 /* Specifying CERT_VERIFY_REV_CHAIN_FLAG doesn't change things either */ 3637 SetLastError(0xdeadbeef); 3638 ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 3639 2, (void **)certs, CERT_VERIFY_REV_CHAIN_FLAG, &revPara, &status); 3640 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, 3641 "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); 3642 ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, 3643 "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); 3644 ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); 3645 /* Again, specifying the issuer cert: no change */ 3646 revPara.pIssuerCert = certs[0]; 3647 SetLastError(0xdeadbeef); 3648 ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 3649 1, (void **)&certs[1], 0, &revPara, &status); 3650 /* Win2k thinks the cert is revoked, and it is, except the CRL is out of 3651 * date, hence the revocation status should be unknown. 3652 */ 3653 ok(!ret && (GetLastError() == CRYPT_E_NO_REVOCATION_CHECK || 3654 broken(GetLastError() == CRYPT_E_REVOKED /* Win2k */)), 3655 "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); 3656 ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK || 3657 broken(status.dwError == CRYPT_E_REVOKED /* Win2k */), 3658 "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); 3659 ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); 3660 CertCloseStore(revPara.hCrlStore, 0); 3661 CertFreeCertificateContext(certs[1]); 3662 CertFreeCertificateContext(certs[0]); 3663 } 3664 3665 static BYTE privKey[] = { 3666 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00, 3667 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10, 3668 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd, 3669 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde, 3670 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68, 3671 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27, 3672 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b, 3673 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4, 3674 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77, 3675 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca, 3676 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06, 3677 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72, 3678 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e, 3679 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf, 3680 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b, 3681 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd, 3682 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8, 3683 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67, 3684 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40, 3685 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e, 3686 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d, 3687 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda, 3688 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78, 3689 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 }; 3690 3691 static const BYTE exportedPublicKeyBlob[] = { 3692 0x06,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x02,0x00,0x00, 3693 0x01,0x00,0x01,0x00,0x79,0x10,0x1c,0xd0,0x6b,0x10,0x18,0x30,0x94,0x61,0xdc,0x0e, 3694 0xcb,0x96,0x4e,0x21,0x3f,0x79,0xcd,0xa9,0x17,0x62,0xbc,0xbb,0x61,0x4c,0xe0,0x75, 3695 0x38,0x6c,0xf3,0xde,0x60,0x86,0x03,0x97,0x65,0xeb,0x1e,0x6b,0xdb,0x53,0x85,0xad, 3696 0x68,0x21,0xf1,0x5d,0xe7,0x1f,0xe6,0x53,0xb4,0xbb,0x59,0x3e,0x14,0x27,0xb1,0x83, 3697 0xa7,0x3a,0x54,0xe2 }; 3698 3699 static const BYTE asnEncodedPublicKey[] = { 3700 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb, 3701 0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb, 3702 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62, 3703 0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10, 3704 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 }; 3705 3706 static void testAcquireCertPrivateKey(void) 3707 { 3708 BOOL ret; 3709 PCCERT_CONTEXT cert; 3710 HCRYPTPROV csp; 3711 DWORD size, keySpec; 3712 BOOL callerFree; 3713 CRYPT_KEY_PROV_INFO keyProvInfo; 3714 HCRYPTKEY key; 3715 WCHAR ms_def_prov_w[MAX_PATH]; 3716 3717 if (!pCryptAcquireCertificatePrivateKey) 3718 { 3719 win_skip("CryptAcquireCertificatePrivateKey() is not available\n"); 3720 return; 3721 } 3722 3723 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W); 3724 3725 keyProvInfo.pwszContainerName = cspNameW; 3726 keyProvInfo.pwszProvName = ms_def_prov_w; 3727 keyProvInfo.dwProvType = PROV_RSA_FULL; 3728 keyProvInfo.dwFlags = 0; 3729 keyProvInfo.cProvParam = 0; 3730 keyProvInfo.rgProvParam = NULL; 3731 keyProvInfo.dwKeySpec = AT_SIGNATURE; 3732 3733 pCryptAcquireContextA(NULL, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 3734 CRYPT_DELETEKEYSET); 3735 3736 cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert, 3737 sizeof(selfSignedCert)); 3738 3739 /* Crash 3740 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL, NULL); 3741 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL, 3742 &callerFree); 3743 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, &keySpec, 3744 NULL); 3745 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, NULL, NULL); 3746 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, &keySpec, 3747 &callerFree); 3748 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, NULL, NULL, NULL); 3749 */ 3750 3751 /* Missing private key */ 3752 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, NULL, NULL); 3753 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY, 3754 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError()); 3755 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec, 3756 &callerFree); 3757 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY, 3758 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError()); 3759 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, 3760 &keyProvInfo); 3761 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec, 3762 &callerFree); 3763 ok(!ret && (GetLastError() == CRYPT_E_NO_KEY_PROPERTY || GetLastError() == NTE_BAD_KEYSET /* win8 */), 3764 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError()); 3765 3766 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 3767 CRYPT_NEWKEYSET); 3768 ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key); 3769 ok(ret, "CryptImportKey failed: %08x\n", GetLastError()); 3770 if (ret) 3771 { 3772 HCRYPTPROV certCSP; 3773 DWORD size; 3774 CERT_KEY_CONTEXT keyContext; 3775 3776 /* Don't cache provider */ 3777 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP, 3778 &keySpec, &callerFree); 3779 ok(ret || 3780 broken(!ret), /* win95 */ 3781 "CryptAcquireCertificatePrivateKey failed: %08x\n", 3782 GetLastError()); 3783 if (ret) 3784 { 3785 ok(callerFree, "Expected callerFree to be TRUE\n"); 3786 CryptReleaseContext(certCSP, 0); 3787 } 3788 3789 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP, 3790 NULL, NULL); 3791 ok(ret || 3792 broken(!ret), /* win95 */ 3793 "CryptAcquireCertificatePrivateKey failed: %08x\n", 3794 GetLastError()); 3795 CryptReleaseContext(certCSP, 0); 3796 3797 /* Use the key prov info's caching (there shouldn't be any) */ 3798 ret = pCryptAcquireCertificatePrivateKey(cert, 3799 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec, 3800 &callerFree); 3801 ok(ret || 3802 broken(!ret), /* win95 */ 3803 "CryptAcquireCertificatePrivateKey failed: %08x\n", 3804 GetLastError()); 3805 if (ret) 3806 { 3807 ok(callerFree, "Expected callerFree to be TRUE\n"); 3808 CryptReleaseContext(certCSP, 0); 3809 } 3810 3811 /* Cache it (and check that it's cached) */ 3812 ret = pCryptAcquireCertificatePrivateKey(cert, 3813 CRYPT_ACQUIRE_CACHE_FLAG, NULL, &certCSP, &keySpec, &callerFree); 3814 ok(ret || 3815 broken(!ret), /* win95 */ 3816 "CryptAcquireCertificatePrivateKey failed: %08x\n", 3817 GetLastError()); 3818 ok(!callerFree, "Expected callerFree to be FALSE\n"); 3819 size = sizeof(keyContext); 3820 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID, 3821 &keyContext, &size); 3822 ok(ret || 3823 broken(!ret), /* win95 */ 3824 "CertGetCertificateContextProperty failed: %08x\n", 3825 GetLastError()); 3826 3827 /* Remove the cached provider */ 3828 CryptReleaseContext(keyContext.hCryptProv, 0); 3829 CertSetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID, 0, 3830 NULL); 3831 /* Allow caching via the key prov info */ 3832 keyProvInfo.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID; 3833 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, 3834 &keyProvInfo); 3835 /* Now use the key prov info's caching */ 3836 ret = pCryptAcquireCertificatePrivateKey(cert, 3837 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec, 3838 &callerFree); 3839 ok(ret || 3840 broken(!ret), /* win95 */ 3841 "CryptAcquireCertificatePrivateKey failed: %08x\n", 3842 GetLastError()); 3843 ok(!callerFree, "Expected callerFree to be FALSE\n"); 3844 size = sizeof(keyContext); 3845 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID, 3846 &keyContext, &size); 3847 ok(ret || 3848 broken(!ret), /* win95 */ 3849 "CertGetCertificateContextProperty failed: %08x\n", 3850 GetLastError()); 3851 CryptReleaseContext(certCSP, 0); 3852 3853 CryptDestroyKey(key); 3854 } 3855 3856 /* Some sanity-checking on public key exporting */ 3857 ret = CryptImportPublicKeyInfo(csp, X509_ASN_ENCODING, 3858 &cert->pCertInfo->SubjectPublicKeyInfo, &key); 3859 ok(ret, "CryptImportPublicKeyInfo failed: %08x\n", GetLastError()); 3860 if (ret) 3861 { 3862 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, NULL, &size); 3863 ok(ret, "CryptExportKey failed: %08x\n", GetLastError()); 3864 if (ret) 3865 { 3866 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size), encodedKey; 3867 3868 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, buf, &size); 3869 ok(ret, "CryptExportKey failed: %08x\n", GetLastError()); 3870 ok(size == sizeof(exportedPublicKeyBlob), "Unexpected size %d\n", 3871 size); 3872 ok(!memcmp(buf, exportedPublicKeyBlob, size), "Unexpected value\n"); 3873 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, 3874 buf, CRYPT_ENCODE_ALLOC_FLAG, NULL, &encodedKey, &size); 3875 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3876 if (ret) 3877 { 3878 ok(size == sizeof(asnEncodedPublicKey), "Unexpected size %d\n", 3879 size); 3880 ok(!memcmp(encodedKey, asnEncodedPublicKey, size), 3881 "Unexpected value\n"); 3882 LocalFree(encodedKey); 3883 } 3884 HeapFree(GetProcessHeap(), 0, buf); 3885 } 3886 CryptDestroyKey(key); 3887 } 3888 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, 3889 NULL, 0, NULL, NULL, &size); 3890 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError()); 3891 if (ret) 3892 { 3893 PCERT_PUBLIC_KEY_INFO info = HeapAlloc(GetProcessHeap(), 0, size); 3894 3895 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, 3896 NULL, 0, NULL, info, &size); 3897 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError()); 3898 if (ret) 3899 { 3900 ok(info->PublicKey.cbData == sizeof(asnEncodedPublicKey), 3901 "Unexpected size %d\n", info->PublicKey.cbData); 3902 ok(!memcmp(info->PublicKey.pbData, asnEncodedPublicKey, 3903 info->PublicKey.cbData), "Unexpected value\n"); 3904 } 3905 HeapFree(GetProcessHeap(), 0, info); 3906 } 3907 3908 CryptReleaseContext(csp, 0); 3909 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, 3910 CRYPT_DELETEKEYSET); 3911 3912 CertFreeCertificateContext(cert); 3913 } 3914 3915 static void testGetPublicKeyLength(void) 3916 { 3917 static char oid_rsa_rsa[] = szOID_RSA_RSA; 3918 static char oid_rsa_dh[] = szOID_RSA_DH; 3919 static char bogusOID[] = "1.2.3"; 3920 DWORD ret; 3921 CERT_PUBLIC_KEY_INFO info = { { 0 } }; 3922 BYTE bogusKey[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; 3923 BYTE key[] = { 0x30,0x0f,0x02,0x08,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 3924 0x02,0x03,0x01,0x00,0x01 }; 3925 3926 /* Crashes 3927 ret = CertGetPublicKeyLength(0, NULL); 3928 */ 3929 /* With an empty public key info */ 3930 SetLastError(0xdeadbeef); 3931 ret = CertGetPublicKeyLength(0, &info); 3932 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND, 3933 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n", 3934 ret, GetLastError()); 3935 SetLastError(0xdeadbeef); 3936 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info); 3937 ok(ret == 0 && 3938 (GetLastError() == CRYPT_E_ASN1_EOD || 3939 GetLastError() == OSS_BAD_ARG), /* win9x */ 3940 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n", 3941 ret, GetLastError()); 3942 /* With a nearly-empty public key info */ 3943 info.Algorithm.pszObjId = oid_rsa_rsa; 3944 SetLastError(0xdeadbeef); 3945 ret = CertGetPublicKeyLength(0, &info); 3946 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND, 3947 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n", 3948 ret, GetLastError()); 3949 SetLastError(0xdeadbeef); 3950 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info); 3951 ok(ret == 0 && 3952 (GetLastError() == CRYPT_E_ASN1_EOD || 3953 GetLastError() == OSS_BAD_ARG), /* win9x */ 3954 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n", 3955 ret, GetLastError()); 3956 /* With a bogus key */ 3957 info.PublicKey.cbData = sizeof(bogusKey); 3958 info.PublicKey.pbData = bogusKey; 3959 SetLastError(0xdeadbeef); 3960 ret = CertGetPublicKeyLength(0, &info); 3961 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND, 3962 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n", 3963 ret, GetLastError()); 3964 SetLastError(0xdeadbeef); 3965 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info); 3966 ok(ret == 0 && 3967 (GetLastError() == CRYPT_E_ASN1_BADTAG || 3968 GetLastError() == OSS_PDU_MISMATCH), /* win9x */ 3969 "Expected length 0 and CRYPT_E_ASN1_BADTAGTAG, got length %d, %08x\n", 3970 ret, GetLastError()); 3971 /* With a believable RSA key but a bogus OID */ 3972 info.Algorithm.pszObjId = bogusOID; 3973 info.PublicKey.cbData = sizeof(key); 3974 info.PublicKey.pbData = key; 3975 SetLastError(0xdeadbeef); 3976 ret = CertGetPublicKeyLength(0, &info); 3977 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND, 3978 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n", 3979 ret, GetLastError()); 3980 SetLastError(0xdeadbeef); 3981 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info); 3982 ok(ret == 56 || broken(ret == 0 && GetLastError() == NTE_BAD_LEN) /* Win7 */, 3983 "Expected length 56, got %d\n", ret); 3984 /* An RSA key with the DH OID */ 3985 info.Algorithm.pszObjId = oid_rsa_dh; 3986 SetLastError(0xdeadbeef); 3987 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info); 3988 ok(ret == 0 && 3989 (GetLastError() == CRYPT_E_ASN1_BADTAG || 3990 GetLastError() == E_INVALIDARG), /* win9x */ 3991 "Expected length 0 and CRYPT_E_ASN1_BADTAG, got length %d, %08x\n", 3992 ret, GetLastError()); 3993 /* With the RSA OID */ 3994 info.Algorithm.pszObjId = oid_rsa_rsa; 3995 SetLastError(0xdeadbeef); 3996 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info); 3997 ok(ret == 56 || broken(ret == 0 && GetLastError() == NTE_BAD_LEN) /* Win7 */, 3998 "Expected length 56, got %d\n", ret); 3999 /* With the RSA OID and a message encoding */ 4000 info.Algorithm.pszObjId = oid_rsa_rsa; 4001 SetLastError(0xdeadbeef); 4002 ret = CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &info); 4003 ok(ret == 56 || broken(ret == 0 && GetLastError() == NTE_BAD_LEN) /* Win7 */, 4004 "Expected length 56, got %d\n", ret); 4005 } 4006 4007 START_TEST(cert) 4008 { 4009 init_function_pointers(); 4010 4011 testAddCert(); 4012 testCertProperties(); 4013 testCreateCert(); 4014 testDupCert(); 4015 testFindCert(); 4016 testGetSubjectCert(); 4017 testGetIssuerCert(); 4018 testLinkCert(); 4019 4020 testCryptHashCert(); 4021 testCertSigs(); 4022 testSignAndEncodeCert(); 4023 testCreateSelfSignCert(); 4024 testIntendedKeyUsage(); 4025 testKeyUsage(); 4026 testGetValidUsages(); 4027 testCompareCertName(); 4028 testCompareIntegerBlob(); 4029 testComparePublicKeyInfo(); 4030 testHashPublicKeyInfo(); 4031 testHashToBeSigned(); 4032 testCompareCert(); 4033 testVerifySubjectCert(); 4034 testVerifyRevocation(); 4035 testAcquireCertPrivateKey(); 4036 testGetPublicKeyLength(); 4037 testIsRDNAttrsInCertificateName(); 4038 } 4039