[修改] 增加freeRTOS
1. 版本FreeRTOSv202212.01,命名为kernel;
This commit is contained in:
574
kernel/FreeRTOS-Plus/Source/AWS/sigv4/source/include/sigv4.h
Normal file
574
kernel/FreeRTOS-Plus/Source/AWS/sigv4/source/include/sigv4.h
Normal file
@ -0,0 +1,574 @@
|
||||
/*
|
||||
* SigV4 Library v1.2.0
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file sigv4.h
|
||||
* @brief Interface for the SigV4 Library.
|
||||
*/
|
||||
|
||||
#ifndef SIGV4_H_
|
||||
#define SIGV4_H_
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* SIGV4_DO_NOT_USE_CUSTOM_CONFIG allows building of the SigV4 library without a
|
||||
* config file. If a config file is provided, the SIGV4_DO_NOT_USE_CUSTOM_CONFIG
|
||||
* macro must not be defined.
|
||||
*/
|
||||
#ifndef SIGV4_DO_NOT_USE_CUSTOM_CONFIG
|
||||
#include "sigv4_config.h"
|
||||
#endif
|
||||
|
||||
/* Include config defaults header to get default values of configurations not
|
||||
* defined in sigv4_config.h file. */
|
||||
#include "sigv4_config_defaults.h"
|
||||
|
||||
/* Convenience macros for library optimization */
|
||||
|
||||
/** @addtogroup sigv4_constants
|
||||
* @{
|
||||
*/
|
||||
#define SIGV4_AWS4_HMAC_SHA256 "AWS4-HMAC-SHA256" /**< AWS identifier for SHA256 signing algorithm. */
|
||||
#define SIGV4_AWS4_HMAC_SHA256_LENGTH ( sizeof( SIGV4_AWS4_HMAC_SHA256 ) - 1U ) /**< Length of AWS identifier for SHA256 signing algorithm. */
|
||||
#define SIGV4_HTTP_X_AMZ_DATE_HEADER "x-amz-date" /**< AWS identifier for HTTP date header. */
|
||||
#define SIGV4_HTTP_X_AMZ_SECURITY_TOKEN_HEADER "x-amz-security-token" /**< AWS identifier for security token. */
|
||||
|
||||
#define SIGV4_STREAMING_AWS4_HMAC_SHA256_PAYLOAD "STREAMING-AWS4-HMAC-SHA256-PAYLOAD" /**< S3 identifier for chunked payloads. */
|
||||
/* MISRA Ref 5.4.1 [Macro identifiers] */
|
||||
/* More details at: https://github.com/aws/SigV4-for-AWS-IoT-embedded-sdk/blob/main/MISRA.md#rule-54 */
|
||||
/* coverity[other_declaration] */
|
||||
#define SIGV4_HTTP_X_AMZ_CONTENT_SHA256_HEADER "x-amz-content-sha256" /**< S3 identifier for streaming requests. */
|
||||
#define SIGV4_HTTP_X_AMZ_CONTENT_SHA256_HEADER_LENGTH ( sizeof( SIGV4_HTTP_X_AMZ_CONTENT_SHA256_HEADER ) - 1U ) /**< Length of S3 identifier for streaming requests. */
|
||||
#define SIGV4_HTTP_X_AMZ_STORAGE_CLASS_HEADER "x-amz-storage-class" /**< S3 identifier for reduced streaming redundancy. */
|
||||
|
||||
#define SIGV4_ACCESS_KEY_ID_LENGTH 20U /**< Length of access key ID. */
|
||||
#define SIGV4_SECRET_ACCESS_KEY_LENGTH 40U /**< Length of secret access key. */
|
||||
|
||||
#define SIGV4_ISO_STRING_LEN 16U /**< Length of ISO 8601 date string. */
|
||||
#define SIGV4_EXPECTED_LEN_RFC_3339 20U /**< Length of RFC 3339 date input. */
|
||||
#define SIGV4_EXPECTED_LEN_RFC_5322 29U
|
||||
/**< Length of RFC 5322 date input. */
|
||||
|
||||
/** @}*/
|
||||
|
||||
/**
|
||||
* @defgroup sigv4_canonical_flags SigV4HttpParameters_t Flags
|
||||
* @brief Flags for SigV4HttpParameters_t.flags. These flags inform the library
|
||||
* of parameters already in canonical form.
|
||||
*
|
||||
* Flags should be bitwise-ORed with each other to change the behavior of
|
||||
* #SigV4_GenerateHTTPAuthorization.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sigv4_canonical_flags
|
||||
* @brief Set this flag to indicate that the HTTP request path input is already
|
||||
* canonicalized.
|
||||
*
|
||||
* This flag is valid only for #SigV4HttpParameters_t.flags.
|
||||
*/
|
||||
#define SIGV4_HTTP_PATH_IS_CANONICAL_FLAG 0x1U
|
||||
|
||||
/**
|
||||
* @ingroup sigv4_canonical_flags
|
||||
* @brief Set this flag to indicate that the HTTP request query input is already
|
||||
* canonicalized.
|
||||
*
|
||||
* This flag is valid only for #SigV4HttpParameters_t.flags.
|
||||
*/
|
||||
#define SIGV4_HTTP_QUERY_IS_CANONICAL_FLAG 0x2U
|
||||
|
||||
/**
|
||||
* @ingroup sigv4_canonical_flags
|
||||
* @brief Set this flag to indicate that the HTTP request headers input is
|
||||
* already canonicalized.
|
||||
*
|
||||
* This flag is valid only for #SigV4HttpParameters_t.flags.
|
||||
*/
|
||||
#define SIGV4_HTTP_HEADERS_ARE_CANONICAL_FLAG 0x4U
|
||||
|
||||
/**
|
||||
* @ingroup sigv4_canonical_flags
|
||||
* @brief Set this flag to indicate that the HTTP request payload is
|
||||
* already hashed.
|
||||
*
|
||||
* This flag is valid only for #SigV4HttpParameters_t.flags.
|
||||
*/
|
||||
#define SIGV4_HTTP_PAYLOAD_IS_HASH 0x8U
|
||||
|
||||
/**
|
||||
* @ingroup sigv4_canonical_flags
|
||||
* @brief Set this flag to indicate that the HTTP request path, query, and
|
||||
* headers are all already canonicalized.
|
||||
*
|
||||
* This flag is valid only for #SigV4HttpParameters_t.flags.
|
||||
*/
|
||||
#define SIGV4_HTTP_ALL_ARE_CANONICAL_FLAG 0x7U
|
||||
|
||||
/**
|
||||
* @ingroup sigv4_enum_types
|
||||
* @brief Return status of the SigV4 Library.
|
||||
*/
|
||||
typedef enum SigV4Status
|
||||
{
|
||||
/**
|
||||
* @brief The SigV4 library function completed successfully.
|
||||
*
|
||||
* Functions that may return this value:
|
||||
* - #SigV4_GenerateHTTPAuthorization
|
||||
* - #SigV4_AwsIotDateToIso8601
|
||||
*/
|
||||
SigV4Success,
|
||||
|
||||
/**
|
||||
* @brief The SigV4 library function received an invalid input
|
||||
* parameter.
|
||||
*
|
||||
* Functions that may return this value:
|
||||
* - #SigV4_GenerateHTTPAuthorization
|
||||
* - #SigV4_AwsIotDateToIso8601
|
||||
*/
|
||||
SigV4InvalidParameter,
|
||||
|
||||
/**
|
||||
* @brief The application buffer was not large enough for the specified hash
|
||||
* function.
|
||||
*
|
||||
* Functions that may return this value:
|
||||
* - #SigV4_GenerateHTTPAuthorization
|
||||
*/
|
||||
SigV4InsufficientMemory,
|
||||
|
||||
/**
|
||||
* @brief An error occurred while formatting the provided date header.
|
||||
*
|
||||
* Functions that may return this value:
|
||||
* - #SigV4_AwsIotDateToIso8601
|
||||
*/
|
||||
SigV4ISOFormattingError,
|
||||
|
||||
/**
|
||||
* @brief The maximum number of header parameters was exceeded while parsing
|
||||
* the http header string passed to the library.
|
||||
* The maximum number of supported HTTP headers can be configured
|
||||
* with the SIGV4_MAX_HTTP_HEADER_COUNT macro in the library config file
|
||||
* passed by the application.
|
||||
*
|
||||
* Functions that may return this value:
|
||||
* - #SigV4_GenerateHTTPAuthorization
|
||||
*/
|
||||
SigV4MaxHeaderPairCountExceeded,
|
||||
|
||||
/**
|
||||
* @brief The maximum number of query parameters was exceeded while parsing
|
||||
* the query string passed to the library.
|
||||
* The maximum number of supported query parameters can be configured
|
||||
* with the SIGV4_MAX_QUERY_PAIR_COUNT macro in the library config file
|
||||
* passed by the application.
|
||||
*
|
||||
* Functions that may return this value:
|
||||
* - #SigV4_GenerateHTTPAuthorization
|
||||
*/
|
||||
SigV4MaxQueryPairCountExceeded,
|
||||
|
||||
/**
|
||||
* @brief An error occurred while performing a hash operation.
|
||||
*
|
||||
* Functions that may return this value:
|
||||
* - #SigV4_GenerateHTTPAuthorization
|
||||
*/
|
||||
SigV4HashError,
|
||||
|
||||
/**
|
||||
* @brief HTTP headers parsed to the library are invalid.
|
||||
*
|
||||
* Functions that may return this value:
|
||||
* - #SigV4_GenerateHTTPAuthorization
|
||||
*/
|
||||
SigV4InvalidHttpHeaders
|
||||
} SigV4Status_t;
|
||||
|
||||
/**
|
||||
* @ingroup sigv4_struct_types
|
||||
* @brief The cryptography interface used to supply the user-defined hash
|
||||
* implementation.
|
||||
*/
|
||||
typedef struct SigV4CryptoInterface
|
||||
{
|
||||
/**
|
||||
* @brief Initializes the @p pHashContext.
|
||||
*
|
||||
* @param[in] pHashContext Context used to maintain the hash's current state
|
||||
* during incremental updates.
|
||||
*
|
||||
* @return Zero on success, all other return values are failures.
|
||||
*/
|
||||
int32_t ( * hashInit )( void * pHashContext );
|
||||
|
||||
/**
|
||||
* @brief Calculates an ongoing hash update (SHA-256, for example).
|
||||
*
|
||||
* @param[in] pHashContext Context used to maintain the hash's current state
|
||||
* during incremental updates.
|
||||
* @param[in] pInput Buffer holding the data to hash.
|
||||
* @param[in] inputLen length of the input buffer data.
|
||||
*
|
||||
* @return Zero on success, all other return values are failures.
|
||||
*/
|
||||
int32_t ( * hashUpdate )( void * pHashContext,
|
||||
const uint8_t * pInput,
|
||||
size_t inputLen );
|
||||
|
||||
/**
|
||||
* @brief Calculates the final binary digest of the hash from the context.
|
||||
*
|
||||
* @param[in] pHashContext Context used to maintain the hash's current state
|
||||
* during incremental updates.
|
||||
* @param[out] pOutput The buffer used to place final hash binary digest
|
||||
* output.
|
||||
* @param[in] outputLen The length of the pOutput buffer, which must be
|
||||
* larger than the hash digest length specified in
|
||||
* #SIGV4_HASH_MAX_DIGEST_LENGTH.
|
||||
*
|
||||
* @return Zero on success, all other return values are failures.
|
||||
*/
|
||||
int32_t ( * hashFinal )( void * pHashContext,
|
||||
uint8_t * pOutput,
|
||||
size_t outputLen );
|
||||
|
||||
/**
|
||||
* @brief Context for the hashInit, hashUpdate, and hashFinal interfaces.
|
||||
*/
|
||||
void * pHashContext;
|
||||
|
||||
/**
|
||||
* @brief The block length of the hash function.
|
||||
*/
|
||||
size_t hashBlockLen;
|
||||
|
||||
/**
|
||||
* @brief The digest length of the hash function.
|
||||
*/
|
||||
size_t hashDigestLen;
|
||||
} SigV4CryptoInterface_t;
|
||||
|
||||
/**
|
||||
* @ingroup sigv4_struct_types
|
||||
* @brief Configurations of the HTTP request used to create the Canonical
|
||||
* Request.
|
||||
*/
|
||||
typedef struct SigV4HttpParameters
|
||||
{
|
||||
const char * pHttpMethod; /**< @brief The HTTP method: GET, POST, PUT, etc. */
|
||||
size_t httpMethodLen; /**< @brief Length of pHttpMethod. */
|
||||
|
||||
/**
|
||||
* @brief These flags are used to indicate if the path, query, or headers are already
|
||||
* in the canonical form. This is to bypass the internal sorting, white space
|
||||
* trimming, and encoding done by the library. This is a performance optimization
|
||||
* option. Please see https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
|
||||
* for information on generating a canonical path, query, and headers string.
|
||||
* - #SIGV4_HTTP_PATH_IS_CANONICAL_FLAG 0x1
|
||||
* - #SIGV4_HTTP_QUERY_IS_CANONICAL_FLAG 0x2
|
||||
* - #SIGV4_HTTP_HEADERS_ARE_CANONICAL_FLAG 0x4
|
||||
* - #SIGV4_HTTP_ALL_ARE_CANONICAL_FLAG 0x7
|
||||
*/
|
||||
uint32_t flags;
|
||||
|
||||
/**
|
||||
* @brief The path in the HTTP request. This is the absolute request URI,
|
||||
* which contains everything in the URI following the HTTP host until the
|
||||
* question mark character ("?") that begins any query string parameters
|
||||
* (e.g. "/path/to/item.txt"). If SIGV4_HTTP_PATH_IS_CANONICAL_FLAG is set,
|
||||
* then this input must already be in canonical form.
|
||||
*
|
||||
* @note If there exists no path for the HTTP request, then this can be
|
||||
* NULL.
|
||||
*/
|
||||
const char * pPath;
|
||||
size_t pathLen; /**< @brief Length of pPath. */
|
||||
|
||||
/**
|
||||
* @brief The HTTP request query from the URL, if it exists. This contains all
|
||||
* characters following the question mark character ("?") that denotes the start
|
||||
* of the query. If SIGV4_HTTP_QUERY_IS_CANONICAL_FLAG is set, then this input
|
||||
* must already be in canonical form.
|
||||
*
|
||||
* @note If the HTTP request does not contain query string, this can
|
||||
* be NULL.
|
||||
*/
|
||||
const char * pQuery;
|
||||
size_t queryLen; /**< @brief Length of pQuery. */
|
||||
|
||||
/**
|
||||
* @brief The headers from the HTTP request that we want to sign. This
|
||||
* should be the raw headers in HTTP request format. If
|
||||
* SIGV4_HTTP_HEADERS_IS_CANONICAL_FLAG is set, then this input must
|
||||
* already be in canonical form.
|
||||
*
|
||||
* @note The headers data MUST NOT be empty. For HTTP/1.1 requests, it is
|
||||
* required that the "host" header MUST be part of the SigV4 signature.
|
||||
*/
|
||||
const char * pHeaders;
|
||||
size_t headersLen; /**< @brief Length of pHeaders. */
|
||||
|
||||
/**
|
||||
* @brief The HTTP response body, if one exists (ex. PUT request). If this
|
||||
* body is chunked, then this field should be set with
|
||||
* STREAMING-AWS4-HMAC-SHA256-PAYLOAD.
|
||||
*/
|
||||
const char * pPayload;
|
||||
size_t payloadLen; /**< @brief Length of pPayload. */
|
||||
} SigV4HttpParameters_t;
|
||||
|
||||
/**
|
||||
* @ingroup sigv4_struct_types
|
||||
* @brief Configurations for the AWS credentials used to generate the Signing
|
||||
* Key.
|
||||
*/
|
||||
typedef struct SigV4Credentials
|
||||
{
|
||||
/**
|
||||
* @brief The pAccessKeyId MUST be at least 16 characters long
|
||||
* but not more than 128 characters long.
|
||||
*/
|
||||
const char * pAccessKeyId;
|
||||
size_t accessKeyIdLen; /**< @brief Length of pAccessKeyId. */
|
||||
|
||||
/**
|
||||
* @brief The pSecretAccessKey MUST be at least 40 characters long.
|
||||
*/
|
||||
const char * pSecretAccessKey;
|
||||
size_t secretAccessKeyLen; /**< @brief Length of pSecretAccessKey. */
|
||||
} SigV4Credentials_t;
|
||||
|
||||
/**
|
||||
* @ingroup sigv4_struct_types
|
||||
* @brief Complete configurations required for generating "String to Sign" and
|
||||
* "Signing Key" values.
|
||||
*
|
||||
* Consists of parameter structures #SigV4Credentials_t,
|
||||
* #SigV4CryptoInterface_t, and #SigV4HttpParameters_t, along with date, region,
|
||||
* and service specifications.
|
||||
*/
|
||||
typedef struct SigV4Parameters
|
||||
{
|
||||
/**
|
||||
* @brief The AccessKeyId, SecretAccessKey, and SecurityToken used to
|
||||
* generate the Authorization header.
|
||||
*/
|
||||
SigV4Credentials_t * pCredentials;
|
||||
|
||||
/**
|
||||
* @brief The date in ISO 8601 format, e.g. "20150830T123600Z". This is
|
||||
* always 16 characters long.
|
||||
*/
|
||||
const char * pDateIso8601;
|
||||
|
||||
/**
|
||||
* @brief The algorithm used for SigV4 authentication. If set to NULL,
|
||||
* this will automatically be set to "AWS4-HMAC-SHA256" by default.
|
||||
*/
|
||||
const char * pAlgorithm;
|
||||
|
||||
size_t algorithmLen; /**< @brief Length of pAlgorithm. */
|
||||
|
||||
/**
|
||||
* @brief The target AWS region for the request. Please see
|
||||
* https://docs.aws.amazon.com/general/latest/gr/rande.html for a list of
|
||||
* region names and codes.
|
||||
*/
|
||||
const char * pRegion;
|
||||
size_t regionLen; /**< @brief Length of pRegion. */
|
||||
|
||||
/**
|
||||
* @brief The target AWS service for the request. The service name can be
|
||||
* found as the first segment of the service endpoint. Please see
|
||||
* https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html
|
||||
* (https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html)
|
||||
* for your service of interest.
|
||||
*/
|
||||
const char * pService;
|
||||
size_t serviceLen; /**< @brief Length of pService. */
|
||||
|
||||
/**
|
||||
* @brief The cryptography interface.
|
||||
*/
|
||||
SigV4CryptoInterface_t * pCryptoInterface;
|
||||
|
||||
/**
|
||||
* @brief HTTP specific SigV4 parameters for canonical request calculation.
|
||||
*/
|
||||
SigV4HttpParameters_t * pHttpParameters;
|
||||
} SigV4Parameters_t;
|
||||
|
||||
/**
|
||||
* @brief Generates the HTTP Authorization header value.
|
||||
* @note The API does not support HTTP headers containing empty HTTP header keys or values.
|
||||
*
|
||||
* @param[in] pParams Parameters for generating the SigV4 signature.
|
||||
* @param[out] pAuthBuf Buffer to hold the generated Authorization header value.
|
||||
* @param[in, out] authBufLen Input: the length of @p pAuthBuf, output: the length
|
||||
* of the authorization value written to the buffer.
|
||||
* @param[out] pSignature Location of the signature in the authorization string.
|
||||
* @param[out] signatureLen The length of @p pSignature.
|
||||
*
|
||||
* @return #SigV4Success if successful, error code otherwise.
|
||||
*
|
||||
* <b>Example</b>
|
||||
* @code{c}
|
||||
* // The following example shows how to use the SigV4_GenerateHTTPAuthorization
|
||||
* // function to generate the HTTP Authorization header value for HTTP requests
|
||||
* // to AWS services requiring SigV4 authentication.
|
||||
*
|
||||
* SigV4Status_t status = SigV4Success;
|
||||
*
|
||||
* // Buffer to hold the authorization header.
|
||||
* char pSigv4Auth[ 2048U ];
|
||||
* size_t sigv4AuthLen = sizeof( pSigv4Auth );
|
||||
*
|
||||
* // Pointer to signature in the Authorization header that will be populated in
|
||||
* // pSigv4Auth by the SigV4_GenerateHTTPAuthorization API function.
|
||||
* char * signature = NULL;
|
||||
* size_t signatureLen = 0;
|
||||
*
|
||||
* SigV4Parameters_t sigv4Params =
|
||||
* {
|
||||
* // Parsed temporary credentials obtained from AWS IoT Credential Provider.
|
||||
* .pCredentials = &sigv4Creds,
|
||||
* // Date in ISO8601 format.
|
||||
* .pDateIso8601 = pDateISO8601,
|
||||
* // The AWS region for the request.
|
||||
* .pRegion = AWS_REGION,
|
||||
* .regionLen = strlen( AWS_REGION ),
|
||||
* // The AWS service for the request.
|
||||
* .pService = AWS_SERVICE_NAME,
|
||||
* .serviceLen = strlen( AWS_SERVICE_NAME ),
|
||||
* // SigV4 crypto interface. See SigV4CryptoInterface_t interface documentation.
|
||||
* .pCryptoInterface = &cryptoInterface,
|
||||
* // HTTP parameters for the HTTP request to generate a SigV4 authorization header for.
|
||||
* .pHttpParameters = &sigv4HttpParams
|
||||
* };
|
||||
*
|
||||
* status = SigV4_GenerateHTTPAuthorization( &sigv4Params, pSigv4Auth, &sigv4AuthLen, &signature, &signatureLen );
|
||||
*
|
||||
* if( status != SigV4Success )
|
||||
* {
|
||||
* // Failed to generate authorization header.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
/* @[declare_sigV4_generateHTTPAuthorization_function] */
|
||||
SigV4Status_t SigV4_GenerateHTTPAuthorization( const SigV4Parameters_t * pParams,
|
||||
char * pAuthBuf,
|
||||
size_t * authBufLen,
|
||||
char ** pSignature,
|
||||
size_t * signatureLen );
|
||||
/* @[declare_sigV4_generateHTTPAuthorization_function] */
|
||||
|
||||
/**
|
||||
* @brief Parse the date header value from the AWS IoT response, and generate
|
||||
* the formatted ISO 8601 date required for authentication.
|
||||
*
|
||||
* This is an optional utility function available to the application, to assist
|
||||
* with formatting of the date header obtained from AWS IoT (when requesting a
|
||||
* temporary token or sending a POST request).
|
||||
*
|
||||
* AWS SigV4 authentication requires an ISO 8601 date to be present in the
|
||||
* "x-amz-date" request header, as well as in the credential scope (must be
|
||||
* identical). For additional information on date handling, please see
|
||||
* https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html.
|
||||
*
|
||||
* Acceptable Input Formats:
|
||||
* - RFC 5322 (ex. "Thu, 18 Jan 2018 09:18:06 GMT"), the preferred format in
|
||||
* HTTP 'Date' response headers. If using this format, the date parameter
|
||||
* should match "***, DD 'MMM' YYYY hh:mm:ss GMT" exactly.
|
||||
* - RFC 3339 (ex. "2018-01-18T09:18:06Z"), found occasionally in 'Date' and
|
||||
* expiration headers. If using this format, the date parameter should match
|
||||
* "YYYY-MM-DD'T'hh:mm:ss'Z'" exactly.
|
||||
*
|
||||
* Formatted Output:
|
||||
* - The ISO8601-formatted date will be returned in the form
|
||||
* "YYYYMMDD'T'HHMMSS'Z'" (ex. "20180118T091806Z").
|
||||
*
|
||||
* @param[in] pDate The date header (in
|
||||
* [RFC 3339](https://tools.ietf.org/html/rfc3339) or
|
||||
* [RFC 5322](https://tools.ietf.org/html/rfc5322) formats). An acceptable date
|
||||
* header can be found in the HTTP response returned by AWS IoT. This value
|
||||
* should use UTC (with no time-zone offset), and be exactly 20 or 29 characters
|
||||
* in length (excluding the null character), to comply with RFC 3339 and RFC
|
||||
* 5322 formats, respectively.
|
||||
* @param[in] dateLen The length of the pDate header value. Must be either
|
||||
* SIGV4_EXPECTED_LEN_RFC_3339 or SIGV4_EXPECTED_LEN_RFC_5322, for valid input
|
||||
* parameters.
|
||||
* @param[out] pDateISO8601 The formatted ISO8601-compliant date. The date value
|
||||
* written to this buffer will be exactly 16 characters in length, to comply
|
||||
* with the ISO8601 standard required for SigV4 authentication.
|
||||
* @param[in] dateISO8601Len The length of buffer pDateISO8601. Must be at least
|
||||
* SIGV4_ISO_STRING_LEN bytes, for valid input parameters.
|
||||
*
|
||||
* @return #SigV4Success code if successful, error code otherwise.
|
||||
*
|
||||
*
|
||||
* <b>Example</b>
|
||||
* @code{c}
|
||||
* // The following example shows how to use the SigV4_AwsIotDateToIso8601
|
||||
* // function to convert an AWS IoT date header value to a ISO 8601 date.
|
||||
*
|
||||
* SigV4Status_t status = SigV4Success;
|
||||
* char pDateISO8601[SIGV4_ISO_STRING_LEN] = {0};
|
||||
* size_t pDateISO8601Len = SIGV4_ISO_STRING_LEN;
|
||||
*
|
||||
* // pDate and dateLen are the date header and length which are parsed from
|
||||
* // an AWS IoT Credential Provider HTTP response, using an HTTP library.
|
||||
* status = SigV4_AwsIotDateToIso8601( pDate, dateLen, pDateISO8601, pDateISO8601Len );
|
||||
*
|
||||
* if( status != SigV4Success )
|
||||
* {
|
||||
* // Failed to parse date
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
/* @[declare_sigV4_awsIotDateToIso8601_function] */
|
||||
SigV4Status_t SigV4_AwsIotDateToIso8601( const char * pDate,
|
||||
size_t dateLen,
|
||||
char * pDateISO8601,
|
||||
size_t dateISO8601Len );
|
||||
/* @[declare_sigV4_awsIotDateToIso8601_function] */
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* SIGV4_H_ */
|
||||
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* SigV4 Library v1.2.0
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file sigv4_config_defaults.h
|
||||
* @brief The default values for configuration macros used by the SigV4 Library.
|
||||
*
|
||||
* @note This file should NOT be modified. If custom values are needed for any
|
||||
* configuration macros, a sigv4_config.h file should be provided to the SigV4
|
||||
* Library to override the default values defined in this file. To use the custom
|
||||
* config file, the preprocessor macro SIGV4_DO_NOT_USE_CUSTOM_CONFIG
|
||||
* must NOT be set.
|
||||
*/
|
||||
|
||||
#ifndef SIGV4_CONFIG_DEFAULTS_H_
|
||||
#define SIGV4_CONFIG_DEFAULTS_H_
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* The macro definition for SIGV4_DO_NOT_USE_CUSTOM_CONFIG is for Doxygen
|
||||
* documentation only. */
|
||||
|
||||
/**
|
||||
* @brief Define this macro to build the AWS IoT SigV4 Library without the
|
||||
* custom config file sigv4_config.h.
|
||||
*
|
||||
* Without the custom config, the the AWS IoT SigV4 Library builds with default
|
||||
* values of config macros defined in the sigv4_config_defaults.h file.
|
||||
*
|
||||
* If a custom config file is provided, then
|
||||
* SIGV4_DO_NOT_USE_CUSTOM_CONFIG must not be defined.
|
||||
*
|
||||
* <b>Default value</b>: SIGV4_DO_NOT_USE_CUSTOM_CONFIG is
|
||||
* <b>not</b> defined by default and the library expects a
|
||||
* sigv4_config.h file.
|
||||
*/
|
||||
#ifdef DOXYGEN
|
||||
#define SIGV4_DO_NOT_USE_CUSTOM_CONFIG
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro defining the size of the internal buffer used for incremental
|
||||
* canonicalization and hashing.
|
||||
*
|
||||
* A buffer of this size in bytes is declared on the stack. It should be be
|
||||
* large enough for the digest output of the specified hash function.
|
||||
*
|
||||
* <b>Possible values:</b> Any positive 32 bit integer. <br>
|
||||
* <b>Default value:</b> `1024`
|
||||
*/
|
||||
#ifndef SIGV4_PROCESSING_BUFFER_LENGTH
|
||||
#define SIGV4_PROCESSING_BUFFER_LENGTH 1024U
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro defining the maximum number of headers in the request, used to
|
||||
* assist the library in sorting header fields during canonicalization.
|
||||
*
|
||||
* This macro should be updated if the number of request headers the application
|
||||
* wishes to sign is higher or lower than the default value (100).
|
||||
*
|
||||
* <b>Possible values:</b> Any positive 32 bit integer. <br>
|
||||
* <b>Default value:</b> `100`
|
||||
*/
|
||||
#ifndef SIGV4_MAX_HTTP_HEADER_COUNT
|
||||
#define SIGV4_MAX_HTTP_HEADER_COUNT 100U
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro defining the maximum number of query key/value pairs, used to
|
||||
* assist the library in sorting query keys during canonicalization.
|
||||
*
|
||||
* This macro should be updated if the number of query key/value pairs the
|
||||
* application wishes to sign is higher or lower than the default value (100).
|
||||
*
|
||||
* <b>Possible values:</b> Any positive 32 bit integer. <br>
|
||||
* <b>Default value:</b> `100`
|
||||
*/
|
||||
#ifndef SIGV4_MAX_QUERY_PAIR_COUNT
|
||||
#define SIGV4_MAX_QUERY_PAIR_COUNT 100U
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro used to compute the worst-case stack size when sorting elements
|
||||
* associated with #SIGV4_MAX_QUERY_PAIR_COUNT or #SIGV4_MAX_HTTP_HEADER_COUNT.
|
||||
* Suppose the max of the two aforementioned macros is X, then the macro
|
||||
* below must be set to 2 * ceiling(log(X)/log(2)) where ceiling rounds up
|
||||
* the ones digit if the decimal is greater than 0.
|
||||
* @note If updating #SIGV4_MAX_QUERY_PAIR_COUNT or #SIGV4_MAX_HTTP_HEADER_COUNT,
|
||||
* be sure to update this value based on the formula above.
|
||||
*/
|
||||
#ifndef SIGV4_WORST_CASE_SORT_STACK_SIZE
|
||||
#define SIGV4_WORST_CASE_SORT_STACK_SIZE 14U
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro indicating the largest block size of any hashing
|
||||
* algorithm used for SigV4 authentication i.e. the maximum of all
|
||||
* values specified for the hashBlockLen in #SigV4CryptoInterface_t.
|
||||
* For example, using SHA-512 would require this value to be at least 128.
|
||||
*
|
||||
* <b>Possible values:</b> Any positive 32 bit integer. <br>
|
||||
* <b>Default value:</b> `64`
|
||||
*/
|
||||
#ifndef SIGV4_HASH_MAX_BLOCK_LENGTH
|
||||
#define SIGV4_HASH_MAX_BLOCK_LENGTH 64U
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro defining the maximum digest length of the specified hash function,
|
||||
* used to determine the length of the output buffer.
|
||||
*
|
||||
* This macro should be updated if using a hashing algorithm other than SHA256
|
||||
* (32 byte digest length). For example, using SHA512 would require this
|
||||
* value to be at least 64.
|
||||
*
|
||||
* <b>Possible values:</b> Any positive 32 bit integer. <br>
|
||||
* <b>Default value:</b> `32`
|
||||
*/
|
||||
#ifndef SIGV4_HASH_MAX_DIGEST_LENGTH
|
||||
#define SIGV4_HASH_MAX_DIGEST_LENGTH 32U
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro to statically enable support for canonicalizing the URI,
|
||||
* headers, and query in this library.
|
||||
*
|
||||
* Set this to one to enable the encoding functions used to create the canonical
|
||||
* request.
|
||||
*
|
||||
* <b>Possible values:</b> 0 or 1 <br>
|
||||
* <b>Default value:</b> `1`
|
||||
*/
|
||||
#ifndef SIGV4_USE_CANONICAL_SUPPORT
|
||||
#define SIGV4_USE_CANONICAL_SUPPORT 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro called by the SigV4 library for logging "Error" level
|
||||
* messages.
|
||||
*
|
||||
* To enable error level logging in the SigV4 library, this macro should
|
||||
* be mapped to the application-specific logging implementation that supports
|
||||
* error logging.
|
||||
*
|
||||
* @note This logging macro is called in the SigV4 library with
|
||||
* parameters wrapped in double parentheses to be ISO C89/C90 standard
|
||||
* compliant. For a reference POSIX implementation of the logging macros, refer
|
||||
* to sigv4_config.h files, and the logging-stack in demos folder of the [AWS
|
||||
* IoT Embedded C SDK
|
||||
* repository](https://github.com/aws/aws-iot-device-sdk-embedded-C).
|
||||
*
|
||||
* <b>Default value</b>: Error logging is turned off, and no code is generated
|
||||
* for calls to the macro in the SigV4 library on compilation.
|
||||
*/
|
||||
#ifndef LogError
|
||||
#define LogError( message )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro called by the the SigV4 library for logging "Warning"
|
||||
* level messages.
|
||||
*
|
||||
* To enable warning level logging in the SigV4 library, this macro
|
||||
* should be mapped to the application-specific logging implementation that
|
||||
* supports warning logging.
|
||||
*
|
||||
* @note This logging macro is called in the SigV4 library with
|
||||
* parameters wrapped in double parentheses to be ISO C89/C90 standard
|
||||
* compliant. For a reference POSIX implementation of the logging macros, refer
|
||||
* to sigv4_config.h files, and the logging-stack in demos folder of the [AWS
|
||||
* IoT Embedded C SDK
|
||||
* repository](https://github.com/aws/aws-iot-device-sdk-embedded-C).
|
||||
*
|
||||
* <b>Default value</b>: Warning logs are turned off, and no code is generated
|
||||
* for calls to the macro in the SigV4 library on compilation.
|
||||
*/
|
||||
#ifndef LogWarn
|
||||
#define LogWarn( message )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro called by the the SigV4 library for logging "Info" level
|
||||
* messages.
|
||||
*
|
||||
* To enable info level logging in the SigV4 library, this macro should
|
||||
* be mapped to the application-specific logging implementation that supports
|
||||
* info logging.
|
||||
*
|
||||
* @note This logging macro is called in the SigV4 library with
|
||||
* parameters wrapped in double parentheses to be ISO C89/C90 standard
|
||||
* compliant. For a reference POSIX implementation of the logging macros, refer
|
||||
* to sigv4_config.h files, and the logging-stack in demos folder of the [AWS
|
||||
* IoT Embedded C SDK
|
||||
* repository](https://github.com/aws/aws-iot-device-sdk-embedded-C).
|
||||
*
|
||||
* <b>Default value</b>: Info logging is turned off, and no code is generated
|
||||
* for calls to the macro in the SigV4 library on compilation.
|
||||
*/
|
||||
#ifndef LogInfo
|
||||
#define LogInfo( message )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro called by the the SigV4 library for logging "Debug"
|
||||
* level messages.
|
||||
*
|
||||
* To enable debug level logging from SigV4 library, this macro should
|
||||
* be mapped to the application-specific logging implementation that supports
|
||||
* debug logging.
|
||||
*
|
||||
* @note This logging macro is called in the SigV4 library with
|
||||
* parameters wrapped in double parentheses to be ISO C89/C90 standard
|
||||
* compliant. For a reference POSIX implementation of the logging macros, refer
|
||||
* to sigv4_config.h files, and the logging-stack in demos folder of the [AWS
|
||||
* IoT Embedded C SDK
|
||||
* repository](https://github.com/aws/aws-iot-device-sdk-embedded-C).
|
||||
*
|
||||
* <b>Default value</b>: Debug logging is turned off, and no code is generated
|
||||
* for calls to the macro in the SigV4 library on compilation.
|
||||
*/
|
||||
#ifndef LogDebug
|
||||
#define LogDebug( message )
|
||||
#endif
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* ifndef SIGV4_CONFIG_DEFAULTS_H_ */
|
||||
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* SigV4 Library v1.2.0
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file sigv4_internal.h
|
||||
* @brief Internal definitions for the SigV4 Library.
|
||||
*/
|
||||
|
||||
#ifndef SIGV4_INTERNAL_H_
|
||||
#define SIGV4_INTERNAL_H_
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* SIGV4_DO_NOT_USE_CUSTOM_CONFIG allows building of the SigV4 library without a
|
||||
* config file. If a config file is provided, the SIGV4_DO_NOT_USE_CUSTOM_CONFIG
|
||||
* macro must not be defined.
|
||||
*/
|
||||
#ifndef SIGV4_DO_NOT_USE_CUSTOM_CONFIG
|
||||
#include "sigv4_config.h"
|
||||
#endif
|
||||
|
||||
/* Include config defaults header to get default values of configurations not
|
||||
* defined in sigv4_config.h file. */
|
||||
#include "sigv4_config_defaults.h"
|
||||
|
||||
/* Constants for date verification. */
|
||||
#define YEAR_MIN 1900L /**< Earliest year accepted. */
|
||||
#define MONTH_ASCII_LEN 3U /**< Length of month abbreviations. */
|
||||
|
||||
/**
|
||||
* @brief Month name abbreviations for RFC 5322 date parsing.
|
||||
*/
|
||||
#define MONTH_NAMES { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }
|
||||
|
||||
/**
|
||||
* @brief Number of days in each respective month.
|
||||
*/
|
||||
#define MONTH_DAYS { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
||||
|
||||
#define FORMAT_RFC_3339 "%4Y-%2M-%2DT%2h:%2m:%2sZ" /**< Format string to parse RFC 3339 date. */
|
||||
#define FORMAT_RFC_3339_LEN sizeof( FORMAT_RFC_3339 ) - 1U /**< Length of the RFC 3339 format string. */
|
||||
|
||||
#define FORMAT_RFC_5322 "%3*, %2D %3M %4Y %2h:%2m:%2s GMT" /**< Format string to parse RFC 5322 date. */
|
||||
#define FORMAT_RFC_5322_LEN sizeof( FORMAT_RFC_5322 ) - 1U /**< Length of the RFC 3339 format string. */
|
||||
|
||||
#define ISO_YEAR_LEN 4U /**< Length of year value in ISO 8601 date. */
|
||||
#define ISO_NON_YEAR_LEN 2U /**< Length of non-year values in ISO 8601 date. */
|
||||
|
||||
#define ISO_DATE_SCOPE_LEN 8U /**< Length of date substring used in credential scope. */
|
||||
|
||||
/* SigV4 related string literals and lengths. */
|
||||
|
||||
/**
|
||||
* @brief The separator between each component of the credential scope.
|
||||
*/
|
||||
#define CREDENTIAL_SCOPE_SEPARATOR '/'
|
||||
#define CREDENTIAL_SCOPE_SEPARATOR_LEN 1U /**< The length of #CREDENTIAL_SCOPE_SEPARATOR. */
|
||||
|
||||
/**
|
||||
* @brief The last component that terminates the credential scope.
|
||||
*/
|
||||
#define CREDENTIAL_SCOPE_TERMINATOR "aws4_request"
|
||||
#define CREDENTIAL_SCOPE_TERMINATOR_LEN ( sizeof( CREDENTIAL_SCOPE_TERMINATOR ) - 1U ) /**< The length of #CREDENTIAL_SCOPE_TERMINATOR. */
|
||||
|
||||
/**
|
||||
* @brief Default value when HttpParameters_t.pPath == NULL.
|
||||
*/
|
||||
#define HTTP_EMPTY_PATH "/"
|
||||
#define HTTP_EMPTY_PATH_LEN ( sizeof( HTTP_EMPTY_PATH ) - 1U ) /**< The length of #HTTP_EMPTY_PATH. */
|
||||
|
||||
#define URI_ENCODED_SPECIAL_CHAR_SIZE 3U /**< The size of an encoded URI special character. */
|
||||
#define URI_DOUBLE_ENCODED_EQUALS_CHAR_SIZE 5U /**< The size of the double-encoded "=" character. */
|
||||
|
||||
#define LINEFEED_CHAR '\n' /**< A linefeed character used to build the canonical request. */
|
||||
#define LINEFEED_CHAR_LEN 1U /**< The length of #LINEFEED_CHAR. */
|
||||
|
||||
#define HTTP_REQUEST_LINE_ENDING "\r\n" /**< The string used in non-canonicalized HTTP headers to separate header entries in HTTP request. */
|
||||
#define HTTP_REQUEST_LINE_ENDING_LEN ( sizeof( HTTP_REQUEST_LINE_ENDING ) - 1U ) /**< The length of #HTTP_REQUEST_LINE_ENDING. */
|
||||
|
||||
#define SPACE_CHAR ' ' /**< A linefeed character used to build the Authorization header value. */
|
||||
#define SPACE_CHAR_LEN 1U /**< The length of #SPACE_CHAR. */
|
||||
|
||||
#define S3_SERVICE_NAME "s3" /**< S3 is the only service where the URI must only be encoded once. */
|
||||
#define S3_SERVICE_NAME_LEN ( sizeof( S3_SERVICE_NAME ) - 1U ) /**< The length of #S3_SERVICE_NAME. */
|
||||
|
||||
#define SIGV4_HMAC_SIGNING_KEY_PREFIX "AWS4" /**< HMAC signing key prefix. */
|
||||
#define SIGV4_HMAC_SIGNING_KEY_PREFIX_LEN ( sizeof( SIGV4_HMAC_SIGNING_KEY_PREFIX ) - 1U ) /**< The length of #SIGV4_HMAC_SIGNING_KEY_PREFIX. */
|
||||
|
||||
#define AUTH_CREDENTIAL_PREFIX "Credential=" /**< The prefix that goes before the credential value in the Authorization header value. */
|
||||
#define AUTH_CREDENTIAL_PREFIX_LEN ( sizeof( AUTH_CREDENTIAL_PREFIX ) - 1U ) /**< The length of #AUTH_CREDENTIAL_PREFIX. */
|
||||
#define AUTH_SEPARATOR ", " /**< The separator between each component in the Authorization header value. */
|
||||
#define AUTH_SEPARATOR_LEN ( sizeof( AUTH_SEPARATOR ) - 1U ) /**< The length of #AUTH_SEPARATOR. */
|
||||
#define AUTH_SIGNED_HEADERS_PREFIX "SignedHeaders=" /**< The prefix that goes before the signed headers in the Authorization header value. */
|
||||
#define AUTH_SIGNED_HEADERS_PREFIX_LEN ( sizeof( AUTH_SIGNED_HEADERS_PREFIX ) - 1U ) /**< The length of #AUTH_SIGNED_HEADERS_PREFIX. */
|
||||
#define AUTH_SIGNATURE_PREFIX "Signature=" /**< The prefix that goes before the signature in the Authorization header value. */
|
||||
#define AUTH_SIGNATURE_PREFIX_LEN ( sizeof( AUTH_SIGNATURE_PREFIX ) - 1U ) /**< The length of #AUTH_SIGNATURE_PREFIX. */
|
||||
|
||||
#define HMAC_INNER_PAD_BYTE ( 0x36U ) /**< The "ipad" byte used for generating the inner key in the HMAC calculation process. */
|
||||
#define HMAC_OUTER_PAD_BYTE ( 0x5CU ) /**< The "opad" byte used for generating the outer key in the HMAC calculation process. */
|
||||
#define HMAX_IPAD_XOR_OPAD_BYTE ( 0x6AU ) /**< The XOR of the "ipad" and "opad" bytes to extract outer key from inner key. */
|
||||
|
||||
/**
|
||||
* @brief A helper macro to print insufficient memory errors.
|
||||
*/
|
||||
#define LOG_INSUFFICIENT_MEMORY_ERROR( purposeOfWrite, bytesExceeded ) \
|
||||
{ \
|
||||
LogError( ( "Unable to " purposeOfWrite ": Insufficient memory configured in SIGV4_PROCESSING_BUFFER_LENGTH macro. BytesExceeded=%lu", \
|
||||
( unsigned long ) ( bytesExceeded ) ) ); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A helper macro to test if a flag is set.
|
||||
*/
|
||||
#define FLAG_IS_SET( bits, flag ) ( ( ( bits ) & ( flag ) ) == ( flag ) )
|
||||
|
||||
/**
|
||||
* @brief A helper macro to determine if a character is whitespace.
|
||||
* @note The ctype function isspace() returns true for the following characters:
|
||||
* ` `, `\t`, `\n`, `\v`, `\f`, `\r`. However, according to RFC5234:
|
||||
* https://datatracker.ietf.org/doc/html/rfc5234#appendix-B.1
|
||||
* the only whitespace characters in an HTTP header are spaces and
|
||||
* horizontal tabs.
|
||||
*/
|
||||
#define isWhitespace( c ) ( ( ( c ) == ' ' ) || ( ( c ) == '\t' ) )
|
||||
|
||||
/**
|
||||
* @brief An aggregator representing the individually parsed elements of the
|
||||
* user-provided date parameter. This is used to verify the complete date
|
||||
* representation, and construct the final ISO 8601 string.
|
||||
*/
|
||||
typedef struct SigV4DateTime
|
||||
{
|
||||
int32_t tm_year; /**< Year (1900 or later) */
|
||||
int32_t tm_mon; /**< Month (1 to 12) */
|
||||
int32_t tm_mday; /**< Day of Month (1 to 28/29/30/31) */
|
||||
int32_t tm_hour; /**< Hour (0 to 23) */
|
||||
int32_t tm_min; /**< Minutes (0 to 59) */
|
||||
int32_t tm_sec; /**< Seconds (0 to 60) */
|
||||
} SigV4DateTime_t;
|
||||
|
||||
/**
|
||||
* @brief A library structure holding the string and length values of parameters to
|
||||
* be sorted and standardized. This allows for a layer of abstraction during the
|
||||
* canonicalization step of the V4 signing process.
|
||||
*/
|
||||
typedef struct SigV4String
|
||||
{
|
||||
char * pData; /**< SigV4 string data */
|
||||
size_t dataLen; /**< Length of pData */
|
||||
} SigV4String_t;
|
||||
|
||||
/**
|
||||
* @brief A library structure holding the string and length values of parameters to
|
||||
* be sorted and standardized. This allows for a layer of abstraction during the
|
||||
* canonicalization step of the V4 signing process.
|
||||
*/
|
||||
typedef struct SigV4ConstString
|
||||
{
|
||||
const char * pData; /**< SigV4 string data */
|
||||
size_t dataLen; /**< Length of pData */
|
||||
} SigV4ConstString_t;
|
||||
|
||||
/**
|
||||
* @brief A key-value pair data structure that allows for sorting of SigV4
|
||||
* string values using internal comparison functions, and provides additional
|
||||
* stability to quickSort(), to comply with Misra rule 21.9.
|
||||
*/
|
||||
typedef struct SigV4KeyValuePair
|
||||
{
|
||||
SigV4ConstString_t key; /**< SigV4 string identifier */
|
||||
SigV4ConstString_t value; /**< SigV4 data */
|
||||
} SigV4KeyValuePair_t;
|
||||
|
||||
/**
|
||||
* @brief An aggregator to maintain the internal state of canonicalization
|
||||
* during intermediate calculations.
|
||||
*/
|
||||
typedef struct CanonicalContext
|
||||
{
|
||||
SigV4KeyValuePair_t pQueryLoc[ SIGV4_MAX_QUERY_PAIR_COUNT ]; /**< Query pointers used during sorting. */
|
||||
SigV4KeyValuePair_t pHeadersLoc[ SIGV4_MAX_HTTP_HEADER_COUNT ]; /**< Header pointers used during sorting. */
|
||||
|
||||
uint8_t pBufProcessing[ SIGV4_PROCESSING_BUFFER_LENGTH ]; /**< Internal calculation buffer used during canonicalization. */
|
||||
char * pBufCur; /**< pBufProcessing cursor. */
|
||||
size_t bufRemaining; /**< pBufProcessing value used during internal calculation. */
|
||||
const char * pHashPayloadLoc; /**< Pointer used to store the location of hashed HTTP request payload. */
|
||||
size_t hashPayloadLen; /**< Length of hashed HTTP request payload. */
|
||||
} CanonicalContext_t;
|
||||
|
||||
/**
|
||||
* @brief An aggregator to maintain the internal state of HMAC
|
||||
* calculations.
|
||||
*/
|
||||
typedef struct HmacContext
|
||||
{
|
||||
/**
|
||||
* @brief The cryptography interface.
|
||||
*/
|
||||
const SigV4CryptoInterface_t * pCryptoInterface;
|
||||
|
||||
/**
|
||||
* @brief All accumulated key data.
|
||||
*/
|
||||
uint8_t key[ SIGV4_HASH_MAX_BLOCK_LENGTH ];
|
||||
|
||||
/**
|
||||
* @brief The length of the accumulated key data.
|
||||
*/
|
||||
size_t keyLen;
|
||||
} HmacContext_t;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* ifndef SIGV4_INTERNAL_H_ */
|
||||
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* SigV4 Library v1.2.0
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file sigv4_quicksort.h
|
||||
* @brief Declaration of Quicksort function for the SigV4 Library.
|
||||
*/
|
||||
|
||||
#ifndef SIGV4_QUICKSORT_H_
|
||||
#define SIGV4_QUICKSORT_H_
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* SIGV4_DO_NOT_USE_CUSTOM_CONFIG allows building of the SigV4 library without a
|
||||
* config file. If a config file is provided, the SIGV4_DO_NOT_USE_CUSTOM_CONFIG
|
||||
* macro must not be defined.
|
||||
*/
|
||||
#ifndef SIGV4_DO_NOT_USE_CUSTOM_CONFIG
|
||||
#include "sigv4_config.h"
|
||||
#endif
|
||||
|
||||
/* Include config defaults header to get default values of configurations not
|
||||
* defined in sigv4_config.h file. */
|
||||
#include "sigv4_config_defaults.h"
|
||||
|
||||
/**
|
||||
* @brief The comparison function used for sorting.
|
||||
* @param[in] pFirstVal The first value to compare
|
||||
* @param[in] pSecondVal The second value to compare
|
||||
*
|
||||
* @return A value less than 0 if @p pFirstVal is less than
|
||||
* @p pSecondVal. Otherwise, greater than 0.
|
||||
*/
|
||||
typedef int32_t ( * ComparisonFunc_t )( const void * pFirstVal,
|
||||
const void * pSecondVal );
|
||||
|
||||
/**
|
||||
* @brief Perform quicksort on an array.
|
||||
*
|
||||
* @param[in] pArray The array to be sorted.
|
||||
* @param[in] numItems The number of items in an array.
|
||||
* @param[in] itemSize The amount of memory per entry in the array.
|
||||
* @param[out] comparator The comparison function to determine if one item is less than another.
|
||||
*/
|
||||
void quickSort( void * pArray,
|
||||
size_t numItems,
|
||||
size_t itemSize,
|
||||
ComparisonFunc_t comparator );
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* ifndef SIGV4_QUICKSORT_H_ */
|
||||
3293
kernel/FreeRTOS-Plus/Source/AWS/sigv4/source/sigv4.c
Normal file
3293
kernel/FreeRTOS-Plus/Source/AWS/sigv4/source/sigv4.c
Normal file
File diff suppressed because it is too large
Load Diff
248
kernel/FreeRTOS-Plus/Source/AWS/sigv4/source/sigv4_quicksort.c
Normal file
248
kernel/FreeRTOS-Plus/Source/AWS/sigv4/source/sigv4_quicksort.c
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* SigV4 Library v1.2.0
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file sigv4_quicksort.c
|
||||
* @brief Implements an Iterative Quicksort Algorithm for the SigV4 Library.
|
||||
*/
|
||||
|
||||
#include "sigv4_quicksort.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* @brief Push a value to the stack.
|
||||
*/
|
||||
#define PUSH_STACK( valueToPush, stack, index ) \
|
||||
{ \
|
||||
( stack )[ ( index ) ] = ( valueToPush ); \
|
||||
++( index ); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pop a value from the stack.
|
||||
*/
|
||||
#define POP_STACK( valueToPop, stack, index ) \
|
||||
{ \
|
||||
--( index ); \
|
||||
( valueToPop ) = ( stack )[ ( index ) ]; \
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief A helper function to swap the value of two pointers
|
||||
* given their sizes.
|
||||
*
|
||||
* @param[in] pFirstItem The item to swap with @p pSecondItem.
|
||||
* @param[in] pSecondItem The item to swap with @p pFirstItem.
|
||||
* @param[in] itemSize The amount of memory per entry in the array.
|
||||
*/
|
||||
static void swap( void * pFirstItem,
|
||||
void * pSecondItem,
|
||||
size_t itemSize );
|
||||
|
||||
/**
|
||||
* @brief A helper function to perform quicksort on a subarray.
|
||||
*
|
||||
* @param[in] pArray The array to be sorted.
|
||||
* @param[in] low The low index of the array.
|
||||
* @param[in] high The high index of the array.
|
||||
* @param[in] itemSize The amount of memory per entry in the array.
|
||||
* @param[out] comparator The comparison function to determine if one item is less than another.
|
||||
*/
|
||||
static void quickSortHelper( void * pArray,
|
||||
size_t low,
|
||||
size_t high,
|
||||
size_t itemSize,
|
||||
ComparisonFunc_t comparator );
|
||||
|
||||
/**
|
||||
* @brief A helper function to partition a subarray using the last element
|
||||
* of the array as the pivot. All items smaller than the pivot end up
|
||||
* at its left while all items greater than end up at its right.
|
||||
*
|
||||
* @param[in] pArray The array to be sorted.
|
||||
* @param[in] low The low index of the array.
|
||||
* @param[in] high The high index of the array.
|
||||
* @param[in] itemSize The amount of memory per entry in the array.
|
||||
* @param[out] comparator The comparison function to determine if one item is less than another.
|
||||
*
|
||||
* @return The index of the pivot
|
||||
*/
|
||||
static size_t partition( void * pArray,
|
||||
size_t low,
|
||||
size_t high,
|
||||
size_t itemSize,
|
||||
ComparisonFunc_t comparator );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void swap( void * pFirstItem,
|
||||
void * pSecondItem,
|
||||
size_t itemSize )
|
||||
{
|
||||
uint8_t * pFirstByte = pFirstItem;
|
||||
uint8_t * pSecondByte = pSecondItem;
|
||||
size_t dataSize = itemSize;
|
||||
|
||||
assert( pFirstItem != NULL );
|
||||
assert( pSecondItem != NULL );
|
||||
|
||||
/* Swap one byte at a time. */
|
||||
while( dataSize-- > 0U )
|
||||
{
|
||||
uint8_t tmp = *pFirstByte;
|
||||
*pFirstByte = *pSecondByte;
|
||||
++pFirstByte;
|
||||
*pSecondByte = tmp;
|
||||
++pSecondByte;
|
||||
}
|
||||
}
|
||||
|
||||
static void quickSortHelper( void * pArray,
|
||||
size_t low,
|
||||
size_t high,
|
||||
size_t itemSize,
|
||||
ComparisonFunc_t comparator )
|
||||
{
|
||||
size_t stack[ SIGV4_WORST_CASE_SORT_STACK_SIZE ];
|
||||
|
||||
/* Low and high are first two items on the stack. Note
|
||||
* that we use an intermediary variable for MISRA compliance. */
|
||||
size_t top = 0U, lo = low, hi = high;
|
||||
|
||||
PUSH_STACK( lo, stack, top );
|
||||
PUSH_STACK( hi, stack, top );
|
||||
|
||||
while( top > 0U )
|
||||
{
|
||||
size_t partitionIndex;
|
||||
size_t len1, len2;
|
||||
POP_STACK( hi, stack, top );
|
||||
POP_STACK( lo, stack, top );
|
||||
|
||||
partitionIndex = partition( pArray, lo, hi, itemSize, comparator );
|
||||
|
||||
/* Calculate length of the left partition containing items smaller
|
||||
* than the pivot element.
|
||||
* The length is zero if either:
|
||||
* 1. The pivoted item is the smallest in the the array before partitioning.
|
||||
* OR
|
||||
* 2. The left partition is only of single length which can be treated as
|
||||
* sorted, and thus, of zero length for avoided adding to the stack. */
|
||||
len1 = ( ( partitionIndex != 0U ) && ( ( partitionIndex - 1U ) > lo ) ) ? ( partitionIndex - lo ) : 0U;
|
||||
|
||||
/* Calculate length of the right partition containing items greater than
|
||||
* or equal to the pivot item.
|
||||
* The calculated length is zero if either:
|
||||
* 1. The pivoted item is the greatest in the the array before partitioning.
|
||||
* OR
|
||||
* 2. The right partition contains only a single length which can be treated as
|
||||
* sorted, and thereby, of zero length to avoid adding to the stack. */
|
||||
len2 = ( ( partitionIndex + 1U ) < hi ) ? ( hi - partitionIndex ) : 0U;
|
||||
|
||||
/* Push the information of the left and right partitions to the stack.
|
||||
* Note: For stack space optimization, the larger of the partitions is pushed
|
||||
* first and the smaller is pushed later so that the smaller part of the tree
|
||||
* is completed first without increasing stack space usage before coming back
|
||||
* to the larger partition. */
|
||||
if( len1 > len2 )
|
||||
{
|
||||
PUSH_STACK( lo, stack, top );
|
||||
PUSH_STACK( partitionIndex - 1U, stack, top );
|
||||
|
||||
if( len2 > 0U )
|
||||
{
|
||||
PUSH_STACK( partitionIndex + 1U, stack, top );
|
||||
PUSH_STACK( hi, stack, top );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( len2 > 0U )
|
||||
{
|
||||
PUSH_STACK( partitionIndex + 1U, stack, top );
|
||||
PUSH_STACK( hi, stack, top );
|
||||
}
|
||||
|
||||
if( len1 > 0U )
|
||||
{
|
||||
PUSH_STACK( lo, stack, top );
|
||||
PUSH_STACK( partitionIndex - 1U, stack, top );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static size_t partition( void * pArray,
|
||||
size_t low,
|
||||
size_t high,
|
||||
size_t itemSize,
|
||||
ComparisonFunc_t comparator )
|
||||
{
|
||||
uint8_t * pivot;
|
||||
uint8_t * pArrayLocal = ( uint8_t * ) pArray;
|
||||
size_t i = low - 1U, j = low;
|
||||
|
||||
assert( pArray != NULL );
|
||||
assert( comparator != NULL );
|
||||
|
||||
/* Choose pivot as the highest indexed item in the current partition. */
|
||||
pivot = pArrayLocal + ( high * itemSize );
|
||||
|
||||
/* Iterate over all elements of the current array to partition it
|
||||
* in comparison to the chosen pivot with smaller items on the left
|
||||
* and larger or equal to items on the right. */
|
||||
for( ; j < high; j++ )
|
||||
{
|
||||
/* Use comparator function to check current element is smaller than the pivot */
|
||||
if( comparator( pArrayLocal + ( j * itemSize ), pivot ) < 0 )
|
||||
{
|
||||
++i;
|
||||
swap( pArrayLocal + ( i * itemSize ), pArrayLocal + ( j * itemSize ), itemSize );
|
||||
}
|
||||
}
|
||||
|
||||
/* Place the pivot between the smaller and larger item chunks of
|
||||
* the array. This represents the 2 partitions of the array. */
|
||||
swap( pArrayLocal + ( ( i + 1U ) * itemSize ), pivot, itemSize );
|
||||
|
||||
/* Return the pivot item's index. */
|
||||
return i + 1U;
|
||||
}
|
||||
|
||||
void quickSort( void * pArray,
|
||||
size_t numItems,
|
||||
size_t itemSize,
|
||||
ComparisonFunc_t comparator )
|
||||
{
|
||||
assert( pArray != NULL );
|
||||
assert( numItems > 0U );
|
||||
assert( itemSize > 0U );
|
||||
assert( comparator != NULL );
|
||||
|
||||
quickSortHelper( pArray, 0U, numItems - 1U, itemSize, comparator );
|
||||
}
|
||||
Reference in New Issue
Block a user