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