crl.c 54.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * crypt32 CRL functions tests
 *
 * Copyright 2005-2006 Juan Lang
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdio.h>
#include <stdarg.h>
23

24 25 26 27 28 29 30 31
#include <windef.h>
#include <winbase.h>
#include <winreg.h>
#include <winerror.h>
#include <wincrypt.h>

#include "wine/test.h"

32

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20,
 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
static const BYTE bigCertWithDifferentIssuer[] = { 0x30, 0x7a, 0x02, 0x01,
 0x01, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
 0x02, 0x01, 0x01 };
static const BYTE CRL[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
 0x5a };
static const BYTE newerCRL[] = { 0x30, 0x2a, 0x30, 0x02, 0x06, 0x00, 0x30,
 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x17, 0x0d, 0x30, 0x36,
 0x30, 0x35, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
static const BYTE signedCRL[] = { 0x30, 0x45, 0x30, 0x2c, 0x30, 0x02, 0x06,
 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
 0x30, 0x5a, 0x30, 0x02, 0x06, 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c,
 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };

80 81
static BOOL (WINAPI *pCertFindCertificateInCRL)(PCCERT_CONTEXT,PCCRL_CONTEXT,DWORD,void*,PCRL_ENTRY*);
static PCCRL_CONTEXT (WINAPI *pCertFindCRLInStore)(HCERTSTORE,DWORD,DWORD,DWORD,const void*,PCCRL_CONTEXT);
82 83 84 85 86
static BOOL (WINAPI *pCertIsValidCRLForCertificate)(PCCERT_CONTEXT, PCCRL_CONTEXT, DWORD, void*);

static void init_function_pointers(void)
{
    HMODULE hdll = GetModuleHandleA("crypt32.dll");
87 88
    pCertFindCertificateInCRL = (void*)GetProcAddress(hdll, "CertFindCertificateInCRL");
    pCertFindCRLInStore = (void*)GetProcAddress(hdll, "CertFindCRLInStore");
89
    pCertIsValidCRLForCertificate = (void*)GetProcAddress(hdll, "CertIsValidCRLForCertificate");
90 91
}

92 93 94
static void testCreateCRL(void)
{
    PCCRL_CONTEXT context;
Juan Lang's avatar
Juan Lang committed
95
    DWORD GLE;
96 97 98

    context = CertCreateCRLContext(0, NULL, 0);
    ok(!context && GetLastError() == E_INVALIDARG,
99
     "Expected E_INVALIDARG, got %08x\n", GetLastError());
100
    context = CertCreateCRLContext(X509_ASN_ENCODING, NULL, 0);
Juan Lang's avatar
Juan Lang committed
101 102 103
    GLE = GetLastError();
    ok(!context && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
     "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
104
    context = CertCreateCRLContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
105
    ok(!context, "Expected failure\n");
106 107
    context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL) - 1);
108
    ok(!context, "Expected failure\n");
109 110
    context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL));
111
    ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
112 113 114
    if (context)
        CertFreeCRLContext(context);
    context = CertCreateCRLContext(X509_ASN_ENCODING, CRL, sizeof(CRL));
115
    ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
116 117 118 119
    if (context)
        CertFreeCRLContext(context);
}

120 121 122
static void testDupCRL(void)
{
    PCCRL_CONTEXT context, dupContext;
123
    BOOL res;
124 125 126 127 128 129 130 131

    context = CertDuplicateCRLContext(NULL);
    ok(context == NULL, "expected NULL\n");
    context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL));
    dupContext = CertDuplicateCRLContext(context);
    ok(dupContext != NULL, "expected a context\n");
    ok(dupContext == context, "expected identical context addresses\n");
132 133 134 135 136 137 138 139 140

    res = CertFreeCRLContext(dupContext);
    ok(res, "CertFreeCRLContext failed\n");

    res = CertFreeCRLContext(context);
    ok(res, "CertFreeCRLContext failed\n");

    res = CertFreeCRLContext(NULL);
    ok(res, "CertFreeCRLContext failed\n");
141 142
}

143 144 145 146
static void testAddCRL(void)
{
    HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
147
    PCCRL_CONTEXT context, context2;
148
    BOOL ret;
Juan Lang's avatar
Juan Lang committed
149
    DWORD GLE;
150

151
    ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
152 153 154 155 156
    if (!store) return;

    /* Bad CRL encoding type */
    ret = CertAddEncodedCRLToStore(0, 0, NULL, 0, 0, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
157
     "Expected E_INVALIDARG, got %08x\n", GetLastError());
158 159
    ret = CertAddEncodedCRLToStore(store, 0, NULL, 0, 0, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
160
     "Expected E_INVALIDARG, got %08x\n", GetLastError());
161 162
    ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL), 0, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
163
     "Expected E_INVALIDARG, got %08x\n", GetLastError());
164 165 166
    ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL), 0,
     NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
167
     "Expected E_INVALIDARG, got %08x\n", GetLastError());
168 169 170
    ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL),
     CERT_STORE_ADD_ALWAYS, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
171
     "Expected E_INVALIDARG, got %08x\n", GetLastError());
172 173 174
    ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL),
     CERT_STORE_ADD_ALWAYS, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
175
     "Expected E_INVALIDARG, got %08x\n", GetLastError());
176 177 178

    /* No CRL */
    ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, NULL, 0, 0, NULL);
Juan Lang's avatar
Juan Lang committed
179 180 181
    GLE = GetLastError();
    ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
     "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
182
    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, NULL, 0, 0, NULL);
Juan Lang's avatar
Juan Lang committed
183 184 185
    GLE = GetLastError();
    ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
     "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
186

