Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-c-io for openSUSE:Factory checked in at 2024-11-12 19:20:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-c-io (Old) and /work/SRC/openSUSE:Factory/.aws-c-io.new.2017 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-io" Tue Nov 12 19:20:53 2024 rev:14 rq:1223375 version:0.15.1 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-c-io/aws-c-io.changes 2024-08-09 16:15:17.540505196 +0200 +++ /work/SRC/openSUSE:Factory/.aws-c-io.new.2017/aws-c-io.changes 2024-11-12 19:21:34.059837164 +0100 @@ -1,0 +2,16 @@ +Thu Nov 7 17:39:11 UTC 2024 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- Update to version 0.15.1 + * chore: Modified bug issue template to add checkbox to + report potential regression. by @ashishdhingra in (#671) + * Fix s2n cleanup by @DmitriyMusatkin in #687 +- from version 0.15.0 + * Update CMake to 3.9 by @waahm7 in (#686) +- from version 0.14.20 + * Handle PKCS#8 private keys in Windows by @sfod in (#683) + * Add network interface name validation api by @waahm7 in (#675) +- from version 0.14.19 + * Clarify socket options logging by @sbSteveK in (#681) + * Use s2n_cleanup_thread() and path by @TingDaoK in (#682) + +------------------------------------------------------------------- Old: ---- v0.14.18.tar.gz New: ---- v0.15.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-c-io.spec ++++++ --- /var/tmp/diff_new_pack.oT3vhB/_old 2024-11-12 19:21:36.667946518 +0100 +++ /var/tmp/diff_new_pack.oT3vhB/_new 2024-11-12 19:21:36.679947021 +0100 @@ -15,12 +15,13 @@ # Please submit bugfixes or comments via https://bugs.opensuse.org/ # + %bcond_with test %define library_version 1.0.0 %define library_soversion 0unstable Name: aws-c-io -Version: 0.14.18 +Version: 0.15.1 Release: 0 Summary: I/O and TLS package AWS SDK for C License: Apache-2.0 @@ -31,11 +32,11 @@ Patch1: aci_add-so-version.patch BuildRequires: cmake BuildRequires: fdupes +BuildRequires: ninja BuildRequires: cmake(aws-c-cal) BuildRequires: cmake(aws-c-common) -BuildRequires: pkgconfig(libssl) BuildRequires: cmake(s2n) -BuildRequires: ninja +BuildRequires: pkgconfig(libssl) %description This is a module for the AWS SDK for C. It handles all I/O ++++++ v0.14.18.tar.gz -> v0.15.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/.github/ISSUE_TEMPLATE/bug-report.yml new/aws-c-io-0.15.1/.github/ISSUE_TEMPLATE/bug-report.yml --- old/aws-c-io-0.14.18/.github/ISSUE_TEMPLATE/bug-report.yml 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/.github/ISSUE_TEMPLATE/bug-report.yml 2024-10-30 18:57:18.000000000 +0100 @@ -12,6 +12,14 @@ description: What is the problem? A clear and concise description of the bug. validations: required: true + - type: checkboxes + id: regression + attributes: + label: Regression Issue + description: What is a regression? If it worked in a previous version but doesn't in the latest version, it's considered a regression. In this case, please provide specific version number in the report. + options: + - label: Select this option if this issue appears to be a regression. + required: false - type: textarea id: expected attributes: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/.github/workflows/issue-regression-labeler.yml new/aws-c-io-0.15.1/.github/workflows/issue-regression-labeler.yml --- old/aws-c-io-0.14.18/.github/workflows/issue-regression-labeler.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/aws-c-io-0.15.1/.github/workflows/issue-regression-labeler.yml 2024-10-30 18:57:18.000000000 +0100 @@ -0,0 +1,32 @@ +# Apply potential regression label on issues +name: issue-regression-label +on: + issues: + types: [opened, edited] +jobs: + add-regression-label: + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Fetch template body + id: check_regression + uses: actions/github-script@v7 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TEMPLATE_BODY: ${{ github.event.issue.body }} + with: + script: | + const regressionPattern = /\[x\] Select this option if this issue appears to be a regression\./i; + const template = `${process.env.TEMPLATE_BODY}` + const match = regressionPattern.test(template); + core.setOutput('is_regression', match); + - name: Manage regression label + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + if [ "${{ steps.check_regression.outputs.is_regression }}" == "true" ]; then + gh issue edit ${{ github.event.issue.number }} --add-label "potential-regression" -R ${{ github.repository }} + else + gh issue edit ${{ github.event.issue.number }} --remove-label "potential-regression" -R ${{ github.repository }} + fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/CMakeLists.txt new/aws-c-io-0.15.1/CMakeLists.txt --- old/aws-c-io-0.14.18/CMakeLists.txt 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/CMakeLists.txt 2024-10-30 18:57:18.000000000 +0100 @@ -1,11 +1,7 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) project(aws-c-io C) -if (POLICY CMP0069) - cmake_policy(SET CMP0069 NEW) # Enable LTO/IPO if available in the compiler, see AwsCFlags -endif() - if (DEFINED CMAKE_PREFIX_PATH) file(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH) endif() @@ -152,10 +148,21 @@ endif() if (USE_S2N) - file(GLOB AWS_IO_TLS_SRC - "source/s2n/*.c" - ) - aws_use_package(s2n) + file(GLOB AWS_IO_TLS_SRC + "source/s2n/*.c" + ) + # Prefer find_package() because it's the normal CMake way to do dependencies. + # But fall back on aws_use_package() because some projects still need to do an IN_SOURCE_BUILD of S2N. + # (e.g. aws-crt-java until this is resolved: https://github.com/awslabs/aws-crt-java/pull/817) + find_package(s2n QUIET) + + if (s2n_FOUND) + list(APPEND DEP_AWS_LIBS AWS::s2n) + else() + # Set flag to use in-source path to <s2n/unstable/*.h> headers if we do an IN_SOURCE_BUILD. + aws_use_package(s2n) + add_definitions(-DAWS_S2N_INSOURCE_PATH) + endif() endif() file(GLOB IO_HEADERS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/README.md new/aws-c-io-0.15.1/README.md --- old/aws-c-io-0.14.18/README.md 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/README.md 2024-10-30 18:57:18.000000000 +0100 @@ -18,7 +18,7 @@ ### Building -CMake 3.1+ is required to build. +CMake 3.9+ is required to build. `<install-path>` must be an absolute path in the following instructions. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/include/aws/io/socket.h new/aws-c-io-0.15.1/include/aws/io/socket.h --- old/aws-c-io-0.14.18/include/aws/io/socket.h 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/include/aws/io/socket.h 2024-10-30 18:57:18.000000000 +0100 @@ -337,6 +337,11 @@ */ AWS_IO_API void aws_socket_endpoint_init_local_address_for_test(struct aws_socket_endpoint *endpoint); +/** + * Validates whether the network interface name is valid. On Windows, it will always return false since we don't support + * network_interface_name on Windows */ +AWS_IO_API bool aws_is_network_interface_name_valid(const char *interface_name); + AWS_EXTERN_C_END AWS_POP_SANE_WARNING_LEVEL diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/source/future.c new/aws-c-io-0.15.1/source/future.c --- old/aws-c-io-0.14.18/source/future.c 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/source/future.c 2024-10-30 18:57:18.000000000 +0100 @@ -56,6 +56,15 @@ }; static void s_future_impl_result_dtor(struct aws_future_impl *future, void *result_addr) { + +/* + * On ARM machines, the compiler complains about the array bounds warning for aws_future_bool, even though + * aws_future_bool will never go into any destroy or release branch. Disable the warning since it's a false positive. + */ +#ifndef _MSC_VER +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Warray-bounds" +#endif switch (future->type) { case AWS_FUTURE_T_BY_VALUE_WITH_CLEAN_UP: { future->result_dtor.clean_up(result_addr); @@ -79,6 +88,9 @@ default: break; } +#ifndef _MSC_VER +# pragma GCC diagnostic pop +#endif } static void s_future_impl_destroy(void *user_data) { @@ -472,60 +484,7 @@ return is_done; } -// AWS_FUTURE_T_BY_VALUE_IMPLEMENTATION(aws_future_bool, bool) -struct aws_future_bool *aws_future_bool_new(struct aws_allocator *alloc) { - return (struct aws_future_bool *)aws_future_impl_new_by_value(alloc, sizeof(_Bool)); -} -void aws_future_bool_set_result(struct aws_future_bool *future, _Bool result) { - aws_future_impl_set_result_by_move((struct aws_future_impl *)future, &result); -} -_Bool aws_future_bool_get_result(const struct aws_future_bool *future) { - return *(_Bool *)aws_future_impl_get_result_address((const struct aws_future_impl *)future); -} -struct aws_future_bool *aws_future_bool_acquire(struct aws_future_bool *future) { - return (struct aws_future_bool *)aws_future_impl_acquire((struct aws_future_impl *)future); -} -struct aws_future_bool *aws_future_bool_release(struct aws_future_bool *future) { - return (struct aws_future_bool *)aws_future_impl_release((struct aws_future_impl *)future); -} -void aws_future_bool_set_error(struct aws_future_bool *future, int error_code) { - aws_future_impl_set_error((struct aws_future_impl *)future, error_code); -} -_Bool aws_future_bool_is_done(const struct aws_future_bool *future) { - return aws_future_impl_is_done((const struct aws_future_impl *)future); -} -int aws_future_bool_get_error(const struct aws_future_bool *future) { - return aws_future_impl_get_error((const struct aws_future_impl *)future); -} -void aws_future_bool_register_callback( - struct aws_future_bool *future, - aws_future_callback_fn *on_done, - void *user_data) { - aws_future_impl_register_callback((struct aws_future_impl *)future, on_done, user_data); -} -_Bool aws_future_bool_register_callback_if_not_done( - struct aws_future_bool *future, - aws_future_callback_fn *on_done, - void *user_data) { - return aws_future_impl_register_callback_if_not_done((struct aws_future_impl *)future, on_done, user_data); -} -void aws_future_bool_register_event_loop_callback( - struct aws_future_bool *future, - struct aws_event_loop *event_loop, - aws_future_callback_fn *on_done, - void *user_data) { - aws_future_impl_register_event_loop_callback((struct aws_future_impl *)future, event_loop, on_done, user_data); -} -void aws_future_bool_register_channel_callback( - struct aws_future_bool *future, - struct aws_channel *channel, - aws_future_callback_fn *on_done, - void *user_data) { - aws_future_impl_register_channel_callback((struct aws_future_impl *)future, channel, on_done, user_data); -} -_Bool aws_future_bool_wait(struct aws_future_bool *future, uint64_t timeout_ns) { - return aws_future_impl_wait((struct aws_future_impl *)future, timeout_ns); -} +AWS_FUTURE_T_BY_VALUE_IMPLEMENTATION(aws_future_bool, bool) AWS_FUTURE_T_BY_VALUE_IMPLEMENTATION(aws_future_size, size_t) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/source/posix/socket.c new/aws-c-io-0.15.1/source/posix/socket.c --- old/aws-c-io-0.14.18/source/posix/socket.c 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/source/posix/socket.c 2024-10-30 18:57:18.000000000 +0100 @@ -1220,7 +1220,8 @@ AWS_LOGF_DEBUG( AWS_LS_IO_SOCKET, - "id=%p fd=%d: setting socket options to: keep-alive %d, keep idle %d, keep-alive interval %d, keep-alive probe " + "id=%p fd=%d: setting socket options to: keep-alive %d, keep-alive timeout %d, keep-alive interval %d, " + "keep-alive probe " "count %d.", (void *)socket, socket->io_handle.data.fd, @@ -2007,3 +2008,11 @@ AWS_FATAL_ASSERT(aws_uuid_to_str(&uuid, &uuid_buf) == AWS_OP_SUCCESS); snprintf(endpoint->address, sizeof(endpoint->address), "testsock" PRInSTR ".sock", AWS_BYTE_BUF_PRI(uuid_buf)); } + +bool aws_is_network_interface_name_valid(const char *interface_name) { + if (if_nametoindex(interface_name) == 0) { + AWS_LOGF_ERROR(AWS_LS_IO_SOCKET, "network_interface_name(%s) is invalid with errno: %d", interface_name, errno); + return false; + } + return true; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/source/s2n/s2n_tls_channel_handler.c new/aws-c-io-0.15.1/source/s2n/s2n_tls_channel_handler.c --- old/aws-c-io-0.14.18/source/s2n/s2n_tls_channel_handler.c 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/source/s2n/s2n_tls_channel_handler.c 2024-10-30 18:57:18.000000000 +0100 @@ -20,10 +20,16 @@ #include <aws/common/task_scheduler.h> #include <aws/common/thread.h> +#include <s2n.h> +#ifdef AWS_S2N_INSOURCE_PATH +# include <api/unstable/cleanup.h> +#else +# include <s2n/unstable/cleanup.h> +#endif + #include <errno.h> #include <inttypes.h> #include <math.h> -#include <s2n.h> #include <stdio.h> #include <stdlib.h> @@ -249,7 +255,7 @@ void aws_tls_clean_up_static_state(void) { /* only clean up s2n if we were the ones that initialized it */ if (!s_s2n_initialized_externally) { - s2n_cleanup(); + s2n_cleanup_final(); } } @@ -1247,7 +1253,7 @@ static void s_aws_cleanup_s2n_thread_local_state(void *user_data) { (void)user_data; - s2n_cleanup(); + s2n_cleanup_thread(); } /* s2n allocates thread-local data structures. We need to clean these up when the event loop's thread exits. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/source/windows/iocp/socket.c new/aws-c-io-0.15.1/source/windows/iocp/socket.c --- old/aws-c-io-0.14.18/source/windows/iocp/socket.c 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/source/windows/iocp/socket.c 2024-10-30 18:57:18.000000000 +0100 @@ -3272,3 +3272,9 @@ AWS_FATAL_ASSERT(aws_uuid_to_str(&uuid, &uuid_buf) == AWS_OP_SUCCESS); snprintf(endpoint->address, sizeof(endpoint->address), "\\\\.\\pipe\\testsock" PRInSTR, AWS_BYTE_BUF_PRI(uuid_buf)); } + +bool aws_is_network_interface_name_valid(const char *interface_name) { + (void)interface_name; + AWS_LOGF_ERROR(AWS_LS_IO_SOCKET, "network_interface_names are not supported on Windows"); + return false; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/source/windows/windows_pki_utils.c new/aws-c-io-0.15.1/source/windows/windows_pki_utils.c --- old/aws-c-io-0.14.18/source/windows/windows_pki_utils.c 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/source/windows/windows_pki_utils.c 2024-10-30 18:57:18.000000000 +0100 @@ -559,6 +559,7 @@ int result = AWS_OP_ERR; BYTE *key = NULL; + BYTE *key_wrapper = NULL; if (aws_pem_objects_init_from_file_contents(&certificates, alloc, *public_cert_chain)) { AWS_LOGF_ERROR( @@ -640,6 +641,7 @@ struct aws_pem_object *private_key_ptr = NULL; DWORD decoded_len = 0; + DWORD decoded_wrapper_len = 0; enum aws_certificate_type cert_type = AWS_CT_X509_UNKNOWN; size_t private_key_count = aws_array_list_length(&private_keys); for (size_t i = 0; i < private_key_count; ++i) { @@ -655,6 +657,27 @@ &key, &decoded_len)) { cert_type = AWS_CT_X509_RSA; + } else if (CryptDecodeObjectEx( + X509_ASN_ENCODING, + PKCS_PRIVATE_KEY_INFO, + private_key_ptr->data.buffer, + (DWORD)private_key_ptr->data.len, + CRYPT_DECODE_ALLOC_FLAG, + 0, + &key_wrapper, + &decoded_wrapper_len)) { + CRYPT_PRIVATE_KEY_INFO *pPrivateKeyInfoStruct = (CRYPT_PRIVATE_KEY_INFO *)key_wrapper; + if (CryptDecodeObjectEx( + X509_ASN_ENCODING, + PKCS_RSA_PRIVATE_KEY, + pPrivateKeyInfoStruct->PrivateKey.pbData, + pPrivateKeyInfoStruct->PrivateKey.cbData, + CRYPT_DECODE_ALLOC_FLAG, + 0, + &key, + &decoded_len)) { + cert_type = AWS_CT_X509_RSA; + } } #ifndef AWS_SUPPORT_WIN7 else if (CryptDecodeObjectEx( @@ -721,6 +744,7 @@ aws_pem_objects_clean_up(&private_keys); LocalFree(key); + LocalFree(key_wrapper); if (result == AWS_OP_ERR) { if (*store != NULL) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/tests/CMakeLists.txt new/aws-c-io-0.15.1/tests/CMakeLists.txt --- old/aws-c-io-0.14.18/tests/CMakeLists.txt 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/tests/CMakeLists.txt 2024-10-30 18:57:18.000000000 +0100 @@ -58,6 +58,7 @@ add_net_test_case(udp_socket_communication) add_net_test_case(test_socket_with_bind_to_interface) add_net_test_case(test_socket_with_bind_to_invalid_interface) +add_net_test_case(test_is_network_interface_name_valid) add_test_case(udp_bind_connect_communication) add_net_test_case(connect_timeout) add_net_test_case(connect_timeout_cancelation) @@ -246,6 +247,7 @@ add_net_test_case(alpn_successfully_negotiates) add_net_test_case(alpn_no_protocol_message) add_net_test_case(test_ecc_cert_import) + add_net_test_case(test_pkcs8_import) add_test_case(alpn_error_creating_handler) add_test_case(tls_destroy_null_context) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/tests/socket_test.c new/aws-c-io-0.15.1/tests/socket_test.c --- old/aws-c-io-0.14.18/tests/socket_test.c 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/tests/socket_test.c 2024-10-30 18:57:18.000000000 +0100 @@ -496,6 +496,20 @@ } AWS_TEST_CASE(test_socket_with_bind_to_invalid_interface, s_test_socket_with_bind_to_invalid_interface) +static int s_test_is_network_interface_name_valid(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + (void)allocator; + + ASSERT_FALSE(aws_is_network_interface_name_valid("invalid_name")); +#if defined(AWS_OS_LINUX) + ASSERT_TRUE(aws_is_network_interface_name_valid("lo")); +#elif !defined(AWS_OS_WINDOWS) + ASSERT_TRUE(aws_is_network_interface_name_valid("lo0")); +#endif + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(test_is_network_interface_name_valid, s_test_is_network_interface_name_valid) + #if defined(USE_VSOCK) static int s_test_vsock_loopback_socket_communication(struct aws_allocator *allocator, void *ctx) { /* Without vsock loopback it's difficult to test vsock functionality. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.14.18/tests/tls_handler_test.c new/aws-c-io-0.15.1/tests/tls_handler_test.c --- old/aws-c-io-0.14.18/tests/tls_handler_test.c 2024-08-03 00:35:40.000000000 +0200 +++ new/aws-c-io-0.15.1/tests/tls_handler_test.c 2024-10-30 18:57:18.000000000 +0100 @@ -2503,4 +2503,40 @@ AWS_TEST_CASE(test_ecc_cert_import, s_test_ecc_cert_import) +static int s_test_pkcs8_import(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + (void)allocator; + + aws_io_library_init(allocator); + + struct aws_byte_buf cert_buf; + struct aws_byte_buf key_buf; + + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&cert_buf, allocator, "unittests.crt")); + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&key_buf, allocator, "unittests.p8")); + + struct aws_byte_cursor cert_cur = aws_byte_cursor_from_buf(&cert_buf); + struct aws_byte_cursor key_cur = aws_byte_cursor_from_buf(&key_buf); + struct aws_tls_ctx_options tls_options = {0}; + AWS_FATAL_ASSERT( + AWS_OP_SUCCESS == aws_tls_ctx_options_init_client_mtls(&tls_options, allocator, &cert_cur, &key_cur)); + + /* import happens in here */ + struct aws_tls_ctx *tls_context = aws_tls_client_ctx_new(allocator, &tls_options); + ASSERT_NOT_NULL(tls_context); + + aws_tls_ctx_release(tls_context); + + aws_tls_ctx_options_clean_up(&tls_options); + + aws_byte_buf_clean_up(&cert_buf); + aws_byte_buf_clean_up(&key_buf); + + aws_io_library_clean_up(); + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(test_pkcs8_import, s_test_pkcs8_import) + #endif /* BYO_CRYPTO */