Пример #1
0
Файл: store.c Проект: devyn/wine
BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
{
    BOOL ret;

    TRACE("(%p)\n", pCrlContext);

    if (!pCrlContext)
        ret = TRUE;
    else if (!pCrlContext->hCertStore)
    {
        ret = TRUE;
        CertFreeCRLContext(pCrlContext);
    }
    else
    {
        PWINECRYPT_CERTSTORE hcs =
         (PWINECRYPT_CERTSTORE)pCrlContext->hCertStore;

        if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
            ret = FALSE;
        else
            ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
        CertFreeCRLContext(pCrlContext);
    }
    return ret;
}
Пример #2
0
static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
{
    WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
    BOOL ret;

    if (ContextList_Remove(ms->crls, pCrlContext))
        ret = CertFreeCRLContext(pCrlContext);
    else
        ret = TRUE;
    return ret;
}
Пример #3
0
PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType,
        const BYTE* pbCrlEncoded, DWORD cbCrlEncoded)
{
    PCRL_CONTEXT crl = NULL;
    BOOL ret;
    PCRL_INFO crlInfo = NULL;
    DWORD size = 0;

    TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCrlEncoded,
          cbCrlEncoded);

    if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
    {
        SetLastError(E_INVALIDARG);
        return NULL;
    }
    ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED,
                              pbCrlEncoded, cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
                              &crlInfo, &size);
    if (ret)
    {
        BYTE *data = NULL;

        crl = Context_CreateDataContext(sizeof(CRL_CONTEXT));
        if (!crl)
            goto end;
        data = CryptMemAlloc(cbCrlEncoded);
        if (!data)
        {
            CertFreeCRLContext(crl);
            crl = NULL;
            goto end;
        }
        memcpy(data, pbCrlEncoded, cbCrlEncoded);
        crl->dwCertEncodingType = dwCertEncodingType;
        crl->pbCrlEncoded       = data;
        crl->cbCrlEncoded       = cbCrlEncoded;
        crl->pCrlInfo           = crlInfo;
        crl->hCertStore         = 0;
    }