187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
    /* Weird--bad add disposition leads to an access violation in Windows.
     * Both tests crash on some win9x boxes.
     */
    if (0)
    {
        ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
         sizeof(signedCRL), 0, NULL);
        ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
                    GetLastError() == E_INVALIDARG /* Vista */),
         "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n", GetLastError());
        ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
         sizeof(signedCRL), 0, NULL);
        ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
                    GetLastError() == E_INVALIDARG /* Vista */),
         "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n", GetLastError());
    }
203 204 205 206 207 208

    /* Weird--can add a CRL to the NULL store (does this have special meaning?)
     */
    context = NULL;
    ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &context);
209
    ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
210 211 212 213 214 215
    if (context)
        CertFreeCRLContext(context);

    /* Normal cases: a "signed" CRL is okay.. */
    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
216
    ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
217 218 219
    /* and an unsigned one is too. */
    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, CRL, sizeof(CRL),
     CERT_STORE_ADD_ALWAYS, NULL);
220
    ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
221 222 223 224

    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
     sizeof(newerCRL), CERT_STORE_ADD_NEW, NULL);
    ok(!ret && GetLastError() == CRYPT_E_EXISTS,
225
     "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
226 227 228 229

    /* This should replace (one of) the existing CRL(s). */
    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
     sizeof(newerCRL), CERT_STORE_ADD_NEWER, NULL);
230
    ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
231 232

    CertCloseStore(store, 0);
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250

    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
    ok(store != NULL, "CertOpenStore failed\n");

    context = CertCreateCRLContext(X509_ASN_ENCODING, CRL, sizeof(CRL));
    ok(context != NULL, "CertCreateCRLContext failed\n");

    ret = CertAddCRLContextToStore(store, context, CERT_STORE_ADD_NEW, &context2);
    ok(ret, "CertAddCRLContextToStore failed\n");
    ok(context2 != NULL && context2 != context, "unexpected context2\n");

    ok(context->pbCrlEncoded != context2->pbCrlEncoded, "Unexpected pbCrlEncoded\n");
    ok(context->cbCrlEncoded == context2->cbCrlEncoded, "Unexpected cbCrlEncoded\n");
    ok(context->pCrlInfo != context2->pCrlInfo, "Unexpected pCrlInfo\n");

    CertFreeCRLContext(context2);
    CertFreeCRLContext(context);
    CertCloseStore(store, 0);
251 252
}

253 254 255 256 257 258
static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
259 260 261 262 263 264 265 266 267
static const BYTE v2CRLWithIssuingDistPoint[] = {
0x30,0x70,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x27,
0x30,0x25,0x30,0x23,0x06,0x03,0x55,0x1d,0x1c,0x01,0x01,0xff,0x04,0x19,0x30,
0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
 0xcd };
