bool SASToken_Validate()

in src/sastoken.c [38:208]


bool SASToken_Validate(STRING_HANDLE sasToken)
{
    bool result;
    /*Codes_SRS_SASTOKEN_25_025: [**SASToken_Validate shall get the SASToken value by invoking STRING_c_str on the handle.**]***/
    const char* sasTokenArray = STRING_c_str(sasToken);

    /* Codes_SRS_SASTOKEN_25_024: [**If handle is NULL then SASToken_Validate shall return false.**] */
    /* Codes_SRS_SASTOKEN_25_026: [**If STRING_c_str on handle return NULL then SASToken_Validate shall return false.**] */
    if (sasToken == NULL || sasTokenArray == NULL)
    {
        result = false;
    }
    else
    {
        int seStart = -1, seStop = -1;
        int srStart = -1, srStop = -1;
        int sigStart = -1, sigStop = -1;
        int tokenLength = (int)STRING_length(sasToken);
        int i;
        for (i = 0; i < tokenLength; i++)
        {
            if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'e' && sasTokenArray[i + 2] == '=') // Look for se=
            {
                seStart = i + 3;
                if (srStart > 0 && srStop < 0)
                {
                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ') // look for either & or space
                        srStop = i - 1;
                    else if (sasTokenArray[i - 1] == '&')
                        srStop = i - 2;
                    else
                        seStart = -1; // as the format is not either "&se=" or " se="
                }
                else if (sigStart > 0 && sigStop < 0)
                {
                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
                        sigStop = i - 1;
                    else if (sasTokenArray[i - 1] == '&')
                        sigStop = i - 2;
                    else
                        seStart = -1;
                }
            }
            else if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'r' && sasTokenArray[i + 2] == '=') // Look for sr=
            {
                srStart = i + 3;
                if (seStart > 0 && seStop < 0)
                {
                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
                        seStop = i - 1;
                    else if (sasTokenArray[i - 1] == '&')
                        seStop = i - 2;
                    else
                        srStart = -1;
                }
                else if (sigStart > 0 && sigStop < 0)
                {
                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
                        sigStop = i - 1;
                    else if (sasTokenArray[i - 1] == '&')
                        sigStop = i - 2;
                    else
                        srStart = -1;
                }
            }
            else if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'i' && sasTokenArray[i + 2] == 'g' && sasTokenArray[i + 3] == '=') // Look for sig=
            {
                sigStart = i + 4;
                if (srStart > 0 && srStop < 0)
                {
                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
                        srStop = i - 1;
                    else if (sasTokenArray[i - 1] == '&')
                        srStop = i - 2;
                    else
                        sigStart = -1;
                }
                else if (seStart > 0 && seStop < 0)
                {
                    if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
                        seStop = i - 1;
                    else if (sasTokenArray[i - 1] == '&')
                        seStop = i - 2;
                    else
                        sigStart = -1;
                }
            }
        }

        /*Codes_SRS_SASTOKEN_25_027: [**If SASTOKEN does not obey the SASToken format then SASToken_Validate shall return false.**]***/
        /*Codes_SRS_SASTOKEN_25_028: [**SASToken_validate shall check for the presence of sr, se and sig from the token and return false if not found**]***/
        if (seStart < 0 || srStart < 0 || sigStart < 0)
        {
            result = false;
        }
        else
        {
            if (seStop < 0)
            {
                seStop = tokenLength;
            }
            else if (srStop < 0)
            {
                srStop = tokenLength;
            }
            else if (sigStop < 0)
            {
                sigStop = tokenLength;
            }

            if ((seStop <= seStart) ||
                (srStop <= srStart) ||
                (sigStop <= sigStart))
            {
                result = false;
            }
            else
            {
                char* expiryASCII;
                size_t malloc_size = safe_subtract_size_t((size_t)seStop, (size_t)seStart);
                malloc_size = safe_add_size_t(malloc_size, 1);
                /*Codes_SRS_SASTOKEN_25_031: [**If malloc fails during validation then SASToken_Validate shall return false.**]***/
                if (malloc_size == SIZE_MAX ||
                    (expiryASCII = (char*)malloc(malloc_size)) == NULL)
                {
                    LogError("malloc error, size:%zu", malloc_size);
                    result = false;
                }
                else
                {
                    double expiry;
                    // Add the Null terminator here
                    memset(expiryASCII, 0, (size_t)seStop - (size_t)seStart + 1);
                    for (i = seStart; i < seStop; i++)
                    {
                        // The se contains the expiration values, if a & token is encountered then
                        // the se field is complete.
                        if (sasTokenArray[i] == '&')
                        {
                            break;
                        }
                        expiryASCII[i - seStart] = sasTokenArray[i];
                    }
                    expiry = getExpiryValue(expiryASCII);
                    /*Codes_SRS_SASTOKEN_25_029: [**SASToken_validate shall check for expiry time from token and if token has expired then would return false **]***/
                    if (expiry <= 0)
                    {
                        result = false;
                    }
                    else
                    {
                        double secSinceEpoch = get_difftime(get_time(NULL), (time_t)0);
                        if (expiry < secSinceEpoch)
                        {
                            /*Codes_SRS_SASTOKEN_25_029: [**SASToken_validate shall check for expiry time from token and if token has expired then would return false **]***/
                            result = false;
                        }
                        else
                        {
                            /*Codes_SRS_SASTOKEN_25_030: [**SASToken_validate shall return true only if the format is obeyed and the token has not yet expired **]***/
                            result = true;
                        }
                    }
                    free(expiryASCII);
                }
            }
        }
    }

    return result;
}