static int rtCrX509TbsCertificate_CheckSanityExtra(PCRTCRX509TBSCERTIFICATE pThis, uint32_t fFlags,
                                                   PRTERRINFO pErrInfo, const char *pszErrorTag)
{
    if (   RTAsn1Integer_IsPresent(&pThis->T0.Version)
        && RTAsn1Integer_UnsignedCompareWithU32(&pThis->T0.Version, RTCRX509TBSCERTIFICATE_V1) != 0
        && RTAsn1Integer_UnsignedCompareWithU32(&pThis->T0.Version, RTCRX509TBSCERTIFICATE_V2) != 0
        && RTAsn1Integer_UnsignedCompareWithU32(&pThis->T0.Version, RTCRX509TBSCERTIFICATE_V3) != 0)
        return RTErrInfoSetF(pErrInfo, VERR_CR_X509_TBSCERT_UNSUPPORTED_VERSION,
                             "%s: Unknown Version number: %llu",
                             pszErrorTag, pThis->T0.Version.uValue.u);

    if (   pThis->SerialNumber.Asn1Core.cb < 1
        || pThis->SerialNumber.Asn1Core.cb > 1024)
        return RTErrInfoSetF(pErrInfo, VERR_CR_X509_TBSCERT_SERIAL_NUMBER_OUT_OF_BOUNDS,
                             "%s: Bad SerialNumber length: %u", pszErrorTag, pThis->SerialNumber.Asn1Core.cb);

    if (  (   RTAsn1BitString_IsPresent(&pThis->T1.IssuerUniqueId)
           || RTAsn1BitString_IsPresent(&pThis->T2.SubjectUniqueId))
        && RTAsn1Integer_UnsignedCompareWithU32(&pThis->T0.Version, RTCRX509TBSCERTIFICATE_V2) < 0)
        return RTErrInfoSetF(pErrInfo, VERR_CR_X509_TBSCERT_UNIQUE_IDS_REQ_V2,
                             "%s: IssuerUniqueId and SubjectUniqueId requires version 2", pszErrorTag);

    if (   RTCrX509Extensions_IsPresent(&pThis->T3.Extensions)
        && RTAsn1Integer_UnsignedCompareWithU32(&pThis->T0.Version, RTCRX509TBSCERTIFICATE_V3) < 0)
        return RTErrInfoSetF(pErrInfo, VERR_CR_X509_TBSCERT_EXTS_REQ_V3, "%s: Extensions requires version 3", pszErrorTag);

    return VINF_SUCCESS;
}
示例#2
0
RTDECL(int) RTAsn1Integer_CheckSanity(PCRTASN1INTEGER pThis, uint32_t fFlags, PRTERRINFO pErrInfo, const char *pszErrorTag)
{
    RT_NOREF_PV(fFlags);
    if (RT_UNLIKELY(!RTAsn1Integer_IsPresent(pThis)))
        return RTErrInfoSetF(pErrInfo, VERR_ASN1_NOT_PRESENT, "%s: Missing (INTEGER).", pszErrorTag);
    return VINF_SUCCESS;
}
示例#3
0
RTDECL(int) RTAsn1Integer_Enum(PRTASN1INTEGER pThis, PFNRTASN1ENUMCALLBACK pfnCallback, uint32_t uDepth, void *pvUser)
{
    Assert(pThis && (!RTAsn1Integer_IsPresent(pThis) || pThis->Asn1Core.pOps == &g_RTAsn1Integer_Vtable));

    /* No children to enumerate. */
    return VINF_SUCCESS;
}
示例#4
0
RTDECL(int) RTAsn1Integer_Clone(PRTASN1INTEGER pThis, PCRTASN1INTEGER pSrc, PCRTASN1ALLOCATORVTABLE pAllocator)
{
    AssertPtr(pSrc); AssertPtr(pThis); AssertPtr(pAllocator);
    RT_ZERO(*pThis);
    if (RTAsn1Integer_IsPresent(pSrc))
    {
        AssertReturn(pSrc->Asn1Core.pOps == &g_RTAsn1Integer_Vtable, VERR_INTERNAL_ERROR_3);

        int rc;
        if (   pSrc->Asn1Core.cb != 1
            || pSrc->uValue.u >= RT_ELEMENTS(g_abSmall))
        {
            /* Value is too large, copy it. */
            rc = RTAsn1Core_CloneContent(&pThis->Asn1Core, &pSrc->Asn1Core, pAllocator);
            if (RT_FAILURE(rc))
                return rc;
        }
        else
        {
            /* Use one of the const values. */
            rc = RTAsn1Core_CloneNoContent(&pThis->Asn1Core, &pSrc->Asn1Core);
            if (RT_FAILURE(rc))
                return rc;
            Assert(g_abSmall[pSrc->uValue.u] == pSrc->uValue.u);
            pThis->Asn1Core.uData.pv = (void *)&g_abSmall[pSrc->uValue.u];
        }
        pThis->uValue.u = pSrc->uValue.u;
    }
    return VINF_SUCCESS;
}
示例#5
0
RTDECL(int) RTAsn1Integer_UnsignedCompare(PCRTASN1INTEGER pLeft, PCRTASN1INTEGER pRight)
{
    Assert(pLeft  && (!RTAsn1Integer_IsPresent(pLeft)  || pLeft->Asn1Core.pOps  == &g_RTAsn1Integer_Vtable));
    Assert(pRight && (!RTAsn1Integer_IsPresent(pRight) || pRight->Asn1Core.pOps == &g_RTAsn1Integer_Vtable));

    int iDiff;
    if (RTAsn1Integer_IsPresent(pLeft))
    {
        if (RTAsn1Integer_IsPresent(pRight))
        {
            if (   pLeft->Asn1Core.cb > 8
                || pRight->Asn1Core.cb > 8)
            {
                uint32_t iLeft  = RTAsn1Integer_UnsignedLastBit(pLeft);
                uint32_t iRight = RTAsn1Integer_UnsignedLastBit(pRight);
                if (iLeft != iRight)
                    return iLeft < iRight ? -1 : 1;

                uint32_t i = iLeft / 8;
                if (i > 8)
                {
                    uint8_t const *pbLeft  = &pLeft->Asn1Core.uData.pu8[pLeft->Asn1Core.cb - i - 1];
                    uint8_t const *pbRight = &pRight->Asn1Core.uData.pu8[pRight->Asn1Core.cb - i - 1];
                    for (;;)
                    {
                        if (*pbLeft != *pbRight)
                            return *pbLeft < *pbRight ? -1 : 1;
                        if (--i <= 8)
                            break;
                        pbLeft++;
                        pbRight++;
                    }
                }
            }

            if (pLeft->uValue.u == pRight->uValue.u)
                iDiff = 0;
            else
                iDiff = pLeft->uValue.u < pRight->uValue.u ? -1 : 1;
        }
        else
            iDiff = -1;
    }
    else
        iDiff = 0 - (int)RTAsn1Integer_IsPresent(pRight);
    return iDiff;
}
示例#6
0
RTDECL(void) RTAsn1Integer_Delete(PRTASN1INTEGER pThis)
{
    if (   pThis
        && RTAsn1Integer_IsPresent(pThis))
    {
        Assert(pThis->Asn1Core.pOps == &g_RTAsn1Integer_Vtable);

        RTAsn1ContentFree(&pThis->Asn1Core);
        RT_ZERO(*pThis);
    }
}
示例#7
0
RTDECL(int) RTAsn1Integer_ToBigNum(PCRTASN1INTEGER pThis, PRTBIGNUM pBigNum, uint32_t fBigNumInit)
{
    AssertReturn(!(fBigNumInit & ~(  RTBIGNUMINIT_F_SENSITIVE | RTBIGNUMINIT_F_UNSIGNED | RTBIGNUMINIT_F_SIGNED
                                   | RTBIGNUMINIT_F_ENDIAN_LITTLE | RTBIGNUMINIT_F_ENDIAN_BIG)),
                 VERR_INVALID_PARAMETER);
    AssertReturn(RTAsn1Integer_IsPresent(pThis), VERR_INVALID_PARAMETER);

    if (!(fBigNumInit & (RTBIGNUMINIT_F_UNSIGNED | RTBIGNUMINIT_F_SIGNED)))
        fBigNumInit |= RTBIGNUMINIT_F_SIGNED;

    if (!(fBigNumInit & (RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_ENDIAN_LITTLE)))
        fBigNumInit |= RTBIGNUMINIT_F_ENDIAN_BIG;

    return RTBigNumInit(pBigNum, fBigNumInit, pThis->Asn1Core.uData.pv, pThis->Asn1Core.cb);
}
示例#8
0
RTDECL(int) RTAsn1Integer_FromBigNum(PRTASN1INTEGER pThis, PCRTBIGNUM pBigNum, PCRTASN1ALLOCATORVTABLE pAllocator)
{
    AssertPtr(pThis); AssertPtr(pBigNum); AssertPtr(pAllocator);

    /* Be nice and auto init the object. */
    if (!RTAsn1Integer_IsPresent(pThis))
        RTAsn1Integer_Init(pThis, NULL);

    uint32_t cb = RTBigNumByteWidth(pBigNum); Assert(cb > 0);
    int rc = RTAsn1ContentReallocZ(&pThis->Asn1Core, cb, pAllocator);
    if (RT_SUCCESS(rc))
    {
        Assert(cb == pThis->Asn1Core.cb);
        rc = RTBigNumToBytesBigEndian(pBigNum, (void *)pThis->Asn1Core.uData.pv, cb);
        if (RT_SUCCESS(rc))
            rtAsn1Integer_UpdateNativeValue(pThis);
    }
    return rc;
}
示例#9
0
RTDECL(int) RTAsn1Integer_UnsignedCompareWithU32(PCRTASN1INTEGER pThis, uint32_t u32Const)
{
    int iDiff;
    if (RTAsn1Integer_IsPresent(pThis))
    {
        if (pThis->Asn1Core.cb > 8)
        {
            int32_t iLast = RTAsn1Integer_UnsignedLastBit(pThis);
            if (iLast >= 32)
                return 1;
        }

        if (pThis->uValue.u == u32Const)
            iDiff = 0;
        else
            iDiff = pThis->uValue.u < u32Const ? -1 : 1;
    }
    else
        iDiff = 1;
    return iDiff;
}
示例#10
0
RTDECL(int) RTAsn1Integer_ToString(PRTASN1INTEGER pThis, char *pszBuf, size_t cbBuf, uint32_t fFlags, size_t *pcbActual)
{
    AssertReturn(RTAsn1Integer_IsPresent(pThis), VERR_INVALID_PARAMETER);
    AssertReturn(fFlags == 0, VERR_INVALID_FLAGS);

    /*
     * We only do hex conversions via this API.
     * Currently we consider all numbers to be unsigned.
     */
    /** @todo Signed ASN.1 INTEGER. */
    int rc;
    size_t cbActual;
    if (pThis->Asn1Core.cb <= 8)
    {
        cbActual = 2 + pThis->Asn1Core.cb*2 + 1;
        if (cbActual <= cbBuf)
        {
            ssize_t cchFormat = RTStrFormatU64(pszBuf, cbBuf, pThis->uValue.u, 16, (int)cbActual - 1 /*cchWidth*/, 0,
                                               RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD);
            rc = VINF_SUCCESS;
            AssertStmt(cchFormat == (ssize_t)cbActual - 1, rc = VERR_INTERNAL_ERROR_3);
        }
        else
            rc = VERR_BUFFER_OVERFLOW;
    }
    else
    {
        cbActual = pThis->Asn1Core.cb * 3 - 1 /* save one separator */ + 1 /* terminator */;
        if (cbActual <= cbBuf)
        {
            rc = RTStrPrintHexBytes(pszBuf, cbBuf, pThis->Asn1Core.uData.pv, pThis->Asn1Core.cb, RTSTRPRINTHEXBYTES_F_SEP_SPACE);
            Assert(rc == VINF_SUCCESS);
        }
        else
            rc = VERR_BUFFER_OVERFLOW;
    }
    if (pcbActual)
        *pcbActual = cbActual;
    return rc;
}