static const BYTE verisignCommercialSoftPubCA[] = {
0x30,0x82,0x02,0x40,0x30,0x82,0x01,0xa9,0x02,0x10,0x03,0xc7,0x8f,0x37,0xdb,0x92,
0x28,0xdf,0x3c,0xbb,0x1a,0xad,0x82,0xfa,0x67,0x10,0x30,0x0d,0x06,0x09,0x2a,0x86,
0x48,0x86,0xf7,0x0d,0x01,0x01,0x02,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,0x17,
0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,0x55,0x04,0x0b,
0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6f,0x6d,0x6d,0x65,
0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x50,
0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,
0x39,0x36,0x30,0x34,0x30,0x39,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,
0x34,0x30,0x31,0x30,0x37,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x61,0x31,0x11,
0x30,0x0f,0x06,0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,
0x74,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,
0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6f,
0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,
0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,0x43,0x41,0x30,
0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xc3,0xd3,0x69,0x65,
0x52,0x01,0x94,0x54,0xab,0x28,0xc6,0x62,0x18,0xb3,0x54,0x55,0xc5,0x44,0x87,0x45,
0x4a,0x3b,0xc2,0x7e,0xd8,0xd3,0xd7,0xc8,0x80,0x86,0x8d,0xd8,0x0c,0xf1,0x16,0x9c,
0xcc,0x6b,0xa9,0x29,0xb2,0x8f,0x76,0x73,0x92,0xc8,0xc5,0x62,0xa6,0x3c,0xed,0x1e,
0x05,0x75,0xf0,0x13,0x00,0x6c,0x14,0x4d,0xd4,0x98,0x90,0x07,0xbe,0x69,0x73,0x81,
0xb8,0x62,0x4e,0x31,0x1e,0xd1,0xfc,0xc9,0x0c,0xeb,0x7d,0x90,0xbf,0xae,0xb4,0x47,
0x51,0xec,0x6f,0xce,0x64,0x35,0x02,0xd6,0x7d,0x67,0x05,0x77,0xe2,0x8f,0xd9,0x51,
0xd7,0xfb,0x97,0x19,0xbc,0x3e,0xd7,0x77,0x81,0xc6,0x43,0xdd,0xf2,0xdd,0xdf,0xca,
0xa3,0x83,0x8b,0xcb,0x41,0xc1,0x3d,0x22,0x48,0x48,0xa6,0x19,0x02,0x03,0x01,0x00,
0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x02,0x05,0x00,
0x03,0x81,0x81,0x00,0xb5,0xbc,0xb0,0x75,0x6a,0x89,0xa2,0x86,0xbd,0x64,0x78,0xc3,
0xa7,0x32,0x75,0x72,0x11,0xaa,0x26,0x02,0x17,0x60,0x30,0x4c,0xe3,0x48,0x34,0x19,
0xb9,0x52,0x4a,0x51,0x18,0x80,0xfe,0x53,0x2d,0x7b,0xd5,0x31,0x8c,0xc5,0x65,0x99,
0x41,0x41,0x2f,0xf2,0xae,0x63,0x7a,0xe8,0x73,0x99,0x15,0x90,0x1a,0x1f,0x7a,0x8b,
0x41,0xd0,0x8e,0x3a,0xd0,0xcd,0x38,0x34,0x44,0xd0,0x75,0xf8,0xea,0x71,0xc4,0x81,
0x19,0x38,0x17,0x35,0x4a,0xae,0xc5,0x3e,0x32,0xe6,0x21,0xb8,0x05,0xc0,0x93,0xe1,
0xc7,0x38,0x5c,0xd8,0xf7,0x93,0x38,0x64,0x90,0xed,0x54,0xce,0xca,0xd3,0xd3,0xd0,
0x5f,0xef,0x04,0x9b,0xde,0x02,0x82,0xdd,0x88,0x29,0xb1,0xc3,0x4f,0xa5,0xcd,0x71,
0x64,0x31,0x3c,0x3c
};
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
static const BYTE rootWithKeySignAndCRLSign[] = {
0x30,0x82,0x01,0xdf,0x30,0x82,0x01,0x4c,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
0x5b,0xc7,0x0b,0x27,0x99,0xbb,0x2e,0x99,0x47,0x9d,0x45,0x4e,0x7c,0x1a,0xca,
0xe8,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
0x00,0x01,0xa3,0x42,0x30,0x40,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,
0xff,0x04,0x04,0x03,0x02,0x00,0x06,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,
0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d,
0x0e,0x04,0x16,0x04,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0,
0x58,0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x09,0x06,0x05,0x2b,
0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,0x81,0x00,0x74,0xcb,0x21,0xfd,0x2d,
0x25,0xdc,0xa5,0xaa,0xa1,0x26,0xdc,0x8b,0x40,0x11,0x64,0xae,0x5c,0x71,0x3c,
0x28,0xbc,0xf9,0xb3,0xcb,0xa5,0x94,0xb2,0x8d,0x4c,0x23,0x2b,0x9b,0xde,0x2c,
0x4c,0x30,0x04,0xc6,0x88,0x10,0x2f,0x53,0xfd,0x6c,0x82,0xf1,0x13,0xfb,0xda,
0x27,0x75,0x25,0x48,0xe4,0x72,0x09,0x2a,0xee,0xb4,0x1e,0xc9,0x55,0xf5,0xf7,
0x82,0x91,0xd8,0x4b,0xe4,0x3a,0xfe,0x97,0x87,0xdf,0xfb,0x15,0x5a,0x12,0x3e,
0x12,0xe6,0xad,0x40,0x0b,0xcf,0xee,0x1a,0x44,0xe0,0x83,0xb2,0x67,0x94,0xd4,
0x2e,0x7c,0xf2,0x06,0x9d,0xb3,0x3b,0x7e,0x2f,0xda,0x25,0x66,0x7e,0xa7,0x1f,
0x45,0xd4,0xf5,0xe3,0xdf,0x2a,0xf1,0x18,0x28,0x20,0xb5,0xf8,0xf5,0x8d,0x7a,
0x2e,0x84,0xee };
static const BYTE eeCert[] = {
0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,
0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30,0x30,
0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30,0x30,
0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,
0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,
0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,
0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,
0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,
0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,
0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,
0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,
0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,
0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,
0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,
0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,
0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x22,0xf1,0x66,0x00,0x79,0xd2,
0xe6,0xb2,0xb2,0xf7,0x2f,0x98,0x92,0x7d,0x73,0xc3,0x6c,0x5c,0x77,0x20,0xe3,
0xbf,0x3e,0xe0,0xb3,0x5c,0x68,0xb4,0x9b,0x3a,0x41,0xae,0x94,0xa0,0x80,0x3a,
0xfe,0x5d,0x7a,0x56,0x87,0x85,0x44,0x45,0xcf,0xa6,0xd3,0x10,0xe7,0x73,0x41,
0xf2,0x7f,0x88,0x85,0x91,0x8e,0xe6,0xec,0xe2,0xce,0x08,0xbc,0xa5,0x76,0xe5,
0x4d,0x1d,0xb7,0x70,0x31,0xdd,0xc9,0x9a,0x15,0x32,0x11,0x5a,0x4e,0x62,0xc8,
0xd1,0xf8,0xec,0x46,0x39,0x5b,0xe7,0x67,0x1f,0x58,0xe8,0xa1,0xa0,0x5b,0xf7,
0x8a,0x6d,0x5f,0x91,0x18,0xd4,0x90,0x85,0xff,0x30,0xc7,0xca,0x9c,0xc6,0x92,
0xb0,0xca,0x16,0xc4,0xa4,0xc0,0xd6,0xe8,0xff,0x15,0x19,0xd1,0x30,0x61,0xf3,
0xef,0x9f };
static const BYTE rootSignedCRL[] = {
0x30,0x82,0x01,0x1d,0x30,0x81,0x87,0x02,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a,
0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x10,0x31,0x0e,0x30,
0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x17,0x0d,
0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x14,
0x30,0x12,0x02,0x01,0x01,0x17,0x0d,0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,
0x30,0x30,0x30,0x30,0x5a,0xa0,0x2d,0x30,0x2b,0x30,0x0a,0x06,0x03,0x55,0x1d,
0x14,0x04,0x03,0x02,0x01,0x01,0x30,0x1d,0x06,0x03,0x55,0x1d,0x23,0x04,0x16,
0x04,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0,0x58,0xff,0x98,
0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9b,0x2b,0x99,0x0d,
0x16,0x83,0x93,0x54,0x29,0x3a,0xa6,0x53,0x5d,0xf8,0xa6,0x73,0x9f,0x2a,0x45,
0x39,0x91,0xff,0x91,0x1c,0x27,0x06,0xe8,0xdb,0x72,0x3f,0x66,0x89,0x15,0x68,
0x55,0xd5,0x49,0x63,0xa6,0x00,0xe9,0x66,0x9c,0x97,0xf9,0xb3,0xb3,0x2b,0x1b,
0xc7,0x79,0x46,0xa8,0xd8,0x2b,0x78,0x27,0xa0,0x70,0x02,0x81,0xc6,0x40,0xb3,
0x76,0x32,0x65,0x4c,0xf8,0xff,0x1d,0x41,0x6e,0x16,0x09,0xa2,0x8a,0x7b,0x0c,
0xd0,0xa6,0x9b,0x61,0xa3,0x7c,0x02,0x91,0x79,0xdf,0x6a,0x5e,0x88,0x95,0x66,
0x33,0x17,0xcb,0x5a,0xd2,0xdc,0x89,0x05,0x62,0x97,0x60,0x73,0x7b,0x2c,0x1a,
0x90,0x20,0x73,0x24,0x9f,0x45,0x22,0x4b,0xc1,0x33,0xd1,0xda,0xd8,0x7e,0x1b,
0x3d,0x74,0xd6,0x3b };
426

