⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encode.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    BOOL ret;

    if (!pbEncoded)
    {
        *pcbEncoded = blob->cbData;
        ret = TRUE;
    }
    else
    {
        if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
         pcbEncoded, blob->cbData)))
        {
            if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
                pbEncoded = *(BYTE **)pbEncoded;
            if (blob->cbData)
                memcpy(pbEncoded, blob->pbData, blob->cbData);
            *pcbEncoded = blob->cbData;
            ret = TRUE;
        }
    }
    return ret;
}

static BOOL WINAPI CRYPT_AsnEncodeValidity(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
 PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
    BOOL ret;
    /* This has two filetimes in a row, a NotBefore and a NotAfter */
    const FILETIME *timePtr = (const FILETIME *)pvStructInfo;
    struct AsnEncodeSequenceItem items[] = {
     { timePtr++, CRYPT_AsnEncodeChoiceOfTime, 0 },
     { timePtr,   CRYPT_AsnEncodeChoiceOfTime, 0 },
    };

    ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, 
     sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
     pcbEncoded);
    return ret;
}

static BOOL WINAPI CRYPT_AsnEncodeAlgorithmId(
 DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo,
 DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
 DWORD *pcbEncoded)
{
    const CRYPT_ALGORITHM_IDENTIFIER *algo =
     (const CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
    BOOL ret;
    struct AsnEncodeSequenceItem items[] = {
     { algo->pszObjId,    CRYPT_AsnEncodeOid, 0 },
     { &algo->Parameters, CRYPT_CopyEncodedBlob, 0 },
    };

    ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
     sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
     pcbEncoded);
    return ret;
}

