bool compareBase64StringToRaw()

in xsec/dsig/DSIGAlgorithmHandlerDefault.cpp [56:148]


bool compareBase64StringToRaw(const char* b64Str,
                              unsigned char* raw,
                              unsigned int rawLen,
                              unsigned int maxCompare = 0) {
    // Decode a base64 buffer and then compare the result to a raw buffer
    // Compare at most maxCompare bits (if maxCompare > 0)
    // Note - whilst the other parameters are bytes, maxCompare is bits

    // The div function below takes signed int, so make sure the value
    // is safe to cast.
    if ((int) maxCompare < 0) {

        throw XSECException(XSECException::CryptoProviderError,
                "Comparison length was unsafe");

    }

    unsigned char outputStr[MAXB64BUFSIZE];
    unsigned int outputLen = 0;

    XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();

    if (!b64) {

        throw XSECException(XSECException::CryptoProviderError,
                "Error requesting Base64 object from Crypto Provider");

    }

    Janitor<XSECCryptoBase64> j_b64(b64);

    b64->decodeInit();
    outputLen = b64->decode((unsigned char *) b64Str, (unsigned int) strlen((char *) b64Str), outputStr, MAXB64BUFSIZE);
    outputLen += b64->decodeFinish(&outputStr[outputLen], MAXB64BUFSIZE - outputLen);

    // Compare

    div_t d;
    d.rem = 0;
    d.quot = 0;

    unsigned int maxCompareBytes;

    unsigned int size;

    if (maxCompare > 0) {
        d = div(maxCompare, 8);
        maxCompareBytes = d.quot;
        if (d.rem != 0)
            maxCompareBytes++;

        if (rawLen < maxCompareBytes && outputLen < maxCompareBytes) {
            if (rawLen != outputLen)
                return false;
            size = rawLen;
        }
        else if (rawLen < maxCompareBytes || outputLen < maxCompareBytes) {
            return false;
        }
        else
            size = maxCompareBytes;
    }
    else {

        if (rawLen != outputLen)
            return false;

        size = rawLen;

    }

    // Compare bytes
    unsigned int i, j;
    for (i = 0; i < size; ++ i) {
        if (raw[i] != outputStr[i])
            return false;
    }

    // Compare bits

    char mask = 0x01;
    if (maxCompare != 0) {
        for (j = 0 ; j < (unsigned int) d.rem; ++j) {

            if ((raw[i] & mask) != (outputStr[i] & mask))
                return false;

            mask = mask << 1;
        }
    }

    return true;
}