427 428
static void testFindCRL(void)
{
429
    HCERTSTORE store;
430
    PCCRL_CONTEXT context;
431
    PCCERT_CONTEXT cert, endCert, rootCert;
432 433
    CRL_FIND_ISSUED_FOR_PARA issuedForPara = { NULL, NULL };
    DWORD count, revoked_count;
434 435
    BOOL ret;

436
    if (!pCertFindCRLInStore || !pCertFindCertificateInCRL)
437
    {
438
        win_skip("CertFindCRLInStore or CertFindCertificateInCRL not available\n");
439 440
        return;
    }
441

442 443 444 445 446
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
                          CERT_STORE_CREATE_NEW_FLAG, NULL);
    ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
    if (!store) return;

447 448
    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
449
    ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
450 451

    /* Crashes
452
    context = pCertFindCRLInStore(NULL, 0, 0, 0, NULL, NULL);
453 454 455
     */

    /* Find any context */
456
    context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ANY, NULL, NULL);
457 458 459 460
    ok(context != NULL, "Expected a context\n");
    if (context)
        CertFreeCRLContext(context);
    /* Bogus flags are ignored */
461
    context = pCertFindCRLInStore(store, 0, 1234, CRL_FIND_ANY, NULL, NULL);
462 463 464 465
    ok(context != NULL, "Expected a context\n");
    if (context)
        CertFreeCRLContext(context);
    /* CRL encoding type is ignored too */
466
    context = pCertFindCRLInStore(store, 1234, 0, CRL_FIND_ANY, NULL, NULL);
467 468 469 470 471
    ok(context != NULL, "Expected a context\n");
    if (context)
        CertFreeCRLContext(context);

    /* This appears to match any cert */
472
    context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, NULL, NULL);
473 474 475 476 477 478 479
    ok(context != NULL, "Expected a context\n");
    if (context)
        CertFreeCRLContext(context);

    /* Try to match an issuer that isn't in the store */
    cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
     sizeof(bigCert2));
480
    ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
481
     GetLastError());
482
    context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
483 484 485 486 487 488
    ok(context == NULL, "Expected no matching context\n");
    CertFreeCertificateContext(cert);

    /* Match an issuer that is in the store */
    cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
     sizeof(bigCert));
489
    ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
490
     GetLastError());
491
    context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
492 493 494
    ok(context != NULL, "Expected a context\n");
    if (context)
        CertFreeCRLContext(context);
495

496 497 498
    /* Try various find flags */
    context = pCertFindCRLInStore(store, 0, CRL_FIND_ISSUED_BY_SIGNATURE_FLAG,
     CRL_FIND_ISSUED_BY, cert, NULL);
499
    ok(!context || broken(context != NULL /* Win9x */), "unexpected context\n");
500 501 502 503 504 505 506
    /* The CRL doesn't have an AKI extension, so it matches any cert */
    context = pCertFindCRLInStore(store, 0, CRL_FIND_ISSUED_BY_AKI_FLAG,
     CRL_FIND_ISSUED_BY, cert, NULL);
    ok(context != NULL, "Expected a context\n");
    if (context)
        CertFreeCRLContext(context);

507 508 509
    if (0)
    {
        /* Crash or return NULL/STATUS_ACCESS_VIOLATION */
510
        pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR, NULL,
511
         NULL);
512
        pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
513 514 515 516 517 518 519
         &issuedForPara, NULL);
    }
    /* Test whether the cert matches the CRL in the store */
    issuedForPara.pSubjectCert = cert;
    issuedForPara.pIssuerCert = cert;
    context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
     &issuedForPara, NULL);
