serialize.c

来自「一个类似windows」· C语言 代码 · 共 516 行 · 第 1/2 页

C
516
字号
                /* assume a zero prop ID means the data are uninitialized, so
                 * stop looking.
                 */
                done = TRUE;
            }
            else if (hdr->unknown != 1)
            {
                SetLastError(ERROR_FILE_NOT_FOUND);
                done = TRUE;
            }
            else if (hdr->propID == propID)
                ret = hdr;
            else
            {
                buf += hdr->cb;
                size -= hdr->cb;
            }
        }
    }
    return ret;
}

const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement,
 DWORD dwContextTypeFlags, DWORD *pdwContentType)
{
    const void *context;

    TRACE("(%p, %ld, %08lx, %p)\n", pbElement, cbElement, dwContextTypeFlags,
     pdwContentType);

    if (!cbElement)
    {
        SetLastError(ERROR_END_OF_MEDIA);
        return NULL;
    }

    __TRY
    {
        const WINE_CONTEXT_INTERFACE *contextInterface = NULL;
        const WINE_CERT_PROP_HEADER *hdr = NULL;
        DWORD type = 0;
        BOOL ret;

        ret = TRUE;
        context = NULL;
        if (dwContextTypeFlags == CERT_STORE_ALL_CONTEXT_FLAG)
        {
            hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CERT_PROP_ID);
            if (hdr)
                type = CERT_STORE_CERTIFICATE_CONTEXT;
            else
            {
                hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CRL_PROP_ID);
                if (hdr)
                    type = CERT_STORE_CRL_CONTEXT;
                else
                {
                    hdr = CRYPT_findPropID(pbElement, cbElement,
                     CERT_CTL_PROP_ID);
                    if (hdr)
                        type = CERT_STORE_CTL_CONTEXT;
                }
            }
        }
        else if (dwContextTypeFlags & CERT_STORE_CERTIFICATE_CONTEXT_FLAG)
        {
            hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CERT_PROP_ID);
            type = CERT_STORE_CERTIFICATE_CONTEXT;
        }
        else if (dwContextTypeFlags & CERT_STORE_CRL_CONTEXT_FLAG)
        {
            hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CRL_PROP_ID);
            type = CERT_STORE_CRL_CONTEXT;
        }
        else if (dwContextTypeFlags & CERT_STORE_CTL_CONTEXT_FLAG)
        {
            hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CTL_PROP_ID);
            type = CERT_STORE_CTL_CONTEXT;
        }

        switch (type)
        {
        case CERT_STORE_CERTIFICATE_CONTEXT:
            contextInterface = &gCertInterface;
            break;
        case CERT_STORE_CRL_CONTEXT:
            contextInterface = &gCRLInterface;
            break;
        case CERT_STORE_CTL_CONTEXT:
            contextInterface = &gCTLInterface;
            break;
        default:
            SetLastError(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
            ret = FALSE;
        }
        if (!hdr)
            ret = FALSE;

        if (ret)
            context = contextInterface->create(X509_ASN_ENCODING,
             (BYTE *)hdr + sizeof(WINE_CERT_PROP_HEADER), hdr->cb);
        if (ret && context)
        {
            BOOL noMoreProps = FALSE;

            while (!noMoreProps && ret)
            {
                if (cbElement < sizeof(WINE_CERT_PROP_HEADER))
                    ret = FALSE;
                else
                {
                    const WINE_CERT_PROP_HEADER *hdr =
                     (const WINE_CERT_PROP_HEADER *)pbElement;

                    TRACE("prop is %ld\n", hdr->propID);
                    cbElement -= sizeof(WINE_CERT_PROP_HEADER);
                    pbElement += sizeof(WINE_CERT_PROP_HEADER);
                    if (cbElement < hdr->cb)
                    {
                        SetLastError(HRESULT_FROM_WIN32(
                         ERROR_INVALID_PARAMETER));
                        ret = FALSE;
                    }
                    else if (!hdr->propID)
                    {
                        /* Like in CRYPT_findPropID, stop if the propID is zero
                         */
                        noMoreProps = TRUE;
                    }
                    else if (hdr->unknown != 1)
                    {
                        SetLastError(ERROR_FILE_NOT_FOUND);
                        ret = FALSE;
                    }
                    else if (hdr->propID != CERT_CERT_PROP_ID &&
                     hdr->propID != CERT_CRL_PROP_ID && hdr->propID !=
                     CERT_CTL_PROP_ID)
                    {
                        /* Have to create a blob for most types, but not
                         * for all.. arghh.
                         */
                        switch (hdr->propID)
                        {
                        case CERT_AUTO_ENROLL_PROP_ID:
                        case CERT_CTL_USAGE_PROP_ID:
                        case CERT_DESCRIPTION_PROP_ID:
                        case CERT_FRIENDLY_NAME_PROP_ID:
                        case CERT_HASH_PROP_ID:
                        case CERT_KEY_IDENTIFIER_PROP_ID:
                        case CERT_MD5_HASH_PROP_ID:
                        case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
                        case CERT_PUBKEY_ALG_PARA_PROP_ID:
                        case CERT_PVK_FILE_PROP_ID:
                        case CERT_SIGNATURE_HASH_PROP_ID:
                        case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
                        case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
                        case CERT_ENROLLMENT_PROP_ID:
                        case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
                        case CERT_RENEWAL_PROP_ID:
                        {
                            CRYPT_DATA_BLOB blob = { hdr->cb,
                             (LPBYTE)pbElement };

                            ret = contextInterface->setProp(context,
                             hdr->propID, 0, &blob);
                            break;
                        }
                        case CERT_DATE_STAMP_PROP_ID:
                            ret = contextInterface->setProp(context,
                             hdr->propID, 0, pbElement);
                            break;
                        default:
                            FIXME("prop ID %ld: stub\n", hdr->propID);
                        }
                    }
                    pbElement += hdr->cb;
                    cbElement -= hdr->cb;
                    if (!cbElement)
                        noMoreProps = TRUE;
                }
            }
            if (ret)
            {
                if (pdwContentType)
                    *pdwContentType = type;
            }
            else
            {
                contextInterface->free(context);
                context = NULL;
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        context = NULL;
    }
    __ENDTRY
    return context;
}

BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore,
 const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags,
 DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext)
{
    const void *context;
    DWORD type;
    BOOL ret;

    TRACE("(%p, %p, %ld, %08lx, %08lx, %08lx, %p, %p)\n", hCertStore,
     pbElement, cbElement, dwAddDisposition, dwFlags, dwContextTypeFlags,
     pdwContentType, ppvContext);

    /* Call the internal function, then delete the hashes.  Tests show this
     * function uses real hash values, not whatever's stored in the hash
     * property.
     */
    context = CRYPT_ReadSerializedElement(pbElement, cbElement,
     dwContextTypeFlags, &type);
    if (context)
    {
        const WINE_CONTEXT_INTERFACE *contextInterface = NULL;

        switch (type)
        {
        case CERT_STORE_CERTIFICATE_CONTEXT:
            contextInterface = &gCertInterface;
            break;
        case CERT_STORE_CRL_CONTEXT:
            contextInterface = &gCRLInterface;
            break;
        case CERT_STORE_CTL_CONTEXT:
            contextInterface = &gCTLInterface;
            break;
        default:
            SetLastError(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
        }
        if (contextInterface)
        {
            contextInterface->setProp(context, CERT_HASH_PROP_ID, 0, NULL);
            contextInterface->setProp(context, CERT_MD5_HASH_PROP_ID, 0, NULL);
            contextInterface->setProp(context, CERT_SIGNATURE_HASH_PROP_ID, 0,
             NULL);
            if (pdwContentType)
                *pdwContentType = type;
            ret = contextInterface->addContextToStore(hCertStore, context,
             dwAddDisposition, ppvContext);
            contextInterface->free(context);
        }
        else
            ret = FALSE;
    }
    else
        ret = FALSE;
    return ret;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?