mirror of
https://github.com/awslabs/aws-crt-php.git
synced 2026-08-17 17:47:12 +00:00
Implemented SigV4A (#40)
* Implemented should_sign_header callback * Added SigV4A to SigningAlgorithm * Added SigV4A test * Added debugging info to README * Fixed memory leak from argument vectors * Fixed memory leak of stream read buffers * Added support for callables as option values * Added should_sign_header support and test * Fixed ELG type bug exposed by aws-crt-ffi change * Updated to aws-crt-ffi v0.2.0
This commit is contained in:
@@ -51,6 +51,26 @@ C:\php-sdk\php-<version>\vc15\x64\php-src
|
||||
$ nmake test-awscrt
|
||||
```
|
||||
|
||||
## Debugging
|
||||
Using [PHPBrew](https://github.com/phpbrew/phpbrew) to build/manage multiple versions of PHP is helpful.
|
||||
|
||||
Note: You must use a debug build of PHP to debug native extensions.
|
||||
See the [PHP Internals Book](https://www.phpinternalsbook.com/php7/build_system/building_php.html) for more info
|
||||
|
||||
```shell
|
||||
# PHP 8 example
|
||||
$ phpbrew install --stdout -j 8 8.0 +default -- CFLAGS=-Wno-error --disable-cgi --enable-debug
|
||||
# PHP 5.5 example
|
||||
$ phpbrew install --stdout -j 8 5.5 +default -openssl -mbstring -- CFLAGS="-w -Wno-error" --enable-debug --with-zlib=/usr/local/opt/zlib
|
||||
$ phpbrew switch php-8.0.6 # or whatever version is current, it'll be at the end of the build output
|
||||
$ phpize
|
||||
$ ./configure
|
||||
$ make CMAKE_BUILD_TYPE=Debug
|
||||
```
|
||||
|
||||
Ensure that the php you launch from your debugger is the result of `which php`, not just
|
||||
the system default php.
|
||||
|
||||
## Security
|
||||
|
||||
See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
|
||||
|
||||
+1
-1
Submodule crt/aws-crt-ffi updated: 105be1d1ce...a7c2c91a10
@@ -13,3 +13,4 @@
|
||||
#include "stream.c"
|
||||
// #include "hash.c"
|
||||
#include "crc.c"
|
||||
#include "php_util.c"
|
||||
|
||||
@@ -105,6 +105,8 @@ function aws_crt_signing_config_aws_set_expiration_in_seconds(int $config, int $
|
||||
|
||||
function aws_crt_signing_config_aws_set_date(int $config, int $timestamp): void {}
|
||||
|
||||
function aws_crt_signing_config_aws_set_should_sign_header_fn(int $config, object $should_sign_header): void {}
|
||||
|
||||
function aws_crt_signable_new_from_http_request(int $http_message): int {}
|
||||
|
||||
function aws_crt_signable_new_from_chunk(int $input_stream, string $previous_signature): int {}
|
||||
|
||||
+100
-82
@@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 36d4e512f02a12c10689eb9b0941bcd7837fbf1d */
|
||||
* Stub hash: 9b39b5b4523538d8b64b2558e11dfafb209c8ea8 */
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_aws_crt_last_error, 0, 0, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
@@ -195,6 +195,11 @@ ZEND_ARG_INFO(0, config)
|
||||
ZEND_ARG_INFO(0, timestamp)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_aws_crt_signing_config_aws_set_should_sign_header_fn, 0, 0, 2)
|
||||
ZEND_ARG_INFO(0, config)
|
||||
ZEND_ARG_INFO(0, should_sign_header)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_aws_crt_signable_new_from_http_request, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, http_message)
|
||||
ZEND_END_ARG_INFO()
|
||||
@@ -285,6 +290,7 @@ ZEND_FUNCTION(aws_crt_signing_config_aws_set_signed_body_value);
|
||||
ZEND_FUNCTION(aws_crt_signing_config_aws_set_signed_body_header_type);
|
||||
ZEND_FUNCTION(aws_crt_signing_config_aws_set_expiration_in_seconds);
|
||||
ZEND_FUNCTION(aws_crt_signing_config_aws_set_date);
|
||||
ZEND_FUNCTION(aws_crt_signing_config_aws_set_should_sign_header_fn);
|
||||
ZEND_FUNCTION(aws_crt_signable_new_from_http_request);
|
||||
ZEND_FUNCTION(aws_crt_signable_new_from_chunk);
|
||||
ZEND_FUNCTION(aws_crt_signable_new_from_canonical_request);
|
||||
@@ -295,86 +301,98 @@ ZEND_FUNCTION(aws_crt_sign_request_aws);
|
||||
ZEND_FUNCTION(aws_crt_crc32);
|
||||
ZEND_FUNCTION(aws_crt_crc32c);
|
||||
|
||||
static const zend_function_entry ext_functions[] =
|
||||
{ZEND_FE(aws_crt_last_error, arginfo_aws_crt_last_error) ZEND_FE(aws_crt_error_name, arginfo_aws_crt_error_name) ZEND_FE(
|
||||
static const zend_function_entry ext_functions
|
||||
[] = {ZEND_FE(aws_crt_last_error, arginfo_aws_crt_last_error) ZEND_FE(aws_crt_error_name, arginfo_aws_crt_error_name) ZEND_FE(
|
||||
aws_crt_error_str,
|
||||
arginfo_aws_crt_error_str) ZEND_FE(aws_crt_error_debug_str, arginfo_aws_crt_error_debug_str)
|
||||
ZEND_FE(aws_crt_event_loop_group_options_new, arginfo_aws_crt_event_loop_group_options_new) ZEND_FE(
|
||||
aws_crt_event_loop_group_options_release,
|
||||
arginfo_aws_crt_event_loop_group_options_release) ZEND_FE(aws_crt_event_loop_group_options_set_max_threads, arginfo_aws_crt_event_loop_group_options_set_max_threads)
|
||||
ZEND_FE(aws_crt_event_loop_group_new, arginfo_aws_crt_event_loop_group_new) ZEND_FE(
|
||||
aws_crt_event_loop_group_release,
|
||||
arginfo_aws_crt_event_loop_group_release) ZEND_FE(aws_crt_input_stream_options_new, arginfo_aws_crt_input_stream_options_new)
|
||||
ZEND_FE(aws_crt_input_stream_options_release, arginfo_aws_crt_input_stream_options_release) ZEND_FE(
|
||||
aws_crt_input_stream_options_set_user_data,
|
||||
arginfo_aws_crt_input_stream_options_set_user_data) ZEND_FE(aws_crt_input_stream_new, arginfo_aws_crt_input_stream_new)
|
||||
ZEND_FE(aws_crt_input_stream_release, arginfo_aws_crt_input_stream_release) ZEND_FE(
|
||||
aws_crt_input_stream_seek,
|
||||
arginfo_aws_crt_input_stream_seek) ZEND_FE(aws_crt_input_stream_read, arginfo_aws_crt_input_stream_read)
|
||||
ZEND_FE(aws_crt_input_stream_eof, arginfo_aws_crt_input_stream_eof) ZEND_FE(
|
||||
aws_crt_input_stream_get_length,
|
||||
arginfo_aws_crt_input_stream_get_length)
|
||||
ZEND_FE(aws_crt_http_message_new_from_blob, arginfo_aws_crt_http_message_new_from_blob) ZEND_FE(
|
||||
aws_crt_http_message_to_blob,
|
||||
arginfo_aws_crt_http_message_to_blob)
|
||||
ZEND_FE(aws_crt_http_message_release, arginfo_aws_crt_http_message_release) ZEND_FE(
|
||||
aws_crt_credentials_options_new,
|
||||
arginfo_aws_crt_credentials_options_new)
|
||||
ZEND_FE(aws_crt_credentials_options_release, arginfo_aws_crt_credentials_options_release) ZEND_FE(
|
||||
aws_crt_credentials_options_set_access_key_id,
|
||||
arginfo_aws_crt_credentials_options_set_access_key_id)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_options_set_secret_access_key,
|
||||
arginfo_aws_crt_credentials_options_set_secret_access_key)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_options_set_session_token,
|
||||
arginfo_aws_crt_credentials_options_set_session_token)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_options_set_expiration_timepoint_seconds,
|
||||
arginfo_aws_crt_credentials_options_set_expiration_timepoint_seconds)
|
||||
ZEND_FE(aws_crt_credentials_new, arginfo_aws_crt_credentials_new) ZEND_FE(
|
||||
aws_crt_credentials_release,
|
||||
arginfo_aws_crt_credentials_release)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_release,
|
||||
arginfo_aws_crt_credentials_provider_release)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_static_options_new,
|
||||
arginfo_aws_crt_credentials_provider_static_options_new)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_static_options_release,
|
||||
arginfo_aws_crt_credentials_provider_static_options_release)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_static_options_set_access_key_id,
|
||||
arginfo_aws_crt_credentials_provider_static_options_set_access_key_id)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_static_options_set_secret_access_key,
|
||||
arginfo_aws_crt_credentials_provider_static_options_set_secret_access_key)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_static_options_set_session_token,
|
||||
arginfo_aws_crt_credentials_provider_static_options_set_session_token)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_static_new,
|
||||
arginfo_aws_crt_credentials_provider_static_new)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_config_aws_new,
|
||||
arginfo_aws_crt_signing_config_aws_new)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_config_aws_release,
|
||||
arginfo_aws_crt_signing_config_aws_release)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_config_aws_set_algorithm,
|
||||
arginfo_aws_crt_signing_config_aws_set_algorithm) ZEND_FE(aws_crt_signing_config_aws_set_signature_type, arginfo_aws_crt_signing_config_aws_set_signature_type) ZEND_FE(aws_crt_signing_config_aws_set_credentials_provider, arginfo_aws_crt_signing_config_aws_set_credentials_provider) ZEND_FE(aws_crt_signing_config_aws_set_region, arginfo_aws_crt_signing_config_aws_set_region) ZEND_FE(aws_crt_signing_config_aws_set_service, arginfo_aws_crt_signing_config_aws_set_service) ZEND_FE(aws_crt_signing_config_aws_set_use_double_uri_encode, arginfo_aws_crt_signing_config_aws_set_use_double_uri_encode) ZEND_FE(aws_crt_signing_config_aws_set_should_normalize_uri_path, arginfo_aws_crt_signing_config_aws_set_should_normalize_uri_path) ZEND_FE(aws_crt_signing_config_aws_set_omit_session_token, arginfo_aws_crt_signing_config_aws_set_omit_session_token) ZEND_FE(aws_crt_signing_config_aws_set_signed_body_value, arginfo_aws_crt_signing_config_aws_set_signed_body_value) ZEND_FE(aws_crt_signing_config_aws_set_signed_body_header_type, arginfo_aws_crt_signing_config_aws_set_signed_body_header_type) ZEND_FE(aws_crt_signing_config_aws_set_expiration_in_seconds, arginfo_aws_crt_signing_config_aws_set_expiration_in_seconds) ZEND_FE(aws_crt_signing_config_aws_set_date, arginfo_aws_crt_signing_config_aws_set_date) ZEND_FE(aws_crt_signable_new_from_http_request, arginfo_aws_crt_signable_new_from_http_request) ZEND_FE(aws_crt_signable_new_from_chunk, arginfo_aws_crt_signable_new_from_chunk) ZEND_FE(aws_crt_signable_new_from_canonical_request, arginfo_aws_crt_signable_new_from_canonical_request) ZEND_FE(aws_crt_signable_release, arginfo_aws_crt_signable_release) ZEND_FE(aws_crt_signing_result_release, arginfo_aws_crt_signing_result_release)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_result_apply_to_http_request,
|
||||
arginfo_aws_crt_signing_result_apply_to_http_request)
|
||||
ZEND_FE(
|
||||
aws_crt_sign_request_aws,
|
||||
arginfo_aws_crt_sign_request_aws)
|
||||
ZEND_FE(
|
||||
aws_crt_crc32,
|
||||
arginfo_aws_crt_crc32)
|
||||
ZEND_FE(
|
||||
aws_crt_crc32c,
|
||||
arginfo_aws_crt_crc32c)
|
||||
ZEND_FE_END};
|
||||
ZEND_FE(aws_crt_event_loop_group_options_new, arginfo_aws_crt_event_loop_group_options_new) ZEND_FE(
|
||||
aws_crt_event_loop_group_options_release,
|
||||
arginfo_aws_crt_event_loop_group_options_release) ZEND_FE(aws_crt_event_loop_group_options_set_max_threads, arginfo_aws_crt_event_loop_group_options_set_max_threads)
|
||||
ZEND_FE(aws_crt_event_loop_group_new, arginfo_aws_crt_event_loop_group_new) ZEND_FE(
|
||||
aws_crt_event_loop_group_release,
|
||||
arginfo_aws_crt_event_loop_group_release) ZEND_FE(aws_crt_input_stream_options_new, arginfo_aws_crt_input_stream_options_new)
|
||||
ZEND_FE(aws_crt_input_stream_options_release, arginfo_aws_crt_input_stream_options_release) ZEND_FE(
|
||||
aws_crt_input_stream_options_set_user_data,
|
||||
arginfo_aws_crt_input_stream_options_set_user_data) ZEND_FE(aws_crt_input_stream_new, arginfo_aws_crt_input_stream_new)
|
||||
ZEND_FE(aws_crt_input_stream_release, arginfo_aws_crt_input_stream_release) ZEND_FE(
|
||||
aws_crt_input_stream_seek,
|
||||
arginfo_aws_crt_input_stream_seek) ZEND_FE(aws_crt_input_stream_read, arginfo_aws_crt_input_stream_read)
|
||||
ZEND_FE(aws_crt_input_stream_eof, arginfo_aws_crt_input_stream_eof) ZEND_FE(
|
||||
aws_crt_input_stream_get_length,
|
||||
arginfo_aws_crt_input_stream_get_length) ZEND_FE(aws_crt_http_message_new_from_blob, arginfo_aws_crt_http_message_new_from_blob)
|
||||
ZEND_FE(aws_crt_http_message_to_blob, arginfo_aws_crt_http_message_to_blob) ZEND_FE(
|
||||
aws_crt_http_message_release,
|
||||
arginfo_aws_crt_http_message_release) ZEND_FE(aws_crt_credentials_options_new, arginfo_aws_crt_credentials_options_new)
|
||||
ZEND_FE(aws_crt_credentials_options_release, arginfo_aws_crt_credentials_options_release) ZEND_FE(
|
||||
aws_crt_credentials_options_set_access_key_id,
|
||||
arginfo_aws_crt_credentials_options_set_access_key_id)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_options_set_secret_access_key,
|
||||
arginfo_aws_crt_credentials_options_set_secret_access_key)
|
||||
ZEND_FE(aws_crt_credentials_options_set_session_token, arginfo_aws_crt_credentials_options_set_session_token) ZEND_FE(
|
||||
aws_crt_credentials_options_set_expiration_timepoint_seconds,
|
||||
arginfo_aws_crt_credentials_options_set_expiration_timepoint_seconds)
|
||||
ZEND_FE(aws_crt_credentials_new, arginfo_aws_crt_credentials_new) ZEND_FE(
|
||||
aws_crt_credentials_release,
|
||||
arginfo_aws_crt_credentials_release)
|
||||
ZEND_FE(aws_crt_credentials_provider_release, arginfo_aws_crt_credentials_provider_release) ZEND_FE(
|
||||
aws_crt_credentials_provider_static_options_new,
|
||||
arginfo_aws_crt_credentials_provider_static_options_new)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_static_options_release,
|
||||
arginfo_aws_crt_credentials_provider_static_options_release)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_static_options_set_access_key_id,
|
||||
arginfo_aws_crt_credentials_provider_static_options_set_access_key_id)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_static_options_set_secret_access_key,
|
||||
arginfo_aws_crt_credentials_provider_static_options_set_secret_access_key)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_static_options_set_session_token,
|
||||
arginfo_aws_crt_credentials_provider_static_options_set_session_token)
|
||||
ZEND_FE(
|
||||
aws_crt_credentials_provider_static_new,
|
||||
arginfo_aws_crt_credentials_provider_static_new)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_config_aws_new,
|
||||
arginfo_aws_crt_signing_config_aws_new)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_config_aws_release,
|
||||
arginfo_aws_crt_signing_config_aws_release)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_config_aws_set_algorithm,
|
||||
arginfo_aws_crt_signing_config_aws_set_algorithm)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_config_aws_set_signature_type,
|
||||
arginfo_aws_crt_signing_config_aws_set_signature_type)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_config_aws_set_credentials_provider,
|
||||
arginfo_aws_crt_signing_config_aws_set_credentials_provider)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_config_aws_set_region,
|
||||
arginfo_aws_crt_signing_config_aws_set_region)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_config_aws_set_service,
|
||||
arginfo_aws_crt_signing_config_aws_set_service)
|
||||
ZEND_FE(aws_crt_signing_config_aws_set_use_double_uri_encode, arginfo_aws_crt_signing_config_aws_set_use_double_uri_encode) ZEND_FE(aws_crt_signing_config_aws_set_should_normalize_uri_path, arginfo_aws_crt_signing_config_aws_set_should_normalize_uri_path) ZEND_FE(aws_crt_signing_config_aws_set_omit_session_token, arginfo_aws_crt_signing_config_aws_set_omit_session_token) ZEND_FE(aws_crt_signing_config_aws_set_signed_body_value, arginfo_aws_crt_signing_config_aws_set_signed_body_value) ZEND_FE(aws_crt_signing_config_aws_set_signed_body_header_type, arginfo_aws_crt_signing_config_aws_set_signed_body_header_type) ZEND_FE(aws_crt_signing_config_aws_set_expiration_in_seconds, arginfo_aws_crt_signing_config_aws_set_expiration_in_seconds) ZEND_FE(aws_crt_signing_config_aws_set_date, arginfo_aws_crt_signing_config_aws_set_date) ZEND_FE(aws_crt_signing_config_aws_set_should_sign_header_fn, arginfo_aws_crt_signing_config_aws_set_should_sign_header_fn) ZEND_FE(aws_crt_signable_new_from_http_request, arginfo_aws_crt_signable_new_from_http_request) ZEND_FE(aws_crt_signable_new_from_chunk, arginfo_aws_crt_signable_new_from_chunk) ZEND_FE(
|
||||
aws_crt_signable_new_from_canonical_request,
|
||||
arginfo_aws_crt_signable_new_from_canonical_request)
|
||||
ZEND_FE(
|
||||
aws_crt_signable_release,
|
||||
arginfo_aws_crt_signable_release)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_result_release,
|
||||
arginfo_aws_crt_signing_result_release)
|
||||
ZEND_FE(
|
||||
aws_crt_signing_result_apply_to_http_request,
|
||||
arginfo_aws_crt_signing_result_apply_to_http_request)
|
||||
ZEND_FE(
|
||||
aws_crt_sign_request_aws,
|
||||
arginfo_aws_crt_sign_request_aws)
|
||||
ZEND_FE(
|
||||
aws_crt_crc32,
|
||||
arginfo_aws_crt_crc32)
|
||||
ZEND_FE(
|
||||
aws_crt_crc32c,
|
||||
arginfo_aws_crt_crc32c)
|
||||
ZEND_FE_END};
|
||||
|
||||
@@ -51,11 +51,7 @@ zval aws_php_invoke_callback(zval *callback, const char *arg_types, ...) {
|
||||
case 's': {
|
||||
const char *buf = va_arg(va, const char *);
|
||||
const size_t len = va_arg(va, size_t);
|
||||
#if AWS_PHP_AT_LEAST_7
|
||||
ZVAL_STRINGL(&stack[arg_idx], buf, len);
|
||||
#else
|
||||
ZVAL_STRINGL(&stack[arg_idx], buf, len, 0);
|
||||
#endif
|
||||
aws_php_zval_stringl(&stack[arg_idx], buf, len);
|
||||
break;
|
||||
}
|
||||
/* other primitives */
|
||||
@@ -129,17 +125,22 @@ zval aws_php_invoke_callback(zval *callback, const char *arg_types, ...) {
|
||||
#endif
|
||||
|
||||
/* Clean up arguments */
|
||||
for (int arg_idx = 0; arg_idx < num_args; ++arg_idx) {
|
||||
#if !AWS_PHP_AT_LEAST_7
|
||||
zval_ptr_dtor(args[arg_idx]);
|
||||
#else
|
||||
zval_ptr_dtor(&stack[arg_idx]);
|
||||
#if AWS_PHP_AT_LEAST_7
|
||||
zend_fcall_info_args_clear(&fci, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void aws_php_zval_stringl(zval *val, const char *str, size_t len) {
|
||||
AWS_FATAL_ASSERT(val != NULL);
|
||||
#if AWS_PHP_AT_LEAST_7
|
||||
ZVAL_STRINGL(val, str, len);
|
||||
#else
|
||||
ZVAL_STRINGL(val, str, len, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
aws_php_thread_queue s_aws_php_main_thread_queue;
|
||||
|
||||
bool aws_php_is_main_thread(void) {
|
||||
@@ -290,7 +291,7 @@ PHP_FUNCTION(aws_crt_error_str) {
|
||||
zend_ulong error_code = 0;
|
||||
aws_php_parse_parameters("l", &error_code);
|
||||
|
||||
RETURN_STRING(aws_crt_error_str(error_code));
|
||||
XRETURN_STRING(aws_crt_error_str(error_code));
|
||||
}
|
||||
|
||||
/* aws_crt_error_name(int error_code) */
|
||||
@@ -298,7 +299,7 @@ PHP_FUNCTION(aws_crt_error_name) {
|
||||
zend_ulong error_code = 0;
|
||||
aws_php_parse_parameters("l", &error_code);
|
||||
|
||||
RETURN_STRING(aws_crt_error_name(error_code));
|
||||
XRETURN_STRING(aws_crt_error_name(error_code));
|
||||
}
|
||||
|
||||
/* aws_crt_error_debug_str(int error_code) */
|
||||
@@ -306,5 +307,5 @@ PHP_FUNCTION(aws_crt_error_debug_str) {
|
||||
zend_ulong error_code = 0;
|
||||
aws_php_parse_parameters("l", &error_code);
|
||||
|
||||
RETURN_STRING(aws_crt_error_debug_str(error_code));
|
||||
XRETURN_STRING(aws_crt_error_debug_str(error_code));
|
||||
}
|
||||
|
||||
+1
-1
@@ -43,6 +43,6 @@ PHP_FUNCTION(aws_crt_event_loop_group_release) {
|
||||
|
||||
aws_php_parse_parameters("l", &php_elg);
|
||||
|
||||
struct aws_event_loop_group *elg = (void *)php_elg;
|
||||
aws_crt_event_loop_group *elg = (void *)php_elg;
|
||||
aws_crt_event_loop_group_release(elg);
|
||||
}
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ PHP_FUNCTION(aws_crt_http_message_to_blob) {
|
||||
aws_crt_http_message *message = (void *)php_msg;
|
||||
aws_crt_buf blob;
|
||||
aws_crt_http_message_to_blob(message, &blob);
|
||||
RETURN_STRINGL((const char *)blob.blob, blob.length);
|
||||
XRETURN_STRINGL((const char *)blob.blob, blob.length);
|
||||
}
|
||||
|
||||
PHP_FUNCTION(aws_crt_http_message_release) {
|
||||
|
||||
+32
-27
@@ -48,21 +48,16 @@ ZEND_EXTERN_MODULE_GLOBALS(awscrt)
|
||||
#if AWS_PHP_AT_LEAST_7
|
||||
/* PHP 7 takes a zval*, PHP5 takes a zval** */
|
||||
# define AWS_PHP_STREAM_FROM_ZVAL(s, z) php_stream_from_zval(s, z)
|
||||
#else /* PHP 5.5-5.6, 7.0-7.1 */
|
||||
/* PHP 7.2+ always duplicate string return values */
|
||||
# undef RETURN_STRING
|
||||
# define RETURN_STRING(s) \
|
||||
{ \
|
||||
RETVAL_STRING(s, 1); \
|
||||
return; \
|
||||
}
|
||||
# undef RETURN_STRINGL
|
||||
# define RETURN_STRINGL(s, l) \
|
||||
{ \
|
||||
RETVAL_STRINGL(s, l, 1); \
|
||||
return; \
|
||||
}
|
||||
#define XRETURN_STRINGL RETURN_STRINGL
|
||||
#define XRETURN_STRING RETURN_STRING
|
||||
#define XRETVAL_STRINGL RETVAL_STRINGL
|
||||
#define XRETVAL_STRING RETVAL_STRING
|
||||
#else /* PHP 5.5-5.6 */
|
||||
# define AWS_PHP_STREAM_FROM_ZVAL(s, z) php_stream_from_zval(s, &z)
|
||||
#define XRETURN_STRINGL(s, l) RETURN_STRINGL(s, l, 1)
|
||||
#define XRETURN_STRING(s) RETURN_STRING(s, 1)
|
||||
#define XRETVAL_STRINGL(s, l) RETVAL_STRINGL(s, l, 1)
|
||||
#define XRETVAL_STRING(s) RETVAL_STRING(s, 1)
|
||||
#endif /* PHP 5.x */
|
||||
|
||||
#include "api.h"
|
||||
@@ -100,29 +95,39 @@ ZEND_EXTERN_MODULE_GLOBALS(awscrt)
|
||||
* throws an exception resulting from argument parsing, notes the current function name in the exception
|
||||
*/
|
||||
#define aws_php_argparse_fail() \
|
||||
do { \
|
||||
aws_php_throw_exception("Failed to parse arguments to %s", __func__); \
|
||||
} while (0)
|
||||
do { \
|
||||
aws_php_throw_exception("Failed to parse arguments to %s", __func__); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* calls zend_parse_parameters() with the arguments and throws an exception if parsing fails
|
||||
*/
|
||||
#define aws_php_parse_parameters(type_spec, ...) \
|
||||
do { \
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), type_spec, __VA_ARGS__) == FAILURE) { \
|
||||
aws_php_argparse_fail(); \
|
||||
} \
|
||||
} while (0)
|
||||
do { \
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), type_spec, __VA_ARGS__) == FAILURE) { \
|
||||
aws_php_argparse_fail(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* calls zend_parse_parameters_none() and throws an exception if parsing fails
|
||||
*/
|
||||
#define aws_php_parse_parameters_none() \
|
||||
do { \
|
||||
if (zend_parse_parameters_none() == FAILURE) { \
|
||||
aws_php_argparse_fail(); \
|
||||
} \
|
||||
} while (0)
|
||||
do { \
|
||||
if (zend_parse_parameters_none() == FAILURE) { \
|
||||
aws_php_argparse_fail(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* PHP/Zend utility functions to work across PHP versions */
|
||||
zval *aws_php_zval_new(void);
|
||||
void aws_php_zval_dtor(void *zval_ptr);
|
||||
bool aws_php_zval_as_bool(zval *z);
|
||||
void aws_php_zval_copy(zval *dest, zval *src);
|
||||
/**
|
||||
* Replacement for ZVAL_STRINGL that is PHP version agnostic
|
||||
*/
|
||||
void aws_php_zval_stringl(zval *val, const char *str, size_t len);
|
||||
|
||||
/* Thread queue functions for managing PHP's optional threading situation */
|
||||
typedef struct _aws_php_task {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include "php_aws_crt.h"
|
||||
|
||||
zval *aws_php_zval_new(void) {
|
||||
return emalloc(sizeof(zval));
|
||||
}
|
||||
|
||||
void aws_php_zval_dtor(void *zval_ptr) {
|
||||
zval *z = zval_ptr;
|
||||
zval_dtor(z);
|
||||
efree(z);
|
||||
}
|
||||
|
||||
bool aws_php_zval_as_bool(zval *z) {
|
||||
#if AWS_PHP_AT_LEAST_7
|
||||
return (Z_TYPE_P(z) == IS_TRUE);
|
||||
#else
|
||||
return (Z_TYPE_P(z) == IS_BOOL && Z_LVAL_P(z) != 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void aws_php_zval_copy(zval *dest, zval *src) {
|
||||
#if AWS_PHP_AT_LEAST_7
|
||||
ZVAL_COPY(dest, src);
|
||||
#else
|
||||
ZVAL_COPY_VALUE(dest, src);
|
||||
#endif
|
||||
}
|
||||
@@ -151,6 +151,59 @@ PHP_FUNCTION(aws_crt_signing_config_aws_set_date) {
|
||||
aws_crt_signing_config_aws_set_date(signing_config, php_timestamp);
|
||||
}
|
||||
|
||||
typedef struct _should_sign_header_data {
|
||||
zval *should_sign_header;
|
||||
zval *header_name;
|
||||
bool result;
|
||||
} should_sign_header_data;
|
||||
|
||||
static void should_sign_header_task(void *data) {
|
||||
should_sign_header_data *task = data;
|
||||
zval result = aws_php_invoke_callback(task->should_sign_header, "z", task->header_name);
|
||||
task->result = aws_php_zval_as_bool(&result);
|
||||
zval_dtor(&result);
|
||||
}
|
||||
|
||||
static bool aws_php_should_sign_header(const char *header_name, size_t header_length, void *user_data) {
|
||||
zval php_header_name;
|
||||
aws_php_zval_stringl(&php_header_name, header_name, header_length);
|
||||
|
||||
should_sign_header_data task_data = {
|
||||
.should_sign_header = user_data,
|
||||
.header_name = &php_header_name,
|
||||
.result = false,
|
||||
};
|
||||
|
||||
aws_php_task task = {
|
||||
.callback = should_sign_header_task,
|
||||
.data = &task_data,
|
||||
};
|
||||
|
||||
aws_php_thread_queue_push(&s_aws_php_main_thread_queue, task);
|
||||
aws_php_thread_queue_yield(&s_aws_php_main_thread_queue);
|
||||
|
||||
zval_dtor(&php_header_name);
|
||||
|
||||
return task_data.result;
|
||||
}
|
||||
|
||||
PHP_FUNCTION(aws_crt_signing_config_aws_set_should_sign_header_fn) {
|
||||
zend_ulong php_signing_config = 0;
|
||||
zval *php_should_sign_header = NULL;
|
||||
|
||||
aws_php_parse_parameters("lz", &php_signing_config, &php_should_sign_header);
|
||||
|
||||
aws_crt_signing_config_aws *signing_config = (void *)php_signing_config;
|
||||
|
||||
/* copy/retain PHP callback, add as user data for signing_config resource */
|
||||
zval *should_sign_header = aws_php_zval_new();
|
||||
aws_php_zval_copy(should_sign_header, php_should_sign_header);
|
||||
aws_crt_resource_set_user_data(signing_config, should_sign_header, aws_php_zval_dtor);
|
||||
|
||||
aws_crt_signing_config_aws_set_should_sign_header_fn(
|
||||
signing_config, aws_php_should_sign_header, should_sign_header);
|
||||
}
|
||||
|
||||
PHP_FUNCTION(aws_crt_signable_new_from_http_request) {
|
||||
zend_ulong php_http_message = 0;
|
||||
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ PHP_FUNCTION(aws_crt_input_stream_read) {
|
||||
aws_crt_input_stream *stream = (void *)php_stream;
|
||||
uint8_t *buf = emalloc(length);
|
||||
int ret = aws_crt_input_stream_read(stream, buf, length);
|
||||
RETURN_STRINGL((const char *)buf, length);
|
||||
XRETVAL_STRINGL((const char *)buf, length);
|
||||
efree(buf);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,4 +7,5 @@ namespace AWS\CRT\Auth;
|
||||
|
||||
class SigningAlgorithm {
|
||||
const SIGv4 = 0;
|
||||
}
|
||||
const SIGv4_ASYMMETRIC = 1;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ class SigningConfigAWS extends NativeResource {
|
||||
'signed_body_value' => null,
|
||||
'signed_body_header_type' => SignedBodyHeaderType::NONE,
|
||||
'expiration_in_seconds' => 0,
|
||||
'date' => time()
|
||||
'date' => time(),
|
||||
'should_sign_header' => null,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -57,6 +58,9 @@ class SigningConfigAWS extends NativeResource {
|
||||
self::$crt->signing_config_aws_set_expiration_in_seconds(
|
||||
$sc, $options->expiration_in_seconds->asInt());
|
||||
self::$crt->signing_config_aws_set_date($sc, $options->date->asInt());
|
||||
if ($should_sign_header = $options->should_sign_header->asCallable()) {
|
||||
self::$crt->signing_config_aws_set_should_sign_header_fn($sc, $should_sign_header);
|
||||
}
|
||||
}
|
||||
|
||||
function __destruct()
|
||||
|
||||
@@ -317,6 +317,10 @@ final class CRT {
|
||||
self::$impl->aws_crt_signing_config_aws_set_date($signing_config, $timestamp);
|
||||
}
|
||||
|
||||
function signing_config_aws_set_should_sign_header_fn($signing_config, $should_sign_header_fn) {
|
||||
self::$impl->aws_crt_signing_config_aws_set_should_sign_header_fn($signing_config, $should_sign_header_fn);
|
||||
}
|
||||
|
||||
function signable_new_from_http_request($http_message) {
|
||||
return self::$impl->aws_crt_signable_new_from_http_request($http_message);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ final class OptionValue {
|
||||
public function asArray() {
|
||||
return is_array($this->value) ? $this->value : (!empty($this->value) ? [$this->value] : []);
|
||||
}
|
||||
|
||||
public function asCallable() {
|
||||
return is_callable($this->value) ? $this->value : null;
|
||||
}
|
||||
}
|
||||
|
||||
final class Options {
|
||||
|
||||
+86
-3
@@ -61,10 +61,13 @@ final class SigningTest extends CrtTestCase {
|
||||
const SIGV4TEST_SESSION_TOKEN = null;
|
||||
const SIGV4TEST_SERVICE = 'service';
|
||||
const SIGV4TEST_REGION = 'us-east-1';
|
||||
public function testSigv4HeaderSigning() {
|
||||
private static function SIGV4TEST_DATE() {
|
||||
return mktime(12, 36, 0, 8, 30, 2015);
|
||||
}
|
||||
|
||||
public function testShouldSignHeader() {
|
||||
$this->skipFFI();
|
||||
|
||||
$date = mktime(12, 36, 0, 8, 30, 2015);
|
||||
$credentials_provider = new StaticCredentialsProvider([
|
||||
'access_key_id' => self::SIGV4TEST_ACCESS_KEY_ID,
|
||||
'secret_access_key' => self::SIGV4TEST_SECRET_ACCESS_KEY,
|
||||
@@ -76,7 +79,48 @@ final class SigningTest extends CrtTestCase {
|
||||
'credentials_provider' => $credentials_provider,
|
||||
'region' => self::SIGV4TEST_REGION,
|
||||
'service' => self::SIGV4TEST_SERVICE,
|
||||
'date' => $date,
|
||||
'date' => self::SIGV4TEST_DATE(),
|
||||
'should_sign_header' => function($header) {
|
||||
return strtolower($header) != 'x-do-not-sign';
|
||||
}
|
||||
]);
|
||||
$http_request = new Request('GET', '/', [], [
|
||||
'Host' => 'example.amazonaws.com',
|
||||
'X-Do-Not-Sign' => 'DO NOT SIGN THIS']);
|
||||
$this->assertNotNull($http_request, "Unable to create HttpRequest for signing");
|
||||
$signable = Signable::fromHttpRequest($http_request);
|
||||
$this->assertNotNull($signable, "Unable to create signable from HttpRequest");
|
||||
|
||||
Signing::signRequestAws(
|
||||
$signable, $signing_config,
|
||||
function($signing_result, $error_code) use (&$http_request) {
|
||||
$this->assertEquals(0, $error_code);
|
||||
$signing_result->applyToHttpRequest($http_request);
|
||||
}
|
||||
);
|
||||
|
||||
// This signature value is computed without the X-Do-Not-Sign header above
|
||||
$headers = $http_request->headers();
|
||||
$this->assertEquals(
|
||||
'AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31',
|
||||
$headers->get('Authorization'));
|
||||
}
|
||||
|
||||
public function testSigv4HeaderSigning() {
|
||||
$this->skipFFI();
|
||||
|
||||
$credentials_provider = new StaticCredentialsProvider([
|
||||
'access_key_id' => self::SIGV4TEST_ACCESS_KEY_ID,
|
||||
'secret_access_key' => self::SIGV4TEST_SECRET_ACCESS_KEY,
|
||||
'session_token' => self::SIGV4TEST_SESSION_TOKEN,
|
||||
]);
|
||||
$signing_config = new SigningConfigAWS([
|
||||
'algorithm' => SigningAlgorithm::SIGv4,
|
||||
'signature_type' => SignatureType::HTTP_REQUEST_HEADERS,
|
||||
'credentials_provider' => $credentials_provider,
|
||||
'region' => self::SIGV4TEST_REGION,
|
||||
'service' => self::SIGV4TEST_SERVICE,
|
||||
'date' => self::SIGV4TEST_DATE(),
|
||||
]);
|
||||
$http_request = new Request('GET', '/', [], ['Host' => 'example.amazonaws.com']);
|
||||
$this->assertNotNull($http_request, "Unable to create HttpRequest for signing");
|
||||
@@ -97,4 +141,43 @@ final class SigningTest extends CrtTestCase {
|
||||
$headers->get('Authorization'));
|
||||
$this->assertEquals('20150830T123600Z', $headers->get('X-Amz-Date'));
|
||||
}
|
||||
|
||||
public function testSigV4aHeaderSigning() {
|
||||
$this->skipFFI();
|
||||
|
||||
$credentials_provider = new StaticCredentialsProvider([
|
||||
'access_key_id' => self::SIGV4TEST_ACCESS_KEY_ID,
|
||||
'secret_access_key' => self::SIGV4TEST_SECRET_ACCESS_KEY,
|
||||
'session_token' => self::SIGV4TEST_SESSION_TOKEN,
|
||||
]);
|
||||
$signing_config = new SigningConfigAWS([
|
||||
'algorithm' => SigningAlgorithm::SIGv4_ASYMMETRIC,
|
||||
'signature_type' => SignatureType::HTTP_REQUEST_HEADERS,
|
||||
'credentials_provider' => $credentials_provider,
|
||||
'region' => self::SIGV4TEST_REGION,
|
||||
'service' => self::SIGV4TEST_SERVICE,
|
||||
'date' => self::SIGV4TEST_DATE(),
|
||||
]);
|
||||
|
||||
$http_request = new Request('GET', '/', [], ['Host' => 'example.amazonaws.com']);
|
||||
$this->assertNotNull($http_request, "Unable to create HttpRequest for signing");
|
||||
$signable = Signable::fromHttpRequest($http_request);
|
||||
$this->assertNotNull($signable, "Unable to create signable from HttpRequest");
|
||||
|
||||
Signing::signRequestAws(
|
||||
$signable, $signing_config,
|
||||
function($signing_result, $error_code) use (&$http_request) {
|
||||
$this->assertEquals(0, $error_code);
|
||||
$signing_result->applyToHttpRequest($http_request);
|
||||
}
|
||||
);
|
||||
|
||||
$headers = $http_request->headers();
|
||||
$auth_header_value = $headers->get('Authorization');
|
||||
$this->assertNotNull($auth_header_value);
|
||||
$this->assertStringStartsWith(
|
||||
'AWS4-ECDSA-P256-SHA256 Credential=AKIDEXAMPLE/20150830/service/aws4_request, SignedHeaders=host;x-amz-date;x-amz-region-set, Signature=',
|
||||
$auth_header_value);
|
||||
$this->assertEquals('20150830T123600Z', $headers->get('X-Amz-Date'));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user