520 521
    ok(context != NULL || broken(!context /* Win9x, NT4 */),
     "Expected a context\n");
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
    if (context)
    {
        ok(context->cbCrlEncoded == sizeof(signedCRL),
         "unexpected CRL size %d\n", context->cbCrlEncoded);
        ok(!memcmp(context->pbCrlEncoded, signedCRL, context->cbCrlEncoded),
         "unexpected CRL data\n");
        CertFreeCRLContext(context);
    }

    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
     v1CRLWithIssuerAndEntry, sizeof(v1CRLWithIssuerAndEntry),
     CERT_STORE_ADD_ALWAYS, NULL);
    ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
     v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
     CERT_STORE_ADD_ALWAYS, NULL);
    ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
     verisignCRL, sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, NULL);
    ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
    issuedForPara.pSubjectCert = cert;
    issuedForPara.pIssuerCert = cert;
    context = NULL;
    count = revoked_count = 0;
    do {
        context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
         &issuedForPara, context);
        if (context)
        {
            PCRL_ENTRY entry;

            count++;
554
            if (pCertFindCertificateInCRL(cert, context, 0, NULL, &entry) &&
555 556 557 558 559 560 561 562
             entry)
                revoked_count++;
        }
    } while (context);
    /* signedCRL, v1CRLWithIssuerAndEntry, and v2CRLWithIssuingDistPoint all
     * match cert's issuer, but verisignCRL does not, so the expected count
     * is 0.
     */
563 564
    ok(count == 3 || broken(count == 0 /* NT4, Win9x */),
     "expected 3 matching CRLs, got %d\n", count);
565 566 567
    /* Only v1CRLWithIssuerAndEntry and v2CRLWithIssuingDistPoint contain
     * entries, so the count of CRL entries that match cert is 2.
     */
568 569
    ok(revoked_count == 2 || broken(revoked_count == 0 /* NT4, Win9x */),
     "expected 2 matching CRL entries, got %d\n", revoked_count);
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589

    CertFreeCertificateContext(cert);

    /* Try again with a cert that doesn't match any CRLs in the store */
    cert = CertCreateCertificateContext(X509_ASN_ENCODING,
     bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer));
    ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
     GetLastError());
    issuedForPara.pSubjectCert = cert;
    issuedForPara.pIssuerCert = cert;
    context = NULL;
    count = revoked_count = 0;
    do {
        context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
         &issuedForPara, context);
        if (context)
        {
            PCRL_ENTRY entry;

            count++;
590
            if (pCertFindCertificateInCRL(cert, context, 0, NULL, &entry) &&
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618
             entry)
                revoked_count++;
        }
    } while (context);
    ok(count == 0, "expected 0 matching CRLs, got %d\n", count);
    ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
     revoked_count);
    CertFreeCertificateContext(cert);

    /* Test again with a real certificate and CRL.  The certificate wasn't
     * revoked, but its issuer does have a CRL.
     */
    cert = CertCreateCertificateContext(X509_ASN_ENCODING,
     verisignCommercialSoftPubCA, sizeof(verisignCommercialSoftPubCA));
    ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
     GetLastError());
    issuedForPara.pIssuerCert = cert;
    issuedForPara.pSubjectCert = cert;
    context = NULL;
    count = revoked_count = 0;
    do {
        context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
         &issuedForPara, context);
        if (context)
        {
            PCRL_ENTRY entry;

            count++;
619
            if (pCertFindCertificateInCRL(cert, context, 0, NULL, &entry) &&
620 621 622 623
             entry)
                revoked_count++;
        }
    } while (context);
624 625
    ok(count == 1 || broken(count == 0 /* Win9x, NT4 */),
     "expected 1 matching CRLs, got %d\n", count);
626 627
    ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
     revoked_count);
628 629 630
    CertFreeCertificateContext(cert);

    CertCloseStore(store, 0);
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658

    /* This test uses a synthesized chain (rootWithKeySignAndCRLSign ->
     * eeCert) whose end certificate is in the CRL.
     */
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    /* Add a CRL for the end certificate */
    CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
     rootSignedCRL, sizeof(rootSignedCRL), CERT_STORE_ADD_ALWAYS, NULL);
    /* Add another CRL unrelated to the tested chain */
    CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
     verisignCRL, sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, NULL);
    endCert = CertCreateCertificateContext(X509_ASN_ENCODING,
     eeCert, sizeof(eeCert));
    rootCert = CertCreateCertificateContext(X509_ASN_ENCODING,
     rootWithKeySignAndCRLSign, sizeof(rootWithKeySignAndCRLSign));
    issuedForPara.pSubjectCert = endCert;
    issuedForPara.pIssuerCert = rootCert;
    context = NULL;
    count = revoked_count = 0;
    do {
        context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
         &issuedForPara, context);
        if (context)
        {
            PCRL_ENTRY entry;

            count++;
659
            if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
660 661 662 663
             entry)
                revoked_count++;
        }
    } while (context);
664 665 666 667
    ok(count == 1 || broken(count == 0 /* Win9x, NT4 */),
     "expected 1 matching CRLs, got %d\n", count);
    ok(revoked_count == 1 || broken(revoked_count == 0 /* Win9x, NT4 */),
     "expected 1 matching CRL entries, got %d\n", revoked_count);
668 669 670 671 672 673 674 675 676 677 678

    /* Test CRL_FIND_ISSUED_BY flags */
    count = revoked_count = 0;
    do {
        context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY,
         endCert, context);
        if (context)
        {
            PCRL_ENTRY entry;

            count++;
679
            if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695
             entry)
                revoked_count++;
        }
    } while (context);
    ok(count == 0, "expected 0 matching CRLs, got %d\n", count);
    ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
     revoked_count);
    count = revoked_count = 0;
    do {
        context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY,
         rootCert, context);
        if (context)
        {
            PCRL_ENTRY entry;

            count++;
696
            if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
             entry)
                revoked_count++;
        }
    } while (context);
    ok(count == 1, "expected 1 matching CRLs, got %d\n", count);
    ok(revoked_count == 1, "expected 1 matching CRL entries, got %d\n",
     revoked_count);
    count = revoked_count = 0;
    do {
        context = pCertFindCRLInStore(store, 0, CRL_FIND_ISSUED_BY_AKI_FLAG,
         CRL_FIND_ISSUED_BY, endCert, context);
        if (context)
        {
            PCRL_ENTRY entry;

            count++;
713
            if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729
             entry)
                revoked_count++;
        }
    } while (context);
    ok(count == 0, "expected 0 matching CRLs, got %d\n", count);
    ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
     revoked_count);
    count = revoked_count = 0;
    do {
        context = pCertFindCRLInStore(store, 0, CRL_FIND_ISSUED_BY_AKI_FLAG,
         CRL_FIND_ISSUED_BY, rootCert, context);
        if (context)
        {
            PCRL_ENTRY entry;

            count++;
730
            if (pCertFindCertificateInCRL(rootCert, context, 0, NULL, &entry) &&
731 732 733 734
             entry)
                revoked_count++;
        }
    } while (context);
