static napi_value s_aws_verify_sigv4a_signing()

in source/auth.c [653:776]


static napi_value s_aws_verify_sigv4a_signing(napi_env env, const struct aws_napi_callback_info *cb_info) {

    napi_value result = NULL;

    AWS_NAPI_ENSURE(env, napi_get_boolean(env, false, &result));

    struct aws_allocator *allocator = aws_napi_get_allocator();
    const struct aws_napi_argument *arg = NULL;

    struct signer_sign_request_state *state = aws_mem_calloc(allocator, 1, sizeof(struct signer_sign_request_state));
    if (!state) {
        return result;
    }

    /* Temp buffers */
    struct aws_byte_buf region_buf;
    AWS_ZERO_STRUCT(region_buf);
    struct aws_byte_buf service_buf;
    AWS_ZERO_STRUCT(service_buf);
    struct aws_byte_buf signed_body_value_buf;
    AWS_ZERO_STRUCT(signed_body_value_buf);
    struct aws_byte_buf expected_canonical_request_buf;
    AWS_ZERO_STRUCT(expected_canonical_request_buf);
    struct aws_byte_buf signature_buf;
    AWS_ZERO_STRUCT(signature_buf);
    struct aws_byte_buf ecc_key_pub_x_buf;
    AWS_ZERO_STRUCT(ecc_key_pub_x_buf);
    struct aws_byte_buf ecc_key_pub_y_buf;
    AWS_ZERO_STRUCT(ecc_key_pub_y_buf);

    /* Get request */
    aws_napi_method_next_argument(napi_object, cb_info, &arg);
    state->request = aws_napi_http_message_unwrap(env, arg->node);
    state->signable = aws_signable_new_http_request(allocator, state->request);

    /* Populate config */
    struct aws_signing_config_aws config;
    AWS_ZERO_STRUCT(config);

    aws_napi_method_next_argument(napi_object, cb_info, &arg);
    napi_value js_config = arg->node;

    if (s_get_config_from_js_config(
            env, &config, js_config, &region_buf, &service_buf, &signed_body_value_buf, state, allocator)) {
        /* error already raised */
        goto done;
    }

    aws_napi_method_next_argument(napi_string, cb_info, &arg);
    napi_value node_expected_canonical_request = arg->node;
    if (aws_byte_buf_init_from_napi(&expected_canonical_request_buf, env, node_expected_canonical_request)) {
        napi_throw_type_error(env, NULL, "The expected canonical request must be a string");
        goto done;
    }

    aws_napi_method_next_argument(napi_string, cb_info, &arg);
    napi_value node_signature = arg->node;
    if (aws_byte_buf_init_from_napi(&signature_buf, env, node_signature)) {
        napi_throw_type_error(env, NULL, "The signature must be a string");
        goto done;
    }

    aws_napi_method_next_argument(napi_string, cb_info, &arg);
    napi_value node_ecc_key_pub_x = arg->node;
    if (aws_byte_buf_init_from_napi(&ecc_key_pub_x_buf, env, node_ecc_key_pub_x)) {
        napi_throw_type_error(env, NULL, "The public ecc key must be a string");
        goto done;
    }

    aws_napi_method_next_argument(napi_string, cb_info, &arg);
    napi_value node_ecc_key_pub_y = arg->node;
    if (aws_byte_buf_init_from_napi(&ecc_key_pub_y_buf, env, node_ecc_key_pub_y)) {
        napi_throw_type_error(env, NULL, "The public ecc key must be a string");
        goto done;
    }

    struct sigv4a_credentail_getter_state credential_state;
    AWS_ZERO_STRUCT(credential_state);
    credential_state.allocator = allocator;
    credential_state.config = &config;
    aws_condition_variable_init(&credential_state.cvar);
    aws_mutex_init(&credential_state.lock);
    /* get credential from provider for the verification */
    if (aws_credentials_provider_get_credentials(
            config.credentials_provider, s_aws_signv4a_on_get_credentials, &credential_state)) {
        goto done;
    }
    /* wait for credential provider getting the credential */
    s_wait_for_get_credential_to_complete(&credential_state);
    if (!config.credentials) {
        napi_throw_type_error(env, NULL, "Failed to get credentials from credential provider");
        goto done;
    }

    if (aws_verify_sigv4a_signing(
            allocator,
            state->signable,
            (struct aws_signing_config_base *)&config,
            aws_byte_cursor_from_buf(&expected_canonical_request_buf),
            aws_byte_cursor_from_buf(&signature_buf),
            aws_byte_cursor_from_buf(&ecc_key_pub_x_buf),
            aws_byte_cursor_from_buf(&ecc_key_pub_y_buf))) {
        /* Verification failed, the signature result is wrong. */
        aws_napi_throw_last_error(env);
        goto done;
    }

    /* verification succeed */
    AWS_NAPI_ENSURE(env, napi_get_boolean(env, true, &result));

done:
    s_destroy_signing_binding(env, allocator, state);

    aws_credentials_provider_release(config.credentials_provider);
    aws_byte_buf_clean_up(&region_buf);
    aws_byte_buf_clean_up(&service_buf);
    aws_byte_buf_clean_up(&signed_body_value_buf);
    aws_byte_buf_clean_up(&expected_canonical_request_buf);
    aws_byte_buf_clean_up(&signature_buf);
    aws_byte_buf_clean_up(&ecc_key_pub_x_buf);
    aws_byte_buf_clean_up(&ecc_key_pub_y_buf);

    return result;
}