Skip to content

Commit

Permalink
Merge pull request #422 from awslabs/PR-323
Browse files Browse the repository at this point in the history
Make AWS service configurable for generating presigned urls
  • Loading branch information
jdelapla authored Dec 6, 2023
2 parents 83c31c3 + eebe8a7 commit b237bd4
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 10 deletions.
6 changes: 6 additions & 0 deletions src/include/com/amazonaws/kinesis/video/common/Include.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ extern "C" {
*/
#define MAX_REGION_NAME_LEN 128

/**
* Maximum allowed service name length
*/
#define MAX_SERVICE_NAME_LEN 128

/**
* Maximum allowed user agent string length
*/
Expand Down Expand Up @@ -483,6 +488,7 @@ struct __RequestInfo {
//!< NOTE: The body will follow the main struct
UINT32 bodySize; //!< Size of the body in bytes
CHAR url[MAX_URI_CHAR_LEN + 1]; //!< The URL for the request
CHAR service[MAX_SERVICE_NAME_LEN + 1]; //!< The AWS service for the request
CHAR certPath[MAX_PATH_LEN + 1]; //!< CA Certificate path to use - optional
CHAR sslCertPath[MAX_PATH_LEN + 1]; //!< SSL Certificate file path to use - optional
CHAR sslPrivateKeyPath[MAX_PATH_LEN + 1]; //!< SSL Certificate private key file path to use - optional
Expand Down
34 changes: 26 additions & 8 deletions src/source/Common/AwsV4Signer.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ STATUS generateAwsSigV4Signature(PRequestInfo pRequestInfo, PCHAR dateTimeStr, B
hmacSize = SIZEOF(hmac);
CHK_STATUS(generateRequestHmac((PBYTE) pScratchBuf, curSize, (PBYTE) dateTimeStr, SIGNATURE_DATE_STRING_LEN * SIZEOF(CHAR), hmac, &hmacSize));
CHK_STATUS(generateRequestHmac(hmac, hmacSize, (PBYTE) pRequestInfo->region, (UINT32) STRLEN(pRequestInfo->region), hmac, &hmacSize));
CHK_STATUS(generateRequestHmac(hmac, hmacSize, (PBYTE) KINESIS_VIDEO_SERVICE_NAME, (UINT32) STRLEN(KINESIS_VIDEO_SERVICE_NAME), hmac, &hmacSize));
CHK_STATUS(generateRequestHmac(hmac, hmacSize, (PBYTE) pRequestInfo->service, (UINT32) STRNLEN(pRequestInfo->service, MAX_SERVICE_NAME_LEN), hmac,
&hmacSize));
CHK_STATUS(generateRequestHmac(hmac, hmacSize, (PBYTE) AWS_SIG_V4_SIGNATURE_END, (UINT32) STRLEN(AWS_SIG_V4_SIGNATURE_END), hmac, &hmacSize));
CHK_STATUS(generateRequestHmac(hmac, hmacSize, (PBYTE) pSignedStr, signedStrLen * SIZEOF(CHAR), hmac, &hmacSize));

Expand Down Expand Up @@ -117,6 +118,12 @@ STATUS signAwsRequestInfo(PRequestInfo pRequestInfo)

CHK(pRequestInfo != NULL && pRequestInfo->pAwsCredentials != NULL, STATUS_NULL_ARG);

// signAwsRequestInfo is a public api function, if service is not specified default to "kinesisvideo" so no breaking changes are introduced to the
// api
if (pRequestInfo->service[0] == L'\0') {
STRNCPY(pRequestInfo->service, KINESIS_VIDEO_SERVICE_NAME, MAX_SERVICE_NAME_LEN);
}

// Generate the time
CHK_STATUS(generateSignatureDateTime(pRequestInfo->currentTime, dateTimeStr));

Expand Down Expand Up @@ -167,6 +174,12 @@ STATUS signAwsRequestInfoQueryParam(PRequestInfo pRequestInfo)

CHK(pRequestInfo != NULL && pRequestInfo->pAwsCredentials != NULL, STATUS_NULL_ARG);

// signAwsRequestInfoQueryParam is a public api function, if service is not specified default to "kinesisvideo" so no breaking changes are
// introduced to the api
if (pRequestInfo->service[0] == L'\0') {
STRNCPY(pRequestInfo->service, KINESIS_VIDEO_SERVICE_NAME, MAX_SERVICE_NAME_LEN);
}

// Generate the time
CHK_STATUS(generateSignatureDateTime(pRequestInfo->currentTime, dateTimeStr));

Expand Down Expand Up @@ -498,8 +511,13 @@ STATUS generateCanonicalRequestString(PRequestInfo pRequestInfo, PCHAR pRequestS
len = SHA256_DIGEST_LENGTH * 2;
CHK(curLen + len <= requestLen, STATUS_BUFFER_TOO_SMALL);
if (pRequestInfo->body == NULL) {
// Streaming treats this portion as if the body were empty
CHK_STATUS(hexEncodedSha256((PBYTE) EMPTY_STRING, 0, pCurPtr));
if (STRNCMP(pRequestInfo->service, KINESIS_VIDEO_SERVICE_NAME, MAX_SERVICE_NAME_LEN) == 0) {
// Streaming treats this portion as if the body were empty
CHK_STATUS(hexEncodedSha256((PBYTE) EMPTY_STRING, 0, pCurPtr));
} else {
len = (UINT32) (ARRAY_SIZE(PREDEFINED_UNSIGNED_PAYLOAD) - 1);
MEMCPY(pCurPtr, PREDEFINED_UNSIGNED_PAYLOAD, SIZEOF(CHAR) * len);
}
} else {
// standard signing
CHK_STATUS(hexEncodedSha256((PBYTE) pRequestInfo->body, pRequestInfo->bodySize, pCurPtr));
Expand Down Expand Up @@ -678,14 +696,14 @@ STATUS generateCredentialScope(PRequestInfo pRequestInfo, PCHAR dateTimeStr, PCH
CHK(pRequestInfo != NULL && dateTimeStr != NULL && pScopeLen != NULL, STATUS_NULL_ARG);

// Calculate the max string length with a null terminator at the end
scopeLen = SIGNATURE_DATE_TIME_STRING_LEN + 1 + MAX_REGION_NAME_LEN + 1 + (UINT32) STRLEN(KINESIS_VIDEO_SERVICE_NAME) + 1 +
scopeLen = SIGNATURE_DATE_TIME_STRING_LEN + 1 + MAX_REGION_NAME_LEN + 1 + (UINT32) STRNLEN(pRequestInfo->service, MAX_SERVICE_NAME_LEN) + 1 +
(UINT32) STRLEN(AWS_SIG_V4_SIGNATURE_END) + 1;

// Early exit on buffer calculation
CHK(pScope != NULL, retStatus);

scopeLen = (UINT32) SNPRINTF(pScope, *pScopeLen, CREDENTIAL_SCOPE_TEMPLATE, SIGNATURE_DATE_STRING_LEN, dateTimeStr, pRequestInfo->region,
KINESIS_VIDEO_SERVICE_NAME, AWS_SIG_V4_SIGNATURE_END);
pRequestInfo->service, AWS_SIG_V4_SIGNATURE_END);
CHK(scopeLen > 0 && scopeLen <= *pScopeLen, STATUS_BUFFER_TOO_SMALL);

CleanUp:
Expand All @@ -707,15 +725,15 @@ STATUS generateEncodedCredentials(PRequestInfo pRequestInfo, PCHAR dateTimeStr,
CHK(pRequestInfo != NULL && dateTimeStr != NULL && pCredsLen != NULL, STATUS_NULL_ARG);

// Calculate the max string length with '/' and a null terminator at the end
credsLen = MAX_ACCESS_KEY_LEN + 1 + SIGNATURE_DATE_TIME_STRING_LEN + 1 + MAX_REGION_NAME_LEN + 1 + (UINT32) STRLEN(KINESIS_VIDEO_SERVICE_NAME) +
1 + (UINT32) STRLEN(AWS_SIG_V4_SIGNATURE_END) + 1;
credsLen = MAX_ACCESS_KEY_LEN + 1 + SIGNATURE_DATE_TIME_STRING_LEN + 1 + MAX_REGION_NAME_LEN + 1 +
(UINT32) STRNLEN(pRequestInfo->service, MAX_SERVICE_NAME_LEN) + 1 + (UINT32) STRLEN(AWS_SIG_V4_SIGNATURE_END) + 1;

// Early exit on buffer calculation
CHK(pCreds != NULL, retStatus);

credsLen = (UINT32) SNPRINTF(pCreds, *pCredsLen, URL_ENCODED_CREDENTIAL_TEMPLATE, pRequestInfo->pAwsCredentials->accessKeyIdLen,
pRequestInfo->pAwsCredentials->accessKeyId, SIGNATURE_DATE_STRING_LEN, dateTimeStr, pRequestInfo->region,
KINESIS_VIDEO_SERVICE_NAME, AWS_SIG_V4_SIGNATURE_END);
pRequestInfo->service, AWS_SIG_V4_SIGNATURE_END);
CHK(credsLen > 0 && credsLen <= *pCredsLen, STATUS_BUFFER_TOO_SMALL);

CleanUp:
Expand Down
6 changes: 4 additions & 2 deletions src/source/Common/AwsV4Signer.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ extern "C" {
#define AUTH_HEADER_TEMPLATE "%s Credential=%.*s/%s, SignedHeaders=%.*s, Signature=%s"

// Authentication query template
#define AUTH_QUERY_TEMPLATE "&X-Amz-Algorithm=%s&X-Amz-Credential=%s&X-Amz-Date=%s&X-Amz-Expires=%u&X-Amz-SignedHeaders=%.*s"
#define AUTH_QUERY_TEMPLATE "?X-Amz-Algorithm=%s&X-Amz-Credential=%s&X-Amz-Date=%s&X-Amz-Expires=%u&X-Amz-SignedHeaders=%.*s"

// Token query param template
#define SECURITY_TOKEN_PARAM_TEMPLATE "&X-Amz-Security-Token=%s"

// Authentication query template
#define AUTH_QUERY_TEMPLATE_WITH_TOKEN \
"&X-Amz-Algorithm=%s&X-Amz-Credential=%s&X-Amz-Date=%s&X-Amz-Expires=%u&X-Amz-SignedHeaders=%.*s" SECURITY_TOKEN_PARAM_TEMPLATE
"?X-Amz-Algorithm=%s&X-Amz-Credential=%s&X-Amz-Date=%s&X-Amz-Expires=%u&X-Amz-SignedHeaders=%.*s" SECURITY_TOKEN_PARAM_TEMPLATE

// Signature query param template
#define SIGNATURE_PARAM_TEMPLATE "&X-Amz-Signature=%s"
Expand All @@ -82,6 +82,8 @@ extern "C" {

#define KVS_MAX_HMAC_SIZE 64

#define PREDEFINED_UNSIGNED_PAYLOAD "UNSIGNED-PAYLOAD"

////////////////////////////////////////////////////
// Function definitions
////////////////////////////////////////////////////
Expand Down

0 comments on commit b237bd4

Please sign in to comment.