735
    ok(count == 0 || broken(count == 1 /* Win9x */),
Juan Lang's avatar
Juan Lang committed
736
     "expected 0 matching CRLs, got %d\n", count);
737 738 739 740 741 742 743 744 745 746 747 748
    ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
     revoked_count);
    count = revoked_count = 0;
    do {
        context = pCertFindCRLInStore(store, 0,
         CRL_FIND_ISSUED_BY_SIGNATURE_FLAG, CRL_FIND_ISSUED_BY, endCert,
         context);
        if (context)
        {
            PCRL_ENTRY entry;

            count++;
749
            if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
             entry)
                revoked_count++;
        }
    } while (context);
    ok(count == 0, "expected 0 matching CRLs, got %d\n", count);
    ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
     revoked_count);
    count = revoked_count = 0;
    do {
        context = pCertFindCRLInStore(store, 0,
         CRL_FIND_ISSUED_BY_SIGNATURE_FLAG, CRL_FIND_ISSUED_BY, rootCert,
         context);
        if (context)
        {
            PCRL_ENTRY entry;

            count++;
767
            if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
768 769 770 771 772 773 774 775 776 777 778
             entry)
                revoked_count++;
        }
    } while (context);
    ok(count == 1, "expected 1 matching CRLs, got %d\n", count);
    ok(revoked_count == 1, "expected 1 matching CRL entries, got %d\n",
     revoked_count);
    CertFreeCertificateContext(rootCert);
    CertFreeCertificateContext(endCert);

    CertCloseStore(store, 0);
779 780
}

781 782 783 784 785 786 787 788 789
static void testGetCRLFromStore(void)
{
    HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    PCCRL_CONTEXT context;
    PCCERT_CONTEXT cert;
    DWORD flags;
    BOOL ret;

790
    ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
791 792 793 794 795 796 797 798 799 800 801
    if (!store) return;

    /* Crash
    context = CertGetCRLFromStore(NULL, NULL, NULL, NULL);
    context = CertGetCRLFromStore(store, NULL, NULL, NULL);
     */

    /* Bogus flags */
    flags = 0xffffffff;
    context = CertGetCRLFromStore(store, NULL, NULL, &flags);
    ok(!context && GetLastError() == E_INVALIDARG,
802
     "Expected E_INVALIDARG, got %08x\n", GetLastError());
803 804 805 806 807

    /* Test an empty store */
    flags = 0;
    context = CertGetCRLFromStore(store, NULL, NULL, &flags);
    ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
808
     "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
809 810 811

    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
812
    ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
813 814 815 816 817 818 819 820 821 822

    /* NULL matches any CRL */
    flags = 0;
    context = CertGetCRLFromStore(store, NULL, NULL, &flags);
    ok(context != NULL, "Expected a context\n");
    CertFreeCRLContext(context);

    /* This cert's issuer isn't in */
    cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
     sizeof(bigCert2));
823
    ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
824 825 826
     GetLastError());
    context = CertGetCRLFromStore(store, cert, NULL, &flags);
    ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
827
     "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
828 829 830 831 832
    CertFreeCertificateContext(cert);

    /* But this one is */
    cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
     sizeof(bigCert));
833
    ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
834 835 836 837 838 839 840 841 842
     GetLastError());
    context = CertGetCRLFromStore(store, cert, NULL, &flags);
    ok(context != NULL, "Expected a context\n");
    CertFreeCRLContext(context);
    CertFreeCertificateContext(cert);

    CertCloseStore(store, 0);
}

843 844 845 846 847 848 849 850 851 852 853
static void checkCRLHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
 PCCRL_CONTEXT context, DWORD propID)
{
    BYTE hash[20] = { 0 }, hashProperty[20];
    BOOL ret;
    DWORD size;

    memset(hash, 0, sizeof(hash));
    memset(hashProperty, 0, sizeof(hashProperty));
    size = sizeof(hash);
    ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
854
    ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
855
    ret = CertGetCRLContextProperty(context, propID, hashProperty, &size);
856 857
    ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
    ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
858 859 860 861 862 863 864 865
     propID);
}