end:
    return crl;
}
Пример #4
0
BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore,
 DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded,
 DWORD dwAddDisposition, PCCRL_CONTEXT *ppCrlContext)
{
    PCCRL_CONTEXT crl = CertCreateCRLContext(dwCertEncodingType,
     pbCrlEncoded, cbCrlEncoded);
    BOOL ret;

    TRACE("(%p, %08x, %p, %d, %08x, %p)\n", hCertStore, dwCertEncodingType,
     pbCrlEncoded, cbCrlEncoded, dwAddDisposition, ppCrlContext);

    if (crl)
    {
        ret = CertAddCRLContextToStore(hCertStore, crl, dwAddDisposition,
         ppCrlContext);
        CertFreeCRLContext(crl);
    }
    else
        ret = FALSE;
    return ret;
}
Пример #5
0
static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL use_link)
{
    crl_t *crl;

    if(use_link) {
        crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context, store);
        if(!crl)
            return NULL;
    }else {
        const crl_t *cloned = (const crl_t*)context;
        DWORD size = 0;
        BOOL res;

        crl = (crl_t*)Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, store);
        if(!crl)
            return NULL;

        Context_CopyProperties(&crl->ctx, &cloned->ctx);

        crl->ctx.dwCertEncodingType = cloned->ctx.dwCertEncodingType;
        crl->ctx.pbCrlEncoded = CryptMemAlloc(cloned->ctx.cbCrlEncoded);
        memcpy(crl->ctx.pbCrlEncoded, cloned->ctx.pbCrlEncoded, cloned->ctx.cbCrlEncoded);
        crl->ctx.cbCrlEncoded = cloned->ctx.cbCrlEncoded;

        /* FIXME: We don't need to decode the object here, we could just clone crl info. */
        res = CryptDecodeObjectEx(crl->ctx.dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED,
         crl->ctx.pbCrlEncoded, crl->ctx.cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
         &crl->ctx.pCrlInfo, &size);
        if(!res) {
            CertFreeCRLContext(&crl->ctx);
            return NULL;
        }
    }

    crl->ctx.hCertStore = store;
    return &crl->base;
}
Пример #6
0
BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
 PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
 PCCRL_CONTEXT* ppStoreContext)
{
    PWINECRYPT_CERTSTORE store = hCertStore;
    BOOL ret = TRUE;
    PCCRL_CONTEXT toAdd = NULL, existing = NULL;

    TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
     dwAddDisposition, ppStoreContext);

    /* Weird case to pass a test */
    if (dwAddDisposition == 0)
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        return FALSE;
    }
    if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
    {
        existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
         pCrlContext, NULL);
    }

    switch (dwAddDisposition)
    {
    case CERT_STORE_ADD_ALWAYS:
        toAdd = CertDuplicateCRLContext(pCrlContext);
        break;
    case CERT_STORE_ADD_NEW:
        if (existing)
        {
            TRACE("found matching CRL, not adding\n");
            SetLastError(CRYPT_E_EXISTS);
            ret = FALSE;
        }
        else
            toAdd = CertDuplicateCRLContext(pCrlContext);
        break;
    case CERT_STORE_ADD_NEWER:
        if (existing)
        {
            LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
             &pCrlContext->pCrlInfo->ThisUpdate);

            if (newer < 0)
                toAdd = CertDuplicateCRLContext(pCrlContext);
            else
            {
                TRACE("existing CRL is newer, not adding\n");
                SetLastError(CRYPT_E_EXISTS);
                ret = FALSE;
            }
        }
        else
            toAdd = CertDuplicateCRLContext(pCrlContext);
        break;
    case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
        if (existing)
        {
            LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
             &pCrlContext->pCrlInfo->ThisUpdate);

            if (newer < 0)
            {
                toAdd = CertDuplicateCRLContext(pCrlContext);
                CrlContext_CopyProperties(toAdd, existing);
            }
            else
            {
                TRACE("existing CRL is newer, not adding\n");
                SetLastError(CRYPT_E_EXISTS);
                ret = FALSE;
            }
        }
        else
            toAdd = CertDuplicateCRLContext(pCrlContext);
        break;
    case CERT_STORE_ADD_REPLACE_EXISTING:
        toAdd = CertDuplicateCRLContext(pCrlContext);
        break;
    case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
        toAdd = CertDuplicateCRLContext(pCrlContext);
        if (existing)
            CrlContext_CopyProperties(toAdd, existing);
        break;
    case CERT_STORE_ADD_USE_EXISTING:
        if (existing)
        {
            CrlContext_CopyProperties(existing, pCrlContext);
            if (ppStoreContext)
                *ppStoreContext = CertDuplicateCRLContext(existing);
        }
        else
            toAdd = CertDuplicateCRLContext(pCrlContext);
        break;
    default:
        FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
        ret = FALSE;
    }

    if (toAdd)
    {
        if (store)
            ret = store->crls.addContext(store, (void *)toAdd,
             (void *)existing, (const void **)ppStoreContext);
        else if (ppStoreContext)
            *ppStoreContext = CertDuplicateCRLContext(toAdd);
        CertFreeCRLContext(toAdd);
    }
    CertFreeCRLContext(existing);

    TRACE("returning %d\n", ret);
    return ret;
}
Пример #7
0
static void test_crypt_ui_wiz_import(void)
{
    BOOL ret;
    CRYPTUI_WIZ_IMPORT_SRC_INFO info;
    HCERTSTORE store;
    PCCERT_CONTEXT cert;
    PCCRL_CONTEXT crl;
    DWORD count;

    if (!pCryptUIWizImport)
    {
        skip("No CryptUIWizImport\n");
        return;
    }

    /* Set CBT hook to disallow MessageBox and wizard creation in current
     * thread.
     */
    hook = SetWindowsHookExA(WH_CBT, cbt_hook_proc, 0, GetCurrentThreadId());

    /* Brings up UI.  Cancelling yields ret = 1. */
    if (0)
    {
        pCryptUIWizImport(0, 0, NULL, NULL, NULL);
    }
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, NULL, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    memset(&info, 0, sizeof(info));
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    info.dwSize = sizeof(info);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT;
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    /* Check allowed vs. given type mismatches */
    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertFreeCertificateContext(info.u.pCertContext);
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT;
    info.u.pCRLContext = CertCreateCRLContext(X509_ASN_ENCODING,
     signedCRL, sizeof(signedCRL));
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertFreeCRLContext(info.u.pCRLContext);
    /* Imports the following cert--self-signed, with no basic constraints set--
     * to the CA store.  Puts up a dialog at the end if it succeeds or fails.
     */
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT;
    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR CA[] = { 'C','A',0 };
        HCERTSTORE ca = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, CA);

        if (ca)
        {
            ret = find_and_delete_cert_in_store(ca, info.u.pCertContext);
            ok(ret ||
             broken(!ret) /* Win9x/NT4 */,
             "expected to find v1CertWithValidPubKey in CA store\n");
            CertCloseStore(ca, 0);
        }
    }
    CertFreeCertificateContext(info.u.pCertContext);
    /* Imports the following cert--not self-signed, with a basic constraints2
     * extensions--to the "AddressBook" store.  Puts up a dialog at the end if
     * it succeeds or fails.
     */
    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     iTunesCert3, sizeof(iTunesCert3));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR AddressBook[] = { 'A','d','d','r','e','s','s',
         'B','o','o','k',0 };
        HCERTSTORE addressBook = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, AddressBook);

        if (addressBook)
        {
            ret = find_and_delete_cert_in_store(addressBook,
             info.u.pCertContext);
            ok(ret ||
             broken(!ret),  /* Windows 2000 and earlier */
             "expected to find iTunesCert3 in AddressBook store\n");
            CertCloseStore(addressBook, 0);
        }
    }
    /* Displays the wizard, but disables the "Certificate store" edit and
     * the Browse button.  Confusingly, the "Place all certificates in the
     * following store" radio button is not disabled.
     */
    if (0)
    {
        ret = pCryptUIWizImport(CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE, 0,
         NULL, &info, NULL);
        ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    }
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    /* Displays the wizard, but sets the "Certificate store" edit to the
     * string "Determined by the program", and disables it and the Browse
     * button, as well as the "Automatically select the certificate store
     * based on the type of certificate" radio button.
     */
    if (0)
    {
        ret = pCryptUIWizImport(CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE, 0,
         NULL, &info, store);
        ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    }
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI |
     CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE, 0, NULL, &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    ret = find_and_delete_cert_in_store(store, info.u.pCertContext);
    ok(ret ||
     broken(!ret) /* Win9x/NT4 */,
     "expected to find iTunesCert3 in memory store\n");
    CertFreeCertificateContext(info.u.pCertContext);
    CertCloseStore(store, 0);

    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     iTunesCert1, sizeof(iTunesCert1));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR AddressBook[] = { 'A','d','d','r','e','s','s',
         'B','o','o','k',0 };
        HCERTSTORE addressBook = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, AddressBook);

        if (addressBook)
        {
            ret = find_and_delete_cert_in_store(addressBook,
             info.u.pCertContext);
            ok(ret ||
             broken(!ret),  /* Windows 2000 and earlier */
             "expected to find iTunesCert1 in AddressBook store\n");
            CertCloseStore(addressBook, 0);
        }
    }
    CertFreeCertificateContext(info.u.pCertContext);

    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     iTunesCert2, sizeof(iTunesCert2));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR CA[] = { 'C','A',0 };
        HCERTSTORE ca = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, CA);

        if (ca)
        {
            ret = find_and_delete_cert_in_store(ca, info.u.pCertContext);
            ok(ret ||
             broken(!ret) /* Win9x/NT4 */,
             "expected to find iTunesCert2 in CA store\n");
            CertCloseStore(ca, 0);
        }
    }
    CertFreeCertificateContext(info.u.pCertContext);

    info.u.hCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    CertAddEncodedCertificateToStore(info.u.hCertStore, X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
     CERT_STORE_ADD_ALWAYS, NULL);
    CertAddEncodedCRLToStore(info.u.hCertStore, X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE;
    /* The ALLOW flags aren't allowed with a store as the source if the source
     * contains types other than those allowed.
     */
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI |
     CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE |
     CRYPTUI_WIZ_IMPORT_ALLOW_CERT | CRYPTUI_WIZ_IMPORT_ALLOW_CRL, 0, NULL,
     &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        count = 0;
        cert = NULL;
        do {
            cert = CertEnumCertificatesInStore(store, cert);
            if (cert)
                count++;
        } while (cert);
        ok(count == 1, "expected 1 cert, got %d\n", count);
        count = 0;
        crl = NULL;
        do {
            crl = CertEnumCRLsInStore(store, crl);
            if (crl)
                count++;
        } while (crl);
        ok(count == 1, "expected 1 CRL, got %d\n", count);
    }
    CertCloseStore(store, 0);
    CertCloseStore(info.u.hCertStore, 0);

    /* If the ALLOW flags match the content of the store, the store can be
     * imported.
     */
    info.u.hCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    CertAddEncodedCertificateToStore(info.u.hCertStore, X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
     CERT_STORE_ADD_ALWAYS, NULL);
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        count = 0;
        cert = NULL;
        do {
            cert = CertEnumCertificatesInStore(store, cert);
            if (cert)
                count++;
        } while (cert);
        ok(count == 1, "expected 1 cert, got %d\n", count);
        count = 0;
        crl = NULL;
        do {
            crl = CertEnumCRLsInStore(store, crl);
            if (crl)
                count++;
        } while (crl);
        ok(count == 0, "expected 0 CRLs, got %d\n", count);
    }
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertCloseStore(store, 0);
    CertCloseStore(info.u.hCertStore, 0);

    /* Again, if the ALLOW flags match the content of the store, the store can
     * be imported.
     */
    info.u.hCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    CertAddEncodedCRLToStore(info.u.hCertStore, X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        count = 0;
        cert = NULL;
        do {
            cert = CertEnumCertificatesInStore(store, cert);
            if (cert)
                count++;
        } while (cert);
        ok(count == 0, "expected 0 certs, got %d\n", count);
        count = 0;
        crl = NULL;
        do {
            crl = CertEnumCRLsInStore(store, crl);
            if (crl)
                count++;
        } while (crl);
        ok(count == 1, "expected 1 CRL, got %d\n", count);
    }
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertCloseStore(store, 0);
    CertCloseStore(info.u.hCertStore, 0);

    UnhookWindowsHookEx(hook);
}
Пример #8
0
static void test_retrieveObjectByUrl(void)
{
    BOOL ret;
    char tmpfile[MAX_PATH * 2], url[MAX_PATH + 8];
    CRYPT_BLOB_ARRAY *pBlobArray;
    PCCERT_CONTEXT cert;
    PCCRL_CONTEXT crl;
    HCERTSTORE store;
    CRYPT_RETRIEVE_AUX_INFO aux = { 0 };
    FILETIME ft = { 0 };

    SetLastError(0xdeadbeef);
    ret = CryptRetrieveObjectByUrlA(NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL);
    ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER ||
                GetLastError() == E_INVALIDARG),
       "got 0x%x/%u (expected ERROR_INVALID_PARAMETER or E_INVALIDARG)\n",
       GetLastError(), GetLastError());

    make_tmp_file(tmpfile);
    snprintf(url, sizeof(url), "file://%s", tmpfile);

    pBlobArray = (CRYPT_BLOB_ARRAY *)0xdeadbeef;
    ret = CryptRetrieveObjectByUrlA(url, NULL, 0, 0, (void **)&pBlobArray,
     NULL, NULL, NULL, NULL);
    if (!ret)
    {
        /* File URL support was apparently removed in Vista/Windows 2008 */
        win_skip("File URLs not supported\n");
        return;
    }
    ok(ret, "CryptRetrieveObjectByUrlA failed: %d\n", GetLastError());
    ok(pBlobArray && pBlobArray != (CRYPT_BLOB_ARRAY *)0xdeadbeef,
     "Expected a valid pointer\n");
    if (pBlobArray && pBlobArray != (CRYPT_BLOB_ARRAY *)0xdeadbeef)
    {
        ok(pBlobArray->cBlob == 1, "Expected 1 blob, got %d\n",
         pBlobArray->cBlob);
        ok(pBlobArray->rgBlob[0].cbData == sizeof(certWithCRLDistPoint),
         "Unexpected size %d\n", pBlobArray->rgBlob[0].cbData);
        CryptMemFree(pBlobArray);
    }
    cert = (PCCERT_CONTEXT)0xdeadbeef;
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0,
     (void **)&cert, NULL, NULL, NULL, NULL);
    ok(ret, "CryptRetrieveObjectByUrlA failed: %d\n", GetLastError());
    ok(cert && cert != (PCCERT_CONTEXT)0xdeadbeef, "Expected a cert\n");
    if (cert && cert != (PCCERT_CONTEXT)0xdeadbeef)
        CertFreeCertificateContext(cert);
    crl = (PCCRL_CONTEXT)0xdeadbeef;
    SetLastError(0xdeadbeef);
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CRL, 0, 0, (void **)&crl,
     NULL, NULL, NULL, NULL);
    /* w2k3,XP, newer w2k: CRYPT_E_NO_MATCH, older w2k: CRYPT_E_ASN1_BADTAG
     * or OSS_DATA_ERROR.
     */
    ok(!ret && (GetLastError() == CRYPT_E_NO_MATCH ||
                broken(GetLastError() == CRYPT_E_ASN1_BADTAG ||
                       GetLastError() == OSS_DATA_ERROR)),
        "got 0x%x/%u (expected CRYPT_E_NO_MATCH)\n", GetLastError(), GetLastError());

    /* only newer versions of cryptnet do the cleanup */
    if(!ret && GetLastError() != CRYPT_E_ASN1_BADTAG &&
               GetLastError() != OSS_DATA_ERROR) {
        ok(crl == NULL, "Expected CRL to be NULL\n");
    }

    if (crl && crl != (PCCRL_CONTEXT)0xdeadbeef)
        CertFreeCRLContext(crl);
    store = (HCERTSTORE)0xdeadbeef;
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CAPI2_ANY, 0, 0,
     &store, NULL, NULL, NULL, NULL);
    ok(ret, "CryptRetrieveObjectByUrlA failed: %d\n", GetLastError());
    if (store && store != (HCERTSTORE)0xdeadbeef)
    {
        DWORD certs = 0;

        cert = NULL;
        do {
            cert = CertEnumCertificatesInStore(store, cert);
            if (cert)
                certs++;
        } while (cert);
        ok(certs == 1, "Expected 1 cert, got %d\n", certs);
        CertCloseStore(store, 0);
    }
    /* Are file URLs cached? */
    cert = (PCCERT_CONTEXT)0xdeadbeef;
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE,
     CRYPT_CACHE_ONLY_RETRIEVAL, 0, (void **)&cert, NULL, NULL, NULL, NULL);
    ok(ret, "CryptRetrieveObjectByUrlA failed: %08x\n", GetLastError());
    if (cert && cert != (PCCERT_CONTEXT)0xdeadbeef)
        CertFreeCertificateContext(cert);

    cert = (PCCERT_CONTEXT)0xdeadbeef;
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0,
     (void **)&cert, NULL, NULL, NULL, &aux);
    /* w2k: failure with E_INVALIDARG */
    ok(ret || broken(GetLastError() == E_INVALIDARG),
       "got %u with 0x%x/%u (expected '!=0' or '0' with E_INVALIDARG)\n",
       ret, GetLastError(), GetLastError());
    if (cert && cert != (PCCERT_CONTEXT)0xdeadbeef)
        CertFreeCertificateContext(cert);

    cert = (PCCERT_CONTEXT)0xdeadbeef;
    aux.cbSize = sizeof(aux);
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0,
     (void **)&cert, NULL, NULL, NULL, &aux);
    /* w2k: failure with E_INVALIDARG */
    ok(ret || broken(GetLastError() == E_INVALIDARG),
       "got %u with 0x%x/%u (expected '!=0' or '0' with E_INVALIDARG)\n",
       ret, GetLastError(), GetLastError());
    if (!ret) {
        /* no more tests useful */
        DeleteFileA(tmpfile);
        skip("no usable CertificateContext\n");
        return;
    }
    CertFreeCertificateContext(cert);

    aux.pLastSyncTime = &ft;
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0,
     (void **)&cert, NULL, NULL, NULL, &aux);
    ok(ret, "CryptRetrieveObjectByUrlA failed: %08x\n", GetLastError());
    CertFreeCertificateContext(cert);
    ok(ft.dwLowDateTime || ft.dwHighDateTime,
     "Expected last sync time to be set\n");
    DeleteFileA(tmpfile);
    /* Okay, after being deleted, are file URLs still cached? */
    SetLastError(0xdeadbeef);
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE,
     CRYPT_CACHE_ONLY_RETRIEVAL, 0, (void **)&cert, NULL, NULL, NULL, NULL);
    ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
     GetLastError() == ERROR_PATH_NOT_FOUND),
     "Expected ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND, got %d\n",
     GetLastError());
}
Пример #9
0
my_bool ma_schannel_verify_certs(SC_CTX *sctx, DWORD dwCertFlags)
{
  SECURITY_STATUS sRet;
  DWORD flags;
  MARIADB_PVIO *pvio= sctx->mysql->net.pvio;
  PCCERT_CONTEXT pServerCert= NULL;
  PCCERT_CONTEXT ca_CTX = NULL;
  PCCRL_CONTEXT crl_CTX = NULL;
  my_bool is_Ok = 0;

  if ((sRet= QueryContextAttributes(&sctx->ctxt, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pServerCert)) != SEC_E_OK)
  {
    ma_schannel_set_sec_error(pvio, sRet);
    return 0;
  }

  if (ca_Check)
  {
    flags = CERT_STORE_SIGNATURE_FLAG |
      CERT_STORE_TIME_VALIDITY_FLAG;

    while ((ca_CTX = CertFindCertificateInStore(ca_CertStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
      0, CERT_FIND_ANY, 0, ca_CTX)) && !is_Ok)
    {
      if (sRet = CertVerifySubjectCertificateContext(pServerCert, ca_CTX, &flags))
        is_Ok = 1;
    }

    if (ca_CTX)
      CertFreeCertificateContext(ca_CTX);

    if (!is_Ok)
    {
      ma_schannel_set_win_error(pvio);
      return 0;
    }

    if (flags)
    {
      if ((flags & CERT_STORE_SIGNATURE_FLAG) != 0)
        pvio->set_error(sctx->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Certificate signature check failed");
      else if ((flags & CERT_STORE_REVOCATION_FLAG) != 0)
        pvio->set_error(sctx->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "certificate was revoked");
      else if ((flags & CERT_STORE_TIME_VALIDITY_FLAG) != 0)
        pvio->set_error(sctx->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "certificate has expired");
      else
        pvio->set_error(sctx->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Unknown error during certificate validation");
      return 0;
    }
  }

  /* Check if none of the certificates in the certificate chain have been revoked. */
  if (crl_Check)
  {
    while ((crl_CTX = CertEnumCRLsInStore(crl_CertStore, crl_CTX)))
    {
      PCRL_INFO Info[1];

      Info[0] = crl_CTX->pCrlInfo;
      if (!(CertVerifyCRLRevocation(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
        pServerCert->pCertInfo,
        1, Info)))
      {
        CertFreeCRLContext(crl_CTX);
        pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "CRL Revocation failed");
        return 0;
      }
    }
    CertFreeCRLContext(crl_CTX);
  }
  return 1;
}
Пример #10
0
static void test_retrieveObjectByUrl(void)
{
    BOOL ret;
    char tmpfile[MAX_PATH * 2], *ptr, url[MAX_PATH + 8];
    CRYPT_BLOB_ARRAY *pBlobArray;
    PCCERT_CONTEXT cert;
    PCCRL_CONTEXT crl;
    HCERTSTORE store;
    CRYPT_RETRIEVE_AUX_INFO aux = { 0 };
    FILETIME ft = { 0 };

    SetLastError(0xdeadbeef);
    ret = CryptRetrieveObjectByUrlA(NULL, NULL, 0, 0, NULL, NULL, NULL, NULL,
     NULL);
    ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
     "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());

    make_tmp_file(tmpfile);
    ptr = strchr(tmpfile, ':');
    if (ptr)
        ptr += 2; /* skip colon and first slash */
    else
        ptr = tmpfile;
    snprintf(url, sizeof(url), "file:///%s", ptr);
    do {
        ptr = strchr(url, '\\');
        if (ptr)
            *ptr = '/';
    } while (ptr);

    pBlobArray = (CRYPT_BLOB_ARRAY *)0xdeadbeef;
    ret = CryptRetrieveObjectByUrlA(url, NULL, 0, 0, (void **)&pBlobArray,
     NULL, NULL, NULL, NULL);
    ok(ret, "CryptRetrieveObjectByUrlA failed: %d\n", GetLastError());
    ok(pBlobArray && pBlobArray != (CRYPT_BLOB_ARRAY *)0xdeadbeef,
     "Expected a valid pointer\n");
    if (pBlobArray && pBlobArray != (CRYPT_BLOB_ARRAY *)0xdeadbeef)
    {
        ok(pBlobArray->cBlob == 1, "Expected 1 blob, got %d\n",
         pBlobArray->cBlob);
        ok(pBlobArray->rgBlob[0].cbData == sizeof(certWithCRLDistPoint),
         "Unexpected size %d\n", pBlobArray->rgBlob[0].cbData);
        CryptMemFree(pBlobArray);
    }
    cert = (PCCERT_CONTEXT)0xdeadbeef;
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0,
     (void **)&cert, NULL, NULL, NULL, NULL);
    ok(cert && cert != (PCCERT_CONTEXT)0xdeadbeef, "Expected a cert\n");
    if (cert && cert != (PCCERT_CONTEXT)0xdeadbeef)
        CertFreeCertificateContext(cert);
    crl = (PCCRL_CONTEXT)0xdeadbeef;
    SetLastError(0xdeadbeef);
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CRL, 0, 0, (void **)&crl,
     NULL, NULL, NULL, NULL);
    ok(!ret && GetLastError() == CRYPT_E_NO_MATCH,
     "Expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
    ok(crl == NULL, "Expected CRL to be NULL\n");
    if (crl && crl != (PCCRL_CONTEXT)0xdeadbeef)
        CertFreeCRLContext(crl);
    store = (HCERTSTORE)0xdeadbeef;
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CAPI2_ANY, 0, 0,
     (void **)&store, NULL, NULL, NULL, NULL);
    ok(ret, "CryptRetrieveObjectByUrlA failed: %d\n", GetLastError());
    if (store && store != (HCERTSTORE)0xdeadbeef)
    {
        DWORD certs = 0;

        cert = NULL;
        do {
            cert = CertEnumCertificatesInStore(store, cert);
            if (cert)
                certs++;
        } while (cert);
        ok(certs == 1, "Expected 1 cert, got %d\n", certs);
        CertCloseStore(store, 0);
    }
    /* Are file URLs cached? */
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE,
     CRYPT_CACHE_ONLY_RETRIEVAL, 0, (void **)&cert, NULL, NULL, NULL, NULL);
    ok(ret, "CryptRetrieveObjectByUrlA failed: %08x\n", GetLastError());
    if (cert && cert != (PCCERT_CONTEXT)0xdeadbeef)
        CertFreeCertificateContext(cert);
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0,
     (void **)&cert, NULL, NULL, NULL, &aux);
    ok(ret, "CryptRetrieveObjectByUrlA failed: %08x\n", GetLastError());
    if (cert && cert != (PCCERT_CONTEXT)0xdeadbeef)
        CertFreeCertificateContext(cert);
    aux.cbSize = sizeof(aux);
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0,
     (void **)&cert, NULL, NULL, NULL, &aux);
    ok(ret, "CryptRetrieveObjectByUrlA failed: %08x\n", GetLastError());
    aux.pLastSyncTime = &ft;
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0,
     (void **)&cert, NULL, NULL, NULL, &aux);
    ok(ft.dwLowDateTime || ft.dwHighDateTime,
     "Expected last sync time to be set\n");
    DeleteFileA(tmpfile);
    /* Okay, after being deleted, are file URLs still cached? */
    SetLastError(0xdeadbeef);
    ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE,
     CRYPT_CACHE_ONLY_RETRIEVAL, 0, (void **)&cert, NULL, NULL, NULL, NULL);
    ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
     GetLastError() == ERROR_PATH_NOT_FOUND),
     "Expected ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND, got %d\n",
     GetLastError());
}
Пример #11
0
/* {{{ static int ma_tls_set_client_certs(MARIADB_TLS *ctls) */
static int ma_tls_set_client_certs(MARIADB_TLS *ctls)
{
  MYSQL *mysql= ctls->pvio->mysql;
  char *certfile= mysql->options.ssl_cert,
       *keyfile= mysql->options.ssl_key,
       *cafile= mysql->options.ssl_ca;
  PCERT_CONTEXT ca_ctx= NULL;
  PCRL_CONTEXT crl_ctx = NULL;
       
  SC_CTX *sctx= (SC_CTX *)ctls->ssl;
  MARIADB_PVIO *pvio= ctls->pvio;

  if (cafile)
  {
    if (!(ca_ctx = ma_schannel_create_cert_context(pvio, cafile)))
      goto end;

    /* Add ca to in-memory certificate store */
    if (CertAddCertificateContextToStore(ca_CertStore, ca_ctx, CERT_STORE_ADD_NEWER, NULL) != TRUE &&
        GetLastError() != CRYPT_E_EXISTS)
    {
      ma_schannel_set_win_error(sctx->mysql);
      goto end;
    }
    ca_Check= 0;
    CertFreeCertificateContext(ca_ctx);
  }

  if (!certfile && keyfile)
    certfile= keyfile;
  if (!keyfile && certfile)
    keyfile= certfile;

  if (certfile && certfile[0])
    if (!(sctx->client_cert_ctx = ma_schannel_create_cert_context(ctls->pvio, certfile)))
      goto end;

  if (sctx->client_cert_ctx && keyfile[0])
    if (!ma_schannel_load_private_key(pvio, sctx->client_cert_ctx, keyfile))
      goto end;
 
  if (mysql->options.extension && mysql->options.extension->ssl_crl)
  {
    if (!(crl_ctx= (CRL_CONTEXT *)ma_schannel_create_crl_context(pvio, mysql->options.extension->ssl_crl)))
      goto end;
    /* Add ca to in-memory certificate store */
    if (CertAddCRLContextToStore(crl_CertStore, crl_ctx, CERT_STORE_ADD_NEWER, NULL) != TRUE &&
        GetLastError() != CRYPT_E_EXISTS)
    {
      ma_schannel_set_win_error(sctx->mysql);
      goto end;
    }
    crl_Check = 1;
    CertFreeCertificateContext(ca_ctx);
  }
  return 0;
  
end:
  if (ca_ctx)
    CertFreeCertificateContext(ca_ctx);
  if (sctx->client_cert_ctx)
    CertFreeCertificateContext(sctx->client_cert_ctx);
  if (crl_ctx)
    CertFreeCRLContext(crl_ctx);
  sctx->client_cert_ctx= NULL;
  return 1;
}
Пример #12
0
static int op_capi_get_by_subject(X509_LOOKUP *_lu,int _type,X509_NAME *_name,
                                  X509_OBJECT *_ret) {
    HCERTSTORE h_store;
    if(_name==NULL)return 0;
    if(_name->bytes==NULL||_name->bytes->length<=0||_name->modified) {
        if(i2d_X509_NAME(_name,NULL)<0)return 0;
        OP_ASSERT(_name->bytes->length>0);
    }
    h_store=(HCERTSTORE)_lu->method_data;
    switch(_type) {
    case X509_LU_X509: {
        CERT_NAME_BLOB  find_para;
        PCCERT_CONTEXT  cert;
        X509           *x;
        int             ret;
        /*Although X509_NAME contains a canon_enc field, that "canonical" [1]
           encoding was just made up by OpenSSL.
          It doesn't correspond to any actual standard, and since it drops the
           initial sequence header, won't be recognized by the Crypto API.
          The assumption here is that CertFindCertificateInStore() will allow any
           appropriate variations in the encoding when it does its comparison.
          This is, however, emphatically not true under Wine, which just compares
           the encodings with memcmp().
          Most of the time things work anyway, though, and there isn't really
           anything we can do to make the situation better.

          [1] A "canonical form" is defined as the one where, if you locked 10
           mathematicians in a room and asked them to come up with a
           representation for something, it's the answer that 9 of them would
           give you back.
          I don't think OpenSSL's encoding qualifies.*/
        find_para.cbData=_name->bytes->length;
        find_para.pbData=(unsigned char *)_name->bytes->data;
        cert=CertFindCertificateInStore(h_store,X509_ASN_ENCODING,0,
                                        CERT_FIND_SUBJECT_NAME,&find_para,NULL);
        if(cert==NULL)return 0;
        x=d2i_X509(NULL,(const unsigned char **)&cert->pbCertEncoded,
                   cert->cbCertEncoded);
        CertFreeCertificateContext(cert);
        if(x==NULL)return 0;
        ret=X509_STORE_add_cert(_lu->store_ctx,x);
        X509_free(x);
        if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
    }
    break;
    case X509_LU_CRL: {
        CERT_INFO      cert_info;
        CERT_CONTEXT   find_para;
        PCCRL_CONTEXT  crl;
        X509_CRL      *x;
        int            ret;
        ret=op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
        if(ret>0)return ret;
        memset(&cert_info,0,sizeof(cert_info));
        cert_info.Issuer.cbData=_name->bytes->length;
        cert_info.Issuer.pbData=(unsigned char *)_name->bytes->data;
        memset(&find_para,0,sizeof(find_para));
        find_para.pCertInfo=&cert_info;
        crl=CertFindCRLInStore(h_store,0,0,CRL_FIND_ISSUED_BY,&find_para,NULL);
        if(crl==NULL)return 0;
        x=d2i_X509_CRL(NULL,(const unsigned char **)&crl->pbCrlEncoded,
                       crl->cbCrlEncoded);
        CertFreeCRLContext(crl);
        if(x==NULL)return 0;
        ret=X509_STORE_add_crl(_lu->store_ctx,x);
        X509_CRL_free(x);
        if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
    }
    break;
    }
    return 0;
}