int AwsSigV4_Sign()

in src/source/restful/aws_signer_v4.c [259:349]


int AwsSigV4_Sign(AwsSigV4Handle xSigV4Handle, char *pcAccessKey, char *pcSecretKey, char *pcRegion, char *pcService, const char *pcXAmzDate)
{
    int xRes = KVS_ERRNO_NONE;
    AwsSigV4_t *pxAwsSigV4 = (AwsSigV4_t *)xSigV4Handle;
    char pcCanonicalReqHexEncSha256[HEX_ENCODED_SHA_256_STRING_SIZE] = {0};
    const mbedtls_md_info_t *pxMdInfo = NULL;
    STRING_HANDLE xStSignedStr = NULL;
    size_t uHmacSize = 0;
    char pHmac[AWS_SIG_V4_MAX_HMAC_SIZE] = {0};
    int i = 0;

    if (pxAwsSigV4 == NULL || pcSecretKey == NULL || pcRegion == NULL || pcService == NULL || pcXAmzDate == NULL)
    {
        xRes = KVS_ERRNO_FAIL;
    }
    /* Do SHA256 on canonical request and then hex encode it. */
    else if (
        prvHexEncodedSha256((const unsigned char *)STRING_c_str(pxAwsSigV4->xStCanonicalRequest), STRING_length(pxAwsSigV4->xStCanonicalRequest), pcCanonicalReqHexEncSha256) !=
        KVS_ERRNO_NONE)
    {
        xRes = KVS_ERRNO_FAIL;
    }
    else if ((pxMdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256)) == NULL)
    {
        xRes = KVS_ERRNO_FAIL;
    }
    /* HMAC size of SHA256 should be 32. */
    else if ((uHmacSize = mbedtls_md_get_size(pxMdInfo)) == 0)
    {
        xRes = KVS_ERRNO_FAIL;
    }
    /* Generate the scope string. */
    else if (STRING_sprintf(pxAwsSigV4->xStScope, TEMPLATE_CANONICAL_SCOPE, SIGNATURE_DATE_STRING_LEN, pcXAmzDate, pcRegion, pcService, AWS_SIG_V4_SIGNATURE_END) != 0)
    {
        xRes = KVS_ERRNO_FAIL;
    }
    /* Generate the signed string. */
    else if (
        (xStSignedStr =
             STRING_construct_sprintf(TEMPLATE_CANONICAL_SIGNED_STRING, AWS_SIG_V4_ALGORITHM, pcXAmzDate, STRING_c_str(pxAwsSigV4->xStScope), pcCanonicalReqHexEncSha256)) == NULL)
    {
        xRes = KVS_ERRNO_FAIL;
    }
    /* Generatue the beginning of the signature. */
    else if (snprintf(pHmac, AWS_SIG_V4_MAX_HMAC_SIZE, TEMPLATE_SIGNATURE_START, AWS_SIG_V4_SIGNATURE_START, pcSecretKey) == 0)
    {
        xRes = KVS_ERRNO_FAIL;
    }
    /* Calculate the HMAC of date, region, service, signature end, and signed string*/
    else if (
        mbedtls_md_hmac(pxMdInfo, (const unsigned char *)pHmac, strlen(pHmac), (const unsigned char *)pcXAmzDate, SIGNATURE_DATE_STRING_LEN, (unsigned char *)pHmac) != 0 ||
        mbedtls_md_hmac(pxMdInfo, (const unsigned char *)pHmac, uHmacSize, (const unsigned char *)pcRegion, strlen(pcRegion), (unsigned char *)pHmac) != 0 ||
        mbedtls_md_hmac(pxMdInfo, (const unsigned char *)pHmac, uHmacSize, (const unsigned char *)pcService, strlen(pcService), (unsigned char *)pHmac) != 0 ||
        mbedtls_md_hmac(
            pxMdInfo, (const unsigned char *)pHmac, uHmacSize, (const unsigned char *)AWS_SIG_V4_SIGNATURE_END, sizeof(AWS_SIG_V4_SIGNATURE_END) - 1, (unsigned char *)pHmac) !=
            0 ||
        mbedtls_md_hmac(
            pxMdInfo, (const unsigned char *)pHmac, uHmacSize, (const unsigned char *)STRING_c_str(xStSignedStr), STRING_length(xStSignedStr), (unsigned char *)pHmac) != 0)
    {
        xRes = KVS_ERRNO_FAIL;
    }
    else
    {
        for (i = 0; i < uHmacSize; i++)
        {
            if (STRING_sprintf(pxAwsSigV4->xStHmacHexEncoded, "%02x", pHmac[i] & 0xFF) != 0)
            {
                xRes = KVS_ERRNO_FAIL;
                break;
            }
        }

        if (xRes == 0)
        {
            if (STRING_sprintf(
                    pxAwsSigV4->xStAuthorization,
                    "AWS4-HMAC-SHA256 Credential=%s/%s, SignedHeaders=%s, Signature=%s",
                    pcAccessKey,
                    STRING_c_str(pxAwsSigV4->xStScope),
                    STRING_c_str(pxAwsSigV4->xStSignedHeaders),
                    STRING_c_str(pxAwsSigV4->xStHmacHexEncoded)) != 0)
            {
                xRes = KVS_ERRNO_FAIL;
            }
        }
    }

    STRING_delete(xStSignedStr);

    return xRes;
}