static void testCRLProperties(void)
{
    PCCRL_CONTEXT context = CertCreateCRLContext(X509_ASN_ENCODING,
     CRL, sizeof(CRL));

866
    ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
    if (context)
    {
        DWORD propID, numProps, access, size;
        BOOL ret;
        BYTE hash[20] = { 0 }, hashProperty[20];
        CRYPT_DATA_BLOB blob;

        /* This crashes
        propID = CertEnumCRLContextProperties(NULL, 0);
         */

        propID = 0;
        numProps = 0;
        do {
            propID = CertEnumCRLContextProperties(context, propID);
            if (propID)
                numProps++;
        } while (propID != 0);
885
        ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
886 887 888 889

        /* Tests with a NULL cert context.  Prop ID 0 fails.. */
        ret = CertSetCRLContextProperty(NULL, 0, 0, NULL);
        ok(!ret && GetLastError() == E_INVALIDARG,
890
         "Expected E_INVALIDARG, got %08x\n", GetLastError());
891 892 893 894 895 896 897
        /* while this just crashes.
        ret = CertSetCRLContextProperty(NULL, CERT_KEY_PROV_HANDLE_PROP_ID, 0,
         NULL);
         */

        ret = CertSetCRLContextProperty(context, 0, 0, NULL);
        ok(!ret && GetLastError() == E_INVALIDARG,
898
         "Expected E_INVALIDARG, got %08x\n", GetLastError());
899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914
        /* Can't set the cert property directly, this crashes.
        ret = CertSetCRLContextProperty(context, CERT_CRL_PROP_ID, 0, CRL);
         */

        /* These all crash.
        ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
         NULL);
        ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, NULL, NULL);
        ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, 
         hashProperty, NULL);
         */
        /* A missing prop */
        size = 0;
        ret = CertGetCRLContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID,
         NULL, &size);
        ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
915
         "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
916 917 918
        /* And, an implicit property */
        ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
         NULL, &size);
919
        ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
920 921
        ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
         &access, &size);
922
        ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
923 924 925 926 927 928 929 930 931 932 933 934
        ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
         "Didn't expect a persisted crl\n");
        /* Trying to set this "read only" property crashes.
        access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
        ret = CertSetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
         &access);
         */

        /* Can I set the hash to an invalid hash? */
        blob.pbData = hash;
        blob.cbData = sizeof(hash);
        ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, &blob);
935
        ok(ret, "CertSetCRLContextProperty failed: %08x\n",
936 937 938 939
         GetLastError());
        size = sizeof(hashProperty);
        ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
         hashProperty, &size);
940
        ok(ret, "CertSetCRLContextProperty failed: %08x\n", GetLastError());
941 942 943
        ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
        /* Delete the (bogus) hash, and get the real one */
        ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, NULL);
944
        ok(ret, "CertSetCRLContextProperty failed: %08x\n", GetLastError());
945 946 947 948 949 950 951 952 953 954 955 956
        checkCRLHash(CRL, sizeof(CRL), CALG_SHA1, context, CERT_HASH_PROP_ID);

        /* Now that the hash property is set, we should get one property when
         * enumerating.
         */
        propID = 0;
        numProps = 0;
        do {
            propID = CertEnumCRLContextProperties(context, propID);
            if (propID)
                numProps++;
        } while (propID != 0);
957
        ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
958 959 960 961 962 963 964 965 966

        /* Check a few other implicit properties */
        checkCRLHash(CRL, sizeof(CRL), CALG_MD5, context,
         CERT_MD5_HASH_PROP_ID);

        CertFreeCRLContext(context);
    }
}

967 968 969 970 971 972 973 974 975 976 977 978 979 980
static const BYTE bigCertWithCRLDistPoints[] = {
0x30,0x81,0xa5,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x26,0x30,0x24,0x30,0x22,0x06,
0x03,0x55,0x1d,0x1f,0x04,0x1b,0x30,0x19,0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,
0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
0x6f,0x72,0x67 };

981 982 983
static void testIsValidCRLForCert(void)
{
    BOOL ret;
984
    PCCERT_CONTEXT cert1, cert2, cert3;
985 986 987
    PCCRL_CONTEXT crl;
    HCERTSTORE store;

988 989
    if(!pCertIsValidCRLForCertificate) return;

990 991
    crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
     sizeof(v1CRLWithIssuerAndEntry));
992
    ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
993 994
    cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
     sizeof(bigCert));
995
    ok(cert1 != NULL, "CertCreateCertificateContext failed: %08x\n",
996 997 998 999 1000 1001 1002 1003
     GetLastError());

    /* Crash
    ret = CertIsValidCRLForCertificate(NULL, NULL, 0, NULL);
    ret = CertIsValidCRLForCertificate(cert1, NULL, 0, NULL);
     */

    /* Curiously, any CRL is valid for the NULL certificate */
1004
    ret = pCertIsValidCRLForCertificate(NULL, crl, 0, NULL);
1005
    ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1006 1007

    /* Same issuer for both cert and CRL, this CRL is valid for that cert */
1008
    ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
1009
    ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1010 1011 1012

    cert2 = CertCreateCertificateContext(X509_ASN_ENCODING,
     bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer));
1013
    ok(cert2 != NULL, "CertCreateCertificateContext failed: %08x\n",
1014 1015 1016 1017 1018 1019
     GetLastError());

    /* Yet more curious: different issuers for these, yet the CRL is valid for
     * that cert.  According to MSDN, the relevant bit to check is whether the
     * CRL has a CRL_ISSUING_DIST_POINT extension.
     */
1020
    ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
1021
    ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1022 1023 1024

    CertFreeCRLContext(crl);

1025 1026
    /* With a CRL_ISSUING_DIST_POINT in the CRL, it returns FALSE, since the
     * cert doesn't have the same extension in it.
1027 1028 1029
     */
    crl = CertCreateCRLContext(X509_ASN_ENCODING, v2CRLWithIssuingDistPoint,
     sizeof(v2CRLWithIssuingDistPoint));
1030
    ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
1031

1032
    ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
