in source/sigv4.c [3121:3228]
SigV4Status_t SigV4_GenerateHTTPAuthorization( const SigV4Parameters_t * pParams,
char * pAuthBuf,
size_t * authBufLen,
char ** pSignature,
size_t * signatureLen )
{
SigV4Status_t returnStatus = SigV4Success;
CanonicalContext_t canonicalContext;
const char * pAlgorithm = NULL;
char * pSignedHeaders = NULL;
size_t algorithmLen = 0U, signedHeadersLen = 0U, authPrefixLen = 0U;
HmacContext_t hmacContext = { 0 };
SigV4String_t signingKey;
size_t uxBufferLen;
returnStatus = verifyParamsToGenerateAuthHeaderApi( pParams,
pAuthBuf, authBufLen,
pSignature, signatureLen );
if( returnStatus == SigV4Success )
{
assignDefaultArguments( pParams, &pAlgorithm, &algorithmLen );
}
if( returnStatus == SigV4Success )
{
returnStatus = generateCanonicalRequestUntilHeaders( pParams, &canonicalContext,
&pSignedHeaders,
&signedHeadersLen );
}
/* Hash and hex-encode the canonical request to the buffer. */
if( returnStatus == SigV4Success )
{
/* Write HTTP request payload hash to the canonical request. */
returnStatus = writePayloadHashToCanonicalRequest( pParams, &canonicalContext );
}
/* Write the prefix of the Authorization header value. */
if( returnStatus == SigV4Success )
{
LogDebug( ( "Generated Canonical Request: %.*s",
( unsigned int ) ( canonicalContext.uxCursorIndex ),
canonicalContext.pBufProcessing ) );
authPrefixLen = *authBufLen;
returnStatus = generateAuthorizationValuePrefix( pParams,
pAlgorithm, algorithmLen,
pSignedHeaders, signedHeadersLen,
pAuthBuf, &authPrefixLen );
}
/* Write string to sign. */
if( returnStatus == SigV4Success )
{
returnStatus = writeStringToSign( pParams, pAlgorithm, algorithmLen, &canonicalContext );
}
/* Write the signing key. The is done by computing the following function
* where the + operator means concatenation:
* HMAC(HMAC(HMAC(HMAC("AWS4" + kSecret,pDate),pRegion),pService),"aws4_request") */
if( returnStatus == SigV4Success )
{
hmacContext.pCryptoInterface = pParams->pCryptoInterface;
signingKey.pData = ( char * ) &( canonicalContext.pBufProcessing[ canonicalContext.uxCursorIndex ] );
signingKey.dataLen = canonicalContext.bufRemaining;
returnStatus = generateSigningKey( pParams,
&hmacContext,
&signingKey,
&canonicalContext.bufRemaining );
}
/* Use the SigningKey and StringToSign to produce the final signature.
* Note that the StringToSign starts from the beginning of the processing buffer. */
if( returnStatus == SigV4Success )
{
uxBufferLen = canonicalContext.uxCursorIndex;
returnStatus = ( completeHmac( &hmacContext,
signingKey.pData,
signingKey.dataLen,
( char * ) canonicalContext.pBufProcessing,
uxBufferLen,
( char * ) &( canonicalContext.pBufProcessing[ canonicalContext.uxCursorIndex ] ),
pParams->pCryptoInterface->hashDigestLen ) != 0 )
? SigV4HashError : SigV4Success;
}
/* Hex-encode the final signature beforehand to its precalculated
* location in the buffer provided for the Authorization header value. */
if( returnStatus == SigV4Success )
{
SigV4String_t originalHmac;
SigV4String_t hexEncodedHmac;
originalHmac.pData = ( char * ) &( canonicalContext.pBufProcessing[ canonicalContext.uxCursorIndex ] );
originalHmac.dataLen = pParams->pCryptoInterface->hashDigestLen;
hexEncodedHmac.pData = &( pAuthBuf[ authPrefixLen ] );
/* #authBufLen is an overestimate but the validation was already done earlier. */
hexEncodedHmac.dataLen = *authBufLen;
returnStatus = lowercaseHexEncode( &originalHmac,
&hexEncodedHmac );
*pSignature = hexEncodedHmac.pData;
*signatureLen = hexEncodedHmac.dataLen;
*authBufLen = authPrefixLen + ( pParams->pCryptoInterface->hashDigestLen << 1U );
}
return returnStatus;
}