static BOOL WINAPI CRYPT_AsnEncodePubKeyInfo(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
 PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
    BOOL ret;

    __TRY
    {
        const CERT_PUBLIC_KEY_INFO *info =
         (const CERT_PUBLIC_KEY_INFO *)pvStructInfo;
        struct AsnEncodeSequenceItem items[] = {
         { &info->Algorithm, CRYPT_AsnEncodeAlgorithmId, 0 },
         { &info->PublicKey, CRYPT_AsnEncodeBits, 0 },
        };

        TRACE("Encoding public key with OID %s\n",
         debugstr_a(info->Algorithm.pszObjId));
        ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
         sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
         pcbEncoded);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL WINAPI CRYPT_AsnEncodeCert(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
 PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
    BOOL ret;

    __TRY
    {
        const CERT_SIGNED_CONTENT_INFO *info =
         (const CERT_SIGNED_CONTENT_INFO *)pvStructInfo;
        struct AsnEncodeSequenceItem items[] = {
         { &info->ToBeSigned,         CRYPT_CopyEncodedBlob, 0 },
         { &info->SignatureAlgorithm, CRYPT_AsnEncodeAlgorithmId, 0 },
         { &info->Signature,          CRYPT_AsnEncodeBitsSwapBytes, 0 },
        };

        if (dwFlags & CRYPT_ENCODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
            items[2].encodeFunc = CRYPT_AsnEncodeBits;
        ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, 
         sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
         pcbEncoded);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

/* Like in Windows, this blithely ignores the validity of the passed-in
 * CERT_INFO, and just encodes it as-is.  The resulting encoded data may not
 * decode properly, see CRYPT_AsnDecodeCertInfo.
 */
static BOOL WINAPI CRYPT_AsnEncodeCertInfo(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
 PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
    BOOL ret;

    __TRY
    {
        const CERT_INFO *info = (const CERT_INFO *)pvStructInfo;
        struct AsnEncodeSequenceItem items[10] = {
         { &info->dwVersion,            CRYPT_AsnEncodeCertVersion, 0 },
         { &info->SerialNumber,         CRYPT_AsnEncodeInteger, 0 },
         { &info->SignatureAlgorithm,   CRYPT_AsnEncodeAlgorithmId, 0 },
         { &info->Issuer,               CRYPT_CopyEncodedBlob, 0 },
         { &info->NotBefore,            CRYPT_AsnEncodeValidity, 0 },
         { &info->Subject,              CRYPT_CopyEncodedBlob, 0 },
         { &info->SubjectPublicKeyInfo, CRYPT_AsnEncodePubKeyInfo, 0 },
         { 0 }
        };
        struct AsnConstructedItem constructed[3] = { { 0 } };
        DWORD cItem = 7, cConstructed = 0;

        if (info->IssuerUniqueId.cbData)
        {
            constructed[cConstructed].tag = 1;
            constructed[cConstructed].pvStructInfo = &info->IssuerUniqueId;
            constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeBits;
            items[cItem].pvStructInfo = &constructed[cConstructed];
            items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
            cConstructed++;
            cItem++;
        }
        if (info->SubjectUniqueId.cbData)
        {
            constructed[cConstructed].tag = 2;
            constructed[cConstructed].pvStructInfo = &info->SubjectUniqueId;
            constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeBits;
            items[cItem].pvStructInfo = &constructed[cConstructed];
            items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
            cConstructed++;
            cItem++;
        }
        if (info->cExtension)
        {
            constructed[cConstructed].tag = 3;
            constructed[cConstructed].pvStructInfo = &info->cExtension;
            constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeExtensions;
            items[cItem].pvStructInfo = &constructed[cConstructed];
            items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
            cConstructed++;
            cItem++;
        }

        ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
         dwFlags, pEncodePara, pbEncoded, pcbEncoded);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL WINAPI CRYPT_AsnEncodeCRLEntry(const CRL_ENTRY *entry,
 BYTE *pbEncoded, DWORD *pcbEncoded)
{
    struct AsnEncodeSequenceItem items[3] = {
     { &entry->SerialNumber,   CRYPT_AsnEncodeInteger, 0 },
     { &entry->RevocationDate, CRYPT_AsnEncodeChoiceOfTime, 0 },
     { 0 }
    };
    DWORD cItem = 2;
    BOOL ret;

    TRACE("%p, %p, %p\n", entry, pbEncoded, pcbEncoded);

    if (entry->cExtension)
    {
        items[cItem].pvStructInfo = &entry->cExtension;
        items[cItem].encodeFunc = CRYPT_AsnEncodeExtensions;
        cItem++;
    }

    ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL,
     pbEncoded, pcbEncoded);

    TRACE("returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL WINAPI CRYPT_AsnEncodeCRLEntries(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
 PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
    DWORD cCRLEntry = *(const DWORD *)pvStructInfo;
    DWORD bytesNeeded, dataLen, lenBytes, i;
    const CRL_ENTRY *rgCRLEntry = *(const CRL_ENTRY *const *)
     ((const BYTE *)pvStructInfo + sizeof(DWORD));
    BOOL ret = TRUE;

    for (i = 0, dataLen = 0; ret && i < cCRLEntry; i++)
    {
        DWORD size;

        ret = CRYPT_AsnEncodeCRLEntry(&rgCRLEntry[i], NULL, &size);
        if (ret)
            dataLen += size;
    }
    CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
    bytesNeeded = 1 + lenBytes + dataLen;
    if (!pbEncoded)
        *pcbEncoded = bytesNeeded;
    else
    {
        if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
         pcbEncoded, bytesNeeded)))
        {
            if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
                pbEncoded = *(BYTE **)pbEncoded;
            *pbEncoded++ = ASN_SEQUENCEOF;
            CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
            pbEncoded += lenBytes;
            for (i = 0; i < cCRLEntry; i++)
            {
                DWORD size = dataLen;

                ret = CRYPT_AsnEncodeCRLEntry(&rgCRLEntry[i], pbEncoded, &size);
                pbEncoded += size;
                dataLen -= size;
            }
        }
    }
    return ret;
}

static BOOL WINAPI CRYPT_AsnEncodeCRLVersion(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
 PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
    const DWORD *ver = (const DWORD *)pvStructInfo;
    BOOL ret;

    /* CRL_V1 is not encoded */
    if (*ver == CRL_V1)
    {
        *pcbEncoded = 0;
        ret = TRUE;
    }
    else
        ret = CRYPT_AsnEncodeInt(dwCertEncodingType, X509_INTEGER, ver,
         dwFlags, pEncodePara, pbEncoded, pcbEncoded);
    return ret;
}

/* Like in Windows, this blithely ignores the validity of the passed-in
 * CRL_INFO, and just encodes it as-is.  The resulting encoded data may not
 * decode properly, see CRYPT_AsnDecodeCRLInfo.
 */
static BOOL WINAPI CRYPT_AsnEncodeCRLInfo(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
 PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
    BOOL ret;

    __TRY
    {
        const CRL_INFO *info = (const CRL_INFO *)pvStructInfo;
        struct AsnEncodeSequenceItem items[7] = {
         { &info->dwVersion,          CRYPT_AsnEncodeCRLVersion, 0 },
         { &info->SignatureAlgorithm, CRYPT_AsnEncodeAlgorithmId, 0 },
         { &info->Issuer,             CRYPT_CopyEncodedBlob, 0 },
         { &info->ThisUpdate,         CRYPT_AsnEncodeChoiceOfTime, 0 },
         { 0 }
        };
        struct AsnConstructedItem constructed[1] = { { 0 } };
        DWORD cItem = 4, cConstructed = 0;

        if (info->NextUpdate.dwLowDateTime || info->NextUpdate.dwHighDateTime)
        {
            items[cItem].pvStructInfo = &info->NextUpdate;
            items[cItem].encodeFunc = CRYPT_AsnEncodeChoiceOfTime;
            cItem++;
        }
        if (info->cCRLEntry)
        {
            items[cItem].pvStructInfo = &info->cCRLEntry;
            items[cItem].encodeFunc = CRYPT_AsnEncodeCRLEntries;
            cItem++;
        }
        if (info->cExtension)
        {
            constructed[cConstructed].tag = 0;
            constructed[cConstructed].pvStructInfo = &info->cExtension;
            constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeExtensions;
            items[cItem].pvStructInfo = &constructed[cConstructed];
            items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
            cConstructed++;
            cItem++;
        }

        ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
         dwFlags, pEncodePara, pbEncoded, pcbEncoded);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnEncodeExtension(CERT_EXTENSION *ext, BYTE *pbEncoded,
 DWORD *pcbEncoded)
{
    BOOL ret;
    struct AsnEncodeSequenceItem items[3] = {
     { ext->pszObjId, CRYPT_AsnEncodeOid, 0 },
     { NULL, NULL, 0 },
     { NULL, NULL, 0 },
    };
    DWORD cItem = 1;

    TRACE("%p, %p, %d\n", ext, pbEncoded, *pcbEncoded);

    if (ext->fCritical)
    {
        items[cItem].pvStructInfo = &ext->fCritical;
        items[cItem].encodeFunc = CRYPT_AsnEncodeBool;
        cItem++;
    }
    items[cItem].pvStructInfo = &ext->Value;
    items[cItem].encodeFunc = CRYPT_AsnEncodeOctets;
    cItem++;

    ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL,
     pbEncoded, pcbEncoded);
    TRACE("returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL WINAPI CRYPT_AsnEncodeExtensions(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
 PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
    BOOL ret;

    __TRY
    {
        DWORD bytesNeeded, dataLen, lenBytes, i;
        const CERT_EXTENSIONS *exts = (const CERT_EXTENSIONS *)pvStructInfo;

⌨️ 快捷键说明

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