1033 1034
    ok(!ret && GetLastError() == CRYPT_E_NO_MATCH,
     "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
1035
    ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
    ok(!ret && GetLastError() == CRYPT_E_NO_MATCH,
     "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());

    /* With a CRL_ISSUING_DIST_POINT in the CRL, it matches the cert containing
     * a CRL_DIST_POINTS_INFO extension.
     */
    cert3 = CertCreateCertificateContext(X509_ASN_ENCODING,
     bigCertWithCRLDistPoints, sizeof(bigCertWithCRLDistPoints));
    ok(cert3 != NULL, "CertCreateCertificateContext failed: %08x\n",
     GetLastError());
    ret = pCertIsValidCRLForCertificate(cert3, crl, 0, NULL);
1047
    ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1048 1049 1050

    CertFreeCRLContext(crl);

1051
    /* And again, with a real CRL, the CRL is valid for all three certs. */
1052 1053
    crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
     sizeof(verisignCRL));
1054
    ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
1055

1056
    ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
1057
    ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1058
    ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
1059
    ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1060 1061
    ret = pCertIsValidCRLForCertificate(cert3, crl, 0, NULL);
    ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1062 1063 1064 1065

    CertFreeCRLContext(crl);

    /* One last test: a CRL in a different store than the cert is also valid
1066
     * for the cert.
1067 1068 1069
     */
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
1070
    ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1071 1072 1073

    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, verisignCRL,
     sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, &crl);
1074
    ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
1075

1076
    ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
1077
    ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1078
    ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
1079
    ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1080 1081
    ret = pCertIsValidCRLForCertificate(cert3, crl, 0, NULL);
    ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1082 1083 1084 1085 1086

    CertFreeCRLContext(crl);

    CertCloseStore(store, 0);

1087
    CertFreeCertificateContext(cert3);
1088 1089 1090 1091
    CertFreeCertificateContext(cert2);
    CertFreeCertificateContext(cert1);
}

1092 1093 1094 1095 1096 1097 1098
static const BYTE crlWithDifferentIssuer[] = {
 0x30,0x47,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x41,0x6c,0x65,0x78,0x20,0x4c,0x61,0x6e,
 0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
 0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a };

1099 1100 1101 1102 1103 1104 1105
static void testFindCertInCRL(void)
{
    BOOL ret;
    PCCERT_CONTEXT cert;
    PCCRL_CONTEXT crl;
    PCRL_ENTRY entry;

1106 1107
    if (!pCertFindCertificateInCRL)
    {
1108
        win_skip("CertFindCertificateInCRL() is not available\n");
1109 1110 1111
        return;
    }

1112 1113
    cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
     sizeof(bigCert));
1114
    ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
1115 1116 1117
     GetLastError());

    /* Crash
1118 1119 1120 1121 1122 1123 1124
    ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, NULL);
    ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, NULL);
    ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, NULL);
    ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, NULL);
    ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, &entry);
    ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, &entry);
    ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, &entry);
1125 1126 1127 1128
     */

    crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
     sizeof(verisignCRL));
1129
    ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
1130
    ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
1131 1132 1133 1134 1135
    ok(entry == NULL, "Expected not to find an entry in CRL\n");
    CertFreeCRLContext(crl);

    crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
     sizeof(v1CRLWithIssuerAndEntry));
1136
    ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
1137
    ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
1138 1139 1140
    ok(entry != NULL, "Expected to find an entry in CRL\n");
    CertFreeCRLContext(crl);

1141 1142 1143
    /* Entry found even though CRL issuer doesn't match cert issuer */
    crl = CertCreateCRLContext(X509_ASN_ENCODING, crlWithDifferentIssuer,
     sizeof(crlWithDifferentIssuer));
1144
    ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
1145
    ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
1146 1147 1148
    ok(entry != NULL, "Expected to find an entry in CRL\n");
    CertFreeCRLContext(crl);

1149 1150 1151 1152 1153 1154 1155 1156 1157 1158
    CertFreeCertificateContext(cert);
}

static void testVerifyCRLRevocation(void)
{
    BOOL ret;
    PCCERT_CONTEXT cert;
    PCCRL_CONTEXT crl;

    ret = CertVerifyCRLRevocation(0, NULL, 0, NULL);
1159
    ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1160
    ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, NULL, 0, NULL);
1161
    ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1162 1163 1164 1165 1166 1167

    cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
     sizeof(bigCert));

    /* Check against no CRL */
    ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 0, NULL);
1168
    ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1169
    ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 0, NULL);
1170
    ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182

    /* Check against CRL with entry for the cert */
    crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
     sizeof(v1CRLWithIssuerAndEntry));
    ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
     (PCRL_INFO *)&crl->pCrlInfo);
    ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
    ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
     (PCRL_INFO *)&crl->pCrlInfo);
    ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
    CertFreeCRLContext(crl);

1183
    /* Check against CRL with different issuer and entry for the cert */
Juan Lang's avatar
Juan Lang committed
1184 1185
    crl = CertCreateCRLContext(X509_ASN_ENCODING, crlWithDifferentIssuer,
     sizeof(crlWithDifferentIssuer));
1186
    ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
1187 1188 1189 1190 1191
    ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
     (PCRL_INFO *)&crl->pCrlInfo);
    ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
    CertFreeCRLContext(crl);

1192 1193 1194 1195 1196
    /* Check against CRL without entry for the cert */
    crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
     sizeof(verisignCRL));
    ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
     (PCRL_INFO *)&crl->pCrlInfo);
1197
    ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1198 1199
    ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
     (PCRL_INFO *)&crl->pCrlInfo);
1200
    ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1201 1202 1203 1204 1205
    CertFreeCRLContext(crl);

    CertFreeCertificateContext(cert);
}

1206 1207
START_TEST(crl)
{
1208 1209
    init_function_pointers();

1210
    testCreateCRL();
1211
    testDupCRL();
1212 1213
    testAddCRL();
    testFindCRL();
1214
    testGetCRLFromStore();
1215 1216

    testCRLProperties();
1217 1218 1219 1220

    testIsValidCRLForCert();
    testFindCertInCRL();
    testVerifyCRLRevocation();
1221
}