s2n-tls-ffi (empty) → 0.1.0.0
raw patch · 9 files changed
+7363/−0 lines, 9 filesdep +basedep +s2n-tls-ffidep +unix
Dependencies added: base, s2n-tls-ffi, unix
Files
- CHANGELOG.md +6/−0
- LICENSE +190/−0
- README.md +77/−0
- cbits/s2n_wrapper.c +3185/−0
- cbits/s2n_wrapper.h +1294/−0
- s2n-tls-ffi.cabal +60/−0
- src/S2nTls/Ffi.hs +918/−0
- src/S2nTls/Ffi/Types.hs +1134/−0
- test/MemorySafety.hs +499/−0
+ CHANGELOG.md view
@@ -0,0 +1,6 @@+# Changelog++## 0.1.0.0 -- 2026-04-28++* Initial release+* Support for linked and dynamic loading via `Library` type
+ LICENSE view
@@ -0,0 +1,190 @@+ Apache License+ Version 2.0, January 2004+ http://www.apache.org/licenses/++ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION++ 1. Definitions.++ "License" shall mean the terms and conditions for use, reproduction,+ and distribution as defined by Sections 1 through 9 of this document.++ "Licensor" shall mean the copyright owner or entity authorized by+ the copyright owner that is granting the License.++ "Legal Entity" shall mean the union of the acting entity and all+ other entities that control, are controlled by, or are under common+ control with that entity. For the purposes of this definition,+ "control" means (i) the power, direct or indirect, to cause the+ direction or management of such entity, whether by contract or+ otherwise, or (ii) ownership of fifty percent (50%) or more of the+ outstanding shares, or (iii) beneficial ownership of such entity.++ "You" (or "Your") shall mean an individual or Legal Entity+ exercising permissions granted by this License.++ "Source" form shall mean the preferred form for making modifications,+ including but not limited to software source code, documentation+ source, and configuration files.++ "Object" form shall mean any form resulting from mechanical+ transformation or translation of a Source form, including but+ not limited to compiled object code, generated documentation,+ and conversions to other media types.++ "Work" shall mean the work of authorship, whether in Source or+ Object form, made available under the License, as indicated by a+ copyright notice that is included in or attached to the work+ (an example is provided in the Appendix below).++ "Derivative Works" shall mean any work, whether in Source or Object+ form, that is based on (or derived from) the Work and for which the+ editorial revisions, annotations, elaborations, or other modifications+ represent, as a whole, an original work of authorship. For the purposes+ of this License, Derivative Works shall not include works that remain+ separable from, or merely link (or bind by name) to the interfaces of,+ the Work and Derivative Works thereof.++ "Contribution" shall mean any work of authorship, including+ the original version of the Work and any modifications or additions+ to that Work or Derivative Works thereof, that is intentionally+ submitted to the Licensor for inclusion in the Work by the copyright owner+ or by an individual or Legal Entity authorized to submit on behalf of+ the copyright owner. For the purposes of this definition, "submitted"+ means any form of electronic, verbal, or written communication sent+ to the Licensor or its representatives, including but not limited to+ communication on electronic mailing lists, source code control systems,+ and issue tracking systems that are managed by, or on behalf of, the+ Licensor for the purpose of discussing and improving the Work, but+ excluding communication that is conspicuously marked or otherwise+ designated in writing by the copyright owner as "Not a Contribution."++ "Contributor" shall mean Licensor and any individual or Legal Entity+ on behalf of whom a Contribution has been received by Licensor and+ subsequently incorporated within the Work.++ 2. Grant of Copyright License. Subject to the terms and conditions of+ this License, each Contributor hereby grants to You a perpetual,+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable+ copyright license to reproduce, prepare Derivative Works of,+ publicly display, publicly perform, sublicense, and distribute the+ Work and such Derivative Works in Source or Object form.++ 3. Grant of Patent License. Subject to the terms and conditions of+ this License, each Contributor hereby grants to You a perpetual,+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable+ (except as stated in this section) patent license to make, have made,+ use, offer to sell, sell, import, and otherwise transfer the Work,+ where such license applies only to those patent claims licensable+ by such Contributor that are necessarily infringed by their+ Contribution(s) alone or by combination of their Contribution(s)+ with the Work to which such Contribution(s) was submitted. If You+ institute patent litigation against any entity (including a+ cross-claim or counterclaim in a lawsuit) alleging that the Work+ or a Contribution incorporated within the Work constitutes direct+ or contributory patent infringement, then any patent licenses+ granted to You under this License for that Work shall terminate+ as of the date such litigation is filed.++ 4. Redistribution. You may reproduce and distribute copies of the+ Work or Derivative Works thereof in any medium, with or without+ modifications, and in Source or Object form, provided that You+ meet the following conditions:++ (a) You must give any other recipients of the Work or+ Derivative Works a copy of this License; and++ (b) You must cause any modified files to carry prominent notices+ stating that You changed the files; and++ (c) You must retain, in the Source form of any Derivative Works+ that You distribute, all copyright, patent, trademark, and+ attribution notices from the Source form of the Work,+ excluding those notices that do not pertain to any part of+ the Derivative Works; and++ (d) If the Work includes a "NOTICE" text file as part of its+ distribution, then any Derivative Works that You distribute must+ include a readable copy of the attribution notices contained+ within such NOTICE file, excluding those notices that do not+ pertain to any part of the Derivative Works, in at least one+ of the following places: within a NOTICE text file distributed+ as part of the Derivative Works; within the Source form or+ documentation, if provided along with the Derivative Works; or,+ within a display generated by the Derivative Works, if and+ wherever such third-party notices normally appear. The contents+ of the NOTICE file are for informational purposes only and+ do not modify the License. You may add Your own attribution+ notices within Derivative Works that You distribute, alongside+ or as an addendum to the NOTICE text from the Work, provided+ that such additional attribution notices cannot be construed+ as modifying the License.++ You may add Your own copyright statement to Your modifications and+ may provide additional or different license terms and conditions+ for use, reproduction, or distribution of Your modifications, or+ for any such Derivative Works as a whole, provided Your use,+ reproduction, and distribution of the Work otherwise complies with+ the conditions stated in this License.++ 5. Submission of Contributions. Unless You explicitly state otherwise,+ any Contribution intentionally submitted for inclusion in the Work+ by You to the Licensor shall be under the terms and conditions of+ this License, without any additional terms or conditions.+ Notwithstanding the above, nothing herein shall supersede or modify+ the terms of any separate license agreement you may have executed+ with Licensor regarding such Contributions.++ 6. Trademarks. This License does not grant permission to use the trade+ names, trademarks, service marks, or product names of the Licensor,+ except as required for reasonable and customary use in describing the+ origin of the Work and reproducing the content of the NOTICE file.++ 7. Disclaimer of Warranty. Unless required by applicable law or+ agreed to in writing, Licensor provides the Work (and each+ Contributor provides its Contributions) on an "AS IS" BASIS,+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or+ implied, including, without limitation, any warranties or conditions+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A+ PARTICULAR PURPOSE. You are solely responsible for determining the+ appropriateness of using or redistributing the Work and assume any+ risks associated with Your exercise of permissions under this License.++ 8. Limitation of Liability. In no event and under no legal theory,+ whether in tort (including negligence), contract, or otherwise,+ unless required by applicable law (such as deliberate and grossly+ negligent acts) or agreed to in writing, shall any Contributor be+ liable to You for damages, including any direct, indirect, special,+ incidental, or consequential damages of any character arising as a+ result of this License or out of the use or inability to use the+ Work (including but not limited to damages for loss of goodwill,+ work stoppage, computer failure or malfunction, or any and all+ other commercial damages or losses), even if such Contributor+ has been advised of the possibility of such damages.++ 9. Accepting Warranty or Additional Liability. While redistributing+ the Work or Derivative Works thereof, You may choose to offer,+ and charge a fee for, acceptance of support, warranty, indemnity,+ or other liability obligations and/or rights consistent with this+ License. However, in accepting such obligations, You may act only+ on Your own behalf and on Your sole responsibility, not on behalf+ of any other Contributor, and only if You agree to indemnify,+ defend, and hold each Contributor harmless for any liability+ incurred by, or claims asserted against, such Contributor by reason+ of your accepting any such warranty or additional liability.++ END OF TERMS AND CONDITIONS++ Copyright 2026 Daniel Goertzen++ Licensed under the Apache License, Version 2.0 (the "License");+ you may not use this file except in compliance with the License.+ You may obtain a copy of the License at++ http://www.apache.org/licenses/LICENSE-2.0++ Unless required by applicable law or agreed to in writing, software+ distributed under the License is distributed on an "AS IS" BASIS,+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ See the License for the specific language governing permissions and+ limitations under the License.
+ README.md view
@@ -0,0 +1,77 @@+# s2n-tls-ffi++Low-level FFI bindings to the [s2n-tls](https://github.com/aws/s2n-tls) library.++This package provides raw FFI bindings which higher-level packages can build upon.++### Using a Linked s2n-tls Library++Call `withS2nTlsFfi` with `Linked` to use the linked-in s2n-tls library.++```haskell+import S2nTls.Ffi++main :: IO ()+main = withS2nTlsFfi Linked $ \ffi -> do+ -- use ffi...+```++### Using a Dynamically Loaded s2n-tls library++Call `withS2nTlsFfi` with `Dynamic path` to load s2n-tls at runtime. This enables runtime selection of different library builds - for example, switching between FIPS and non-FIPS crypto backends without recompiling your application.++```haskell+import S2nTls.Ffi++main :: IO ()+main = do+ let lib = if needFips then Dynamic "libs2n-fips.so" else Dynamic "libs2n.so"+ withS2nTlsFfi lib $ \ffi -> do+ -- use ffi...+```++## Error Handling via C Wrappers++s2n-tls stores error information in thread-local storage (TLS). When a function fails, the error code and debug message are available via `s2n_errno_location()` and `s2n_strerror_debug()`. However, Haskell's FFI provides no guarantee that a subsequent call will execute on the same OS thread, making direct access to thread-local error state unreliable.++To solve this, most s2n functions are called through thin C wrappers that:++1. Call the underlying s2n function+2. If it fails, immediately read the error code and debug string from TLS+3. Copy this information into an output struct with an owned 256-byte buffer+4. Return to Haskell with the error information safely captured++This ensures error information is captured in the same C stack frame before control returns to Haskell. The `S2nTlsFfi` record exposes these wrapped functions, which return `Either S2nError result` for functions that can fail.++Note that `s2n_send` and `s2n_recv` have special behavior: if the error was `S2N_ERR_T_BLOCKED`, debug info is not captured because this is a frequent, expected case that doesn't need debug overhead.++### Direct Error Functions++The `s2n_strerror` and `s2n_strerror_name` functions are **not** subject to thread-local storage limitations - they take an error code as input and return static strings. These can be called directly without wrappers if you need to format error messages yourself.++## Missing Symbol Behavior++Symbol loading is forgiving - missing symbols don't cause failure at load time. This allows the bindings to work with different versions of s2n-tls that may not export all functions.++- The `missingSymbols` field of `S2nTlsFfi` lists symbol names that couldn't be loaded+- Calling a function for a missing symbol throws a `MissingSymbol` exception+- Check `missingSymbols` at startup if your application requires specific functions++## Tests++The `memory-safety` test suite invokes all FFI functions to detect segfaults and memory errors. It does not verify correct behavior - only that calling each function doesn't crash. Each function name is printed before invocation, so if a crash occurs you can identify the culprit.++Run with:++```+cabal test memory-safety+```++## Related Packages++- [s2n-tls](https://github.com/goertzenator/s2n-tls) - High-level Haskell bindings built on this package+- [warp-s2n-tls](https://github.com/goertzenator/warp-s2n-tls) - TLS support for Warp using s2n-tls++## License++Apache-2.0
+ cbits/s2n_wrapper.c view
@@ -0,0 +1,3185 @@+/*+ * s2n_wrapper.c - C wrappers for s2n-tls functions+ *+ * These wrappers capture error information from thread-local storage+ * immediately after s2n function calls, making error handling safe+ * for Haskell FFI where TLS can be unreliable.+ */++#include "s2n_wrapper.h"+#include <stddef.h>+#include <stdio.h>++/* ============================================================================+ * Initialization & Cleanup+ * ============================================================================ */++int s2n_wrap_init(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn();+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cleanup(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn();+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cleanup_final(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn();+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_crypto_disable_init(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn();+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_disable_atexit(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn();+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_get_fips_mode(+ int (*fn)(int *),+ int *fips_mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(fips_mode);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Stack Traces+ * ============================================================================ */++int s2n_wrap_stack_traces_enabled_set(+ int (*fn)(int),+ int enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(enabled);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_calculate_stacktrace(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn();+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_free_stacktrace(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn();+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_get_stacktrace(+ int (*fn)(void *),+ void *stacktrace,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(stacktrace);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Config Management+ * ============================================================================ */++void *s2n_wrap_config_new(+ void *(*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn();+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++void *s2n_wrap_config_new_minimal(+ void *(*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn();+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_free(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_free_dhparams(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_free_cert_chain_and_key(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_wall_clock(+ int (*fn)(void *, void *, void *),+ void *config, void *clock_fn, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, clock_fn, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_monotonic_clock(+ int (*fn)(void *, void *, void *),+ void *config, void *clock_fn, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, clock_fn, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Cache Callbacks+ * ============================================================================ */++int s2n_wrap_config_set_cache_store_callback(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, callback, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_cache_retrieve_callback(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, callback, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_cache_delete_callback(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, callback, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Memory & Random Callbacks+ * ============================================================================ */++int s2n_wrap_mem_set_callbacks(+ int (*fn)(void *, void *, void *, void *),+ void *init_cb, void *cleanup_cb, void *malloc_cb, void *free_cb,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(init_cb, cleanup_cb, malloc_cb, free_cb);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_rand_set_callbacks(+ int (*fn)(void *, void *, void *, void *),+ void *init_cb, void *cleanup_cb, void *seed_cb, void *mix_cb,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(init_cb, cleanup_cb, seed_cb, mix_cb);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Certificate Chain Management+ * ============================================================================ */++void *s2n_wrap_cert_chain_and_key_new(+ void *(*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn();+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_chain_and_key_load_pem(+ int (*fn)(void *, const char *, const char *),+ void *chain_and_key, const char *chain_pem, const char *private_key_pem,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(chain_and_key, chain_pem, private_key_pem);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_chain_and_key_load_pem_bytes(+ int (*fn)(void *, const uint8_t *, uint32_t, const uint8_t *, uint32_t),+ void *chain_and_key, const uint8_t *chain_pem, uint32_t chain_pem_len,+ const uint8_t *private_key_pem, uint32_t private_key_pem_len,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(chain_and_key, chain_pem, chain_pem_len, private_key_pem, private_key_pem_len);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_chain_and_key_load_public_pem_bytes(+ int (*fn)(void *, const uint8_t *, uint32_t),+ void *chain_and_key, const uint8_t *chain_pem, uint32_t chain_pem_len,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(chain_and_key, chain_pem, chain_pem_len);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_chain_and_key_free(+ int (*fn)(void *),+ void *chain_and_key,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(chain_and_key);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_chain_and_key_set_ctx(+ int (*fn)(void *, void *),+ void *chain_and_key, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(chain_and_key, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++void *s2n_wrap_cert_chain_and_key_get_ctx(+ void *(*fn)(void *),+ void *chain_and_key,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn(chain_and_key);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++void *s2n_wrap_cert_chain_and_key_get_private_key(+ void *(*fn)(void *),+ void *chain_and_key,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn(chain_and_key);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_chain_and_key_set_ocsp_data(+ int (*fn)(void *, const uint8_t *, uint32_t),+ void *chain_and_key, const uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(chain_and_key, data, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_chain_and_key_set_sct_list(+ int (*fn)(void *, const uint8_t *, uint32_t),+ void *chain_and_key, const uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(chain_and_key, data, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_cert_tiebreak_callback(+ int (*fn)(void *, void *),+ void *config, void *callback,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, callback);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_add_cert_chain_and_key(+ int (*fn)(void *, const char *, const char *),+ void *config, const char *chain_pem, const char *private_key_pem,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, chain_pem, private_key_pem);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_add_cert_chain_and_key_to_store(+ int (*fn)(void *, void *),+ void *config, void *chain_and_key,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, chain_and_key);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_cert_chain_and_key_defaults(+ int (*fn)(void *, void **, uint32_t),+ void *config, void **chain_and_key_array, uint32_t count,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, chain_and_key_array, count);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Trust Store+ * ============================================================================ */++int s2n_wrap_config_set_verification_ca_location(+ int (*fn)(void *, const char *, const char *),+ void *config, const char *ca_pem_filename, const char *ca_dir,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, ca_pem_filename, ca_dir);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_add_pem_to_trust_store(+ int (*fn)(void *, const char *),+ void *config, const char *pem,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, pem);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_wipe_trust_store(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_load_system_certs(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_cert_authorities_from_trust_store(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Verification & Validation+ * ============================================================================ */++int s2n_wrap_config_set_verify_after_sign(+ int (*fn)(void *, int),+ void *config, int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, mode);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_check_stapled_ocsp_response(+ int (*fn)(void *, uint8_t),+ void *config, uint8_t check,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, check);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_disable_x509_time_verification(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_disable_x509_verification(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_max_cert_chain_depth(+ int (*fn)(void *, uint16_t),+ void *config, uint16_t depth,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, depth);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_verify_host_callback(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, callback, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * DH Parameters+ * ============================================================================ */++int s2n_wrap_config_add_dhparams(+ int (*fn)(void *, const char *),+ void *config, const char *dhparams_pem,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, dhparams_pem);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Security Policies & Preferences+ * ============================================================================ */++int s2n_wrap_config_set_cipher_preferences(+ int (*fn)(void *, const char *),+ void *config, const char *version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, version);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_append_protocol_preference(+ int (*fn)(void *, const uint8_t *, uint8_t),+ void *config, const uint8_t *protocol, uint8_t protocol_len,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, protocol, protocol_len);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_protocol_preferences(+ int (*fn)(void *, const char **, int),+ void *config, const char **protocols, int protocol_count,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, protocols, protocol_count);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_status_request_type(+ int (*fn)(void *, int),+ void *config, int type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, type);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_ct_support_level(+ int (*fn)(void *, int),+ void *config, int level,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, level);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_alert_behavior(+ int (*fn)(void *, int),+ void *config, int behavior,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, behavior);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Extension Data+ * ============================================================================ */++int s2n_wrap_config_set_extension_data(+ int (*fn)(void *, int, const uint8_t *, uint32_t),+ void *config, int extension_type, const uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, extension_type, data, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_send_max_fragment_length(+ int (*fn)(void *, int),+ void *config, int mfl_code,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, mfl_code);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_accept_max_fragment_length(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Session & Ticket Configuration+ * ============================================================================ */++int s2n_wrap_config_set_session_state_lifetime(+ int (*fn)(void *, uint64_t),+ void *config, uint64_t lifetime,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, lifetime);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_session_tickets_onoff(+ int (*fn)(void *, uint8_t),+ void *config, uint8_t enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, enabled);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_session_cache_onoff(+ int (*fn)(void *, uint8_t),+ void *config, uint8_t enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, enabled);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_ticket_encrypt_decrypt_key_lifetime(+ int (*fn)(void *, uint64_t),+ void *config, uint64_t lifetime,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, lifetime);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_ticket_decrypt_key_lifetime(+ int (*fn)(void *, uint64_t),+ void *config, uint64_t lifetime,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, lifetime);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_add_ticket_crypto_key(+ int (*fn)(void *, const uint8_t *, uint32_t, const uint8_t *, uint32_t, uint64_t),+ void *config, const uint8_t *name, uint32_t name_len,+ const uint8_t *key, uint32_t key_len, uint64_t intro_time_in_seconds_from_epoch,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, name, name_len, key, key_len, intro_time_in_seconds_from_epoch);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_require_ticket_forward_secrecy(+ int (*fn)(void *, int),+ void *config, int enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, enabled);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Buffer & I/O Configuration+ * ============================================================================ */++int s2n_wrap_config_set_send_buffer_size(+ int (*fn)(void *, uint32_t),+ void *config, uint32_t size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, size);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_recv_multi_record(+ int (*fn)(void *, int),+ void *config, int enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, enabled);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Miscellaneous Config+ * ============================================================================ */++int s2n_wrap_config_set_ctx(+ int (*fn)(void *, void *),+ void *config, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_get_ctx(+ int (*fn)(void *, void **),+ void *config, void **ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_client_hello_cb(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, callback, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_client_hello_cb_mode(+ int (*fn)(void *, int),+ void *config, int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, mode);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_max_blinding_delay(+ int (*fn)(void *, uint32_t),+ void *config, uint32_t max_delay,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, max_delay);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_get_client_auth_type(+ int (*fn)(void *, int *),+ void *config, int *auth_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, auth_type);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_client_auth_type(+ int (*fn)(void *, int),+ void *config, int auth_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, auth_type);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_initial_ticket_count(+ int (*fn)(void *, uint8_t),+ void *config, uint8_t count,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, count);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_psk_mode(+ int (*fn)(void *, int),+ void *config, int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, mode);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_psk_selection_callback(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, callback, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_async_pkey_callback(+ int (*fn)(void *, void *),+ void *config, void *callback,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, callback);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_async_pkey_validation_mode(+ int (*fn)(void *, int),+ void *config, int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, mode);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_session_ticket_cb(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, callback, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_key_log_cb(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, callback, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_enable_cert_req_dss_legacy_compat(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_server_max_early_data_size(+ int (*fn)(void *, uint32_t),+ void *config, uint32_t size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, size);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_early_data_cb(+ int (*fn)(void *, void *),+ void *config, void *callback,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, callback);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_get_supported_groups(+ int (*fn)(void *, uint16_t *, uint16_t, uint16_t *),+ void *config, uint16_t *groups, uint16_t groups_count, uint16_t *groups_count_out,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, groups, groups_count, groups_count_out);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_config_set_serialization_version(+ int (*fn)(void *, int),+ void *config, int version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(config, version);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Connection Creation & Management+ * ============================================================================ */++void *s2n_wrap_connection_new(+ void *(*fn)(int),+ int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn(mode);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_config(+ int (*fn)(void *, void *),+ void *conn, void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, config);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_ctx(+ int (*fn)(void *, void *),+ void *conn, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++void *s2n_wrap_connection_get_ctx(+ void *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn(conn);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_cb_done(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_server_name_extension_used(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Client Hello Access+ * ============================================================================ */++void *s2n_wrap_connection_get_client_hello(+ void *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn(conn);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++void *s2n_wrap_client_hello_parse_message(+ void *(*fn)(const uint8_t *, uint32_t),+ const uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn(data, length);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_free(+ int (*fn)(void **),+ void **client_hello,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(client_hello);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++ssize_t s2n_wrap_client_hello_get_raw_message_length(+ ssize_t (*fn)(void *),+ void *client_hello,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ ssize_t result = fn(client_hello);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++ssize_t s2n_wrap_client_hello_get_raw_message(+ ssize_t (*fn)(void *, uint8_t *, uint32_t),+ void *client_hello, uint8_t *out, uint32_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ ssize_t result = fn(client_hello, out, max_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++ssize_t s2n_wrap_client_hello_get_cipher_suites_length(+ ssize_t (*fn)(void *),+ void *client_hello,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ ssize_t result = fn(client_hello);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++ssize_t s2n_wrap_client_hello_get_cipher_suites(+ ssize_t (*fn)(void *, uint8_t *, uint32_t),+ void *client_hello, uint8_t *out, uint32_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ ssize_t result = fn(client_hello, out, max_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++ssize_t s2n_wrap_client_hello_get_extensions_length(+ ssize_t (*fn)(void *),+ void *client_hello,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ ssize_t result = fn(client_hello);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++ssize_t s2n_wrap_client_hello_get_extensions(+ ssize_t (*fn)(void *, uint8_t *, uint32_t),+ void *client_hello, uint8_t *out, uint32_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ ssize_t result = fn(client_hello, out, max_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++ssize_t s2n_wrap_client_hello_get_extension_length(+ ssize_t (*fn)(void *, int),+ void *client_hello, int extension_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ ssize_t result = fn(client_hello, extension_type);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++ssize_t s2n_wrap_client_hello_get_extension_by_id(+ ssize_t (*fn)(void *, int, uint8_t *, uint32_t),+ void *client_hello, int extension_type, uint8_t *out, uint32_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ ssize_t result = fn(client_hello, extension_type, out, max_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_has_extension(+ int (*fn)(void *, uint16_t, int *),+ void *client_hello, uint16_t extension_iana, int *exists,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(client_hello, extension_iana, exists);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_get_session_id_length(+ int (*fn)(void *, uint32_t *),+ void *client_hello, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(client_hello, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_get_session_id(+ int (*fn)(void *, uint8_t *, uint32_t *, uint32_t),+ void *client_hello, uint8_t *out, uint32_t *out_length, uint32_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(client_hello, out, out_length, max_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_get_compression_methods_length(+ int (*fn)(void *, uint32_t *),+ void *client_hello, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(client_hello, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_get_compression_methods(+ int (*fn)(void *, uint8_t *, uint32_t, uint32_t *),+ void *client_hello, uint8_t *out, uint32_t max_length, uint32_t *out_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(client_hello, out, max_length, out_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_get_legacy_protocol_version(+ int (*fn)(void *, uint8_t *),+ void *client_hello, uint8_t *version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(client_hello, version);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_get_supported_groups(+ int (*fn)(void *, uint16_t *, uint16_t, uint16_t *),+ void *client_hello, uint16_t *groups, uint16_t groups_count, uint16_t *groups_count_out,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(client_hello, groups, groups_count, groups_count_out);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_get_server_name_length(+ int (*fn)(void *, uint16_t *),+ void *client_hello, uint16_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(client_hello, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_get_server_name(+ int (*fn)(void *, uint8_t *, uint16_t, uint16_t *),+ void *client_hello, uint8_t *out, uint16_t max_length, uint16_t *out_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(client_hello, out, max_length, out_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_client_hello_get_legacy_record_version(+ int (*fn)(void *, uint8_t *),+ void *client_hello, uint8_t *version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(client_hello, version);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * File Descriptor & I/O+ * ============================================================================ */++int s2n_wrap_connection_set_fd(+ int (*fn)(void *, int),+ void *conn, int fd,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, fd);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_read_fd(+ int (*fn)(void *, int),+ void *conn, int fd,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, fd);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_write_fd(+ int (*fn)(void *, int),+ void *conn, int fd,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, fd);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_read_fd(+ int (*fn)(void *, int *),+ void *conn, int *fd,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, fd);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_write_fd(+ int (*fn)(void *, int *),+ void *conn, int *fd,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, fd);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_use_corked_io(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_recv_ctx(+ int (*fn)(void *, void *),+ void *conn, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_send_ctx(+ int (*fn)(void *, void *),+ void *conn, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_recv_cb(+ int (*fn)(void *, void *),+ void *conn, void *callback,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, callback);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_send_cb(+ int (*fn)(void *, void *),+ void *conn, void *callback,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, callback);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Connection Preferences+ * ============================================================================ */++int s2n_wrap_connection_prefer_throughput(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_prefer_low_latency(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_recv_buffering(+ int (*fn)(void *, int),+ void *conn, int enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, enabled);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_dynamic_buffers(+ int (*fn)(void *, int),+ void *conn, int enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, enabled);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_dynamic_record_threshold(+ int (*fn)(void *, uint32_t, uint16_t),+ void *conn, uint32_t resize_threshold, uint16_t timeout_threshold,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, resize_threshold, timeout_threshold);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Host Verification+ * ============================================================================ */++int s2n_wrap_connection_set_verify_host_callback(+ int (*fn)(void *, void *, void *),+ void *conn, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, callback, ctx);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Blinding & Security+ * ============================================================================ */++int s2n_wrap_connection_set_blinding(+ int (*fn)(void *, int),+ void *conn, int blinding,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, blinding);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Cipher & Protocol Configuration+ * ============================================================================ */++int s2n_wrap_connection_set_cipher_preferences(+ int (*fn)(void *, const char *),+ void *conn, const char *version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, version);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_request_key_update(+ int (*fn)(void *, int),+ void *conn, int peer_request,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, peer_request);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_append_protocol_preference(+ int (*fn)(void *, const uint8_t *, uint8_t),+ void *conn, const uint8_t *protocol, uint8_t protocol_len,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, protocol, protocol_len);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_protocol_preferences(+ int (*fn)(void *, const char **, int),+ void *conn, const char **protocols, int protocol_count,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, protocols, protocol_count);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Server Name (SNI)+ * ============================================================================ */++int s2n_wrap_set_server_name(+ int (*fn)(void *, const char *),+ void *conn, const char *server_name,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, server_name);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++const char *s2n_wrap_get_server_name(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ const char *result = fn(conn);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Application Protocol (ALPN)+ * ============================================================================ */++const char *s2n_wrap_get_application_protocol(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ const char *result = fn(conn);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * OCSP & Certificate Transparency+ * ============================================================================ */++const uint8_t *s2n_wrap_connection_get_ocsp_response(+ const uint8_t *(*fn)(void *, uint32_t *),+ void *conn, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ const uint8_t *result = fn(conn, length);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++const uint8_t *s2n_wrap_connection_get_sct_list(+ const uint8_t *(*fn)(void *, uint32_t *),+ void *conn, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ const uint8_t *result = fn(conn, length);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Handshake & TLS Operations+ * ============================================================================ */++int s2n_wrap_negotiate(+ int (*fn)(void *, int *),+ void *conn, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, blocked);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++ssize_t s2n_wrap_send(+ ssize_t (*fn)(void *, const void *, ssize_t, int *),+ void *conn, const void *buf, ssize_t size, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ ssize_t result = fn(conn, buf, size, blocked);+ int err = *(err_funcs->errno_location)();+ bool is_blocked = err_funcs->error_get_type(err) == 3; // S2N_ERR_T_BLOCKED==3+ if (result < 0)+ {+ S2N_FILL_ERROR_MAYBE(err_funcs, err_out, !is_blocked);+ }+ return result;+}++ssize_t s2n_wrap_recv(+ ssize_t (*fn)(void *, void *, ssize_t, int *),+ void *conn, void *buf, ssize_t size, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ ssize_t result = fn(conn, buf, size, blocked);+ int err = *(err_funcs->errno_location)();+ bool is_blocked = err_funcs->error_get_type(err) == 3; // S2N_ERR_T_BLOCKED==3+ if (result < 0)+ {+ S2N_FILL_ERROR_MAYBE(err_funcs, err_out, !is_blocked);+ }+ return result;+}++int s2n_wrap_connection_free_handshake(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_release_buffers(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_wipe(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_free(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_shutdown(+ int (*fn)(void *, int *),+ void *conn, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, blocked);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_shutdown_send(+ int (*fn)(void *, int *),+ void *conn, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, blocked);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Client Authentication+ * ============================================================================ */++int s2n_wrap_connection_get_client_auth_type(+ int (*fn)(void *, int *),+ void *conn, int *auth_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, auth_type);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_client_auth_type(+ int (*fn)(void *, int),+ void *conn, int auth_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, auth_type);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_client_cert_chain(+ int (*fn)(void *, const uint8_t **, uint32_t *),+ void *conn, const uint8_t **cert_chain, uint32_t *cert_chain_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, cert_chain, cert_chain_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_client_cert_used(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Session Management+ * ============================================================================ */++int s2n_wrap_connection_add_new_tickets_to_send(+ int (*fn)(void *, uint8_t),+ void *conn, uint8_t num_tickets,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, num_tickets);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_tickets_sent(+ int (*fn)(void *, uint16_t *),+ void *conn, uint16_t *tickets_sent,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, tickets_sent);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_server_keying_material_lifetime(+ int (*fn)(void *, uint32_t),+ void *conn, uint32_t lifetime,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, lifetime);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_session_ticket_get_data_len(+ int (*fn)(void *, size_t *),+ void *ticket, size_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(ticket, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_session_ticket_get_data(+ int (*fn)(void *, size_t, uint8_t *),+ void *ticket, size_t max_length, uint8_t *data,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(ticket, max_length, data);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_session_ticket_get_lifetime(+ int (*fn)(void *, uint32_t *),+ void *ticket, uint32_t *lifetime,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(ticket, lifetime);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_session(+ int (*fn)(void *, const uint8_t *, size_t),+ void *conn, const uint8_t *session, size_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, session, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_session(+ int (*fn)(void *, uint8_t *, size_t),+ void *conn, uint8_t *session, size_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, session, max_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_session_ticket_lifetime_hint(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_session_length(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_session_id_length(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_session_id(+ int (*fn)(void *, uint8_t *, size_t),+ void *conn, uint8_t *session_id, size_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, session_id, max_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_is_session_resumed(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Certificate Information+ * ============================================================================ */++int s2n_wrap_connection_is_ocsp_stapled(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_selected_signature_algorithm(+ int (*fn)(void *, int *),+ void *conn, int *sig_alg,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, sig_alg);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_selected_digest_algorithm(+ int (*fn)(void *, int *),+ void *conn, int *hash_alg,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, hash_alg);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_selected_client_cert_signature_algorithm(+ int (*fn)(void *, int *),+ void *conn, int *sig_alg,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, sig_alg);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_selected_client_cert_digest_algorithm(+ int (*fn)(void *, int *),+ void *conn, int *hash_alg,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, hash_alg);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++void *s2n_wrap_connection_get_selected_cert(+ void *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn(conn);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_chain_get_length(+ int (*fn)(void *, uint32_t *),+ void *chain, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(chain, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_chain_get_cert(+ int (*fn)(void *, void **, uint32_t),+ void *chain, void **cert, uint32_t index,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(chain, cert, index);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_get_der(+ int (*fn)(void *, const uint8_t **, uint32_t *),+ void *cert, const uint8_t **der, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(cert, der, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_peer_cert_chain(+ int (*fn)(void *, void *),+ void *conn, void *cert_chain,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, cert_chain);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_get_x509_extension_value_length(+ int (*fn)(void *, const uint8_t *, uint32_t *),+ void *cert, const uint8_t *oid, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(cert, oid, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_get_x509_extension_value(+ int (*fn)(void *, const uint8_t *, uint8_t *, uint32_t *, int *),+ void *cert, const uint8_t *oid, uint8_t *value, uint32_t *length, int *critical,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(cert, oid, value, length, critical);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_get_utf8_string_from_extension_data_length(+ int (*fn)(const uint8_t *, uint32_t, uint32_t *),+ const uint8_t *data, uint32_t data_length, uint32_t *utf8_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(data, data_length, utf8_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_cert_get_utf8_string_from_extension_data(+ int (*fn)(const uint8_t *, uint32_t, uint8_t *, uint32_t *),+ const uint8_t *data, uint32_t data_length, uint8_t *utf8, uint32_t *utf8_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(data, data_length, utf8, utf8_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Pre-Shared Keys (PSK)+ * ============================================================================ */++void *s2n_wrap_external_psk_new(+ void *(*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn();+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_psk_free(+ int (*fn)(void **),+ void **psk,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_psk_set_identity(+ int (*fn)(void *, const uint8_t *, uint16_t),+ void *psk, const uint8_t *identity, uint16_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk, identity, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_psk_set_secret(+ int (*fn)(void *, const uint8_t *, uint16_t),+ void *psk, const uint8_t *secret, uint16_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk, secret, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_psk_set_hmac(+ int (*fn)(void *, int),+ void *psk, int hmac,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk, hmac);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_append_psk(+ int (*fn)(void *, void *),+ void *conn, void *psk,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, psk);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_psk_mode(+ int (*fn)(void *, int),+ void *conn, int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, mode);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_negotiated_psk_identity_length(+ int (*fn)(void *, uint16_t *),+ void *conn, uint16_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_negotiated_psk_identity(+ int (*fn)(void *, uint8_t *, uint16_t),+ void *conn, uint8_t *identity, uint16_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, identity, max_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++void *s2n_wrap_offered_psk_new(+ void *(*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ void *result = fn();+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_offered_psk_free(+ int (*fn)(void **),+ void **psk,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_offered_psk_get_identity(+ int (*fn)(void *, uint8_t **, uint16_t *),+ void *psk, uint8_t **identity, uint16_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk, identity, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_offered_psk_list_next(+ int (*fn)(void *, void *),+ void *psk_list, void *psk,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk_list, psk);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_offered_psk_list_reread(+ int (*fn)(void *),+ void *psk_list,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk_list);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_offered_psk_list_choose_psk(+ int (*fn)(void *, void *),+ void *psk_list, void *psk,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk_list, psk);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_psk_configure_early_data(+ int (*fn)(void *, uint32_t, uint8_t, uint8_t),+ void *psk, uint32_t max_early_data_size, uint8_t cipher_suite_first_byte, uint8_t cipher_suite_second_byte,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk, max_early_data_size, cipher_suite_first_byte, cipher_suite_second_byte);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_psk_set_application_protocol(+ int (*fn)(void *, const uint8_t *, uint8_t),+ void *psk, const uint8_t *protocol, uint8_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk, protocol, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_psk_set_early_data_context(+ int (*fn)(void *, const uint8_t *, uint16_t),+ void *psk, const uint8_t *context, uint16_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(psk, context, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Protocol Version Information+ * ============================================================================ */++int s2n_wrap_connection_get_client_protocol_version(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_server_protocol_version(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_actual_protocol_version(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_client_hello_version(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Cipher & Security Information+ * ============================================================================ */++const char *s2n_wrap_connection_get_cipher(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ const char *result = fn(conn);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_certificate_match(+ int (*fn)(void *, int *),+ void *conn, int *cert_match,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, cert_match);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_master_secret(+ int (*fn)(void *, uint8_t *, size_t),+ void *conn, uint8_t *secret, size_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, secret, max_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_tls_exporter(+ int (*fn)(void *, const uint8_t *, uint32_t, const uint8_t *, uint32_t, uint8_t *, uint32_t),+ void *conn, const uint8_t *label, uint32_t label_length,+ const uint8_t *context, uint32_t context_length,+ uint8_t *output, uint32_t output_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, label, label_length, context, context_length, output, output_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_cipher_iana_value(+ int (*fn)(void *, uint8_t *, uint8_t *),+ void *conn, uint8_t *first, uint8_t *second,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, first, second);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_is_valid_for_cipher_preferences(+ int (*fn)(void *, const char *),+ void *conn, const char *version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, version);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++const char *s2n_wrap_connection_get_curve(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ const char *result = fn(conn);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++const char *s2n_wrap_connection_get_kem_name(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ const char *result = fn(conn);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++const char *s2n_wrap_connection_get_kem_group_name(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ const char *result = fn(conn);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_key_exchange_group(+ int (*fn)(void *, const char **),+ void *conn, const char **group_name,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, group_name);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_alert(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++const char *s2n_wrap_connection_get_handshake_type_name(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ const char *result = fn(conn);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++const char *s2n_wrap_connection_get_last_message_name(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ const char *result = fn(conn);+ if (result == NULL)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Async Private Key Operations+ * ============================================================================ */++int s2n_wrap_async_pkey_op_perform(+ int (*fn)(void *, void *),+ void *op, void *key,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(op, key);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_async_pkey_op_apply(+ int (*fn)(void *, void *),+ void *op, void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(op, conn);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_async_pkey_op_free(+ int (*fn)(void *),+ void *op,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(op);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_async_pkey_op_get_op_type(+ int (*fn)(void *, int *),+ void *op, int *op_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(op, op_type);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_async_pkey_op_get_input_size(+ int (*fn)(void *, uint32_t *),+ void *op, uint32_t *size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(op, size);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_async_pkey_op_get_input(+ int (*fn)(void *, uint8_t *, uint32_t),+ void *op, uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(op, data, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_async_pkey_op_set_output(+ int (*fn)(void *, const uint8_t *, uint32_t),+ void *op, const uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(op, data, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Early Data+ * ============================================================================ */++int s2n_wrap_connection_set_server_max_early_data_size(+ int (*fn)(void *, uint32_t),+ void *conn, uint32_t size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, size);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_set_server_early_data_context(+ int (*fn)(void *, const uint8_t *, uint16_t),+ void *conn, const uint8_t *context, uint16_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, context, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_early_data_status(+ int (*fn)(void *, int *),+ void *conn, int *status,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, status);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_remaining_early_data_size(+ int (*fn)(void *, uint32_t *),+ void *conn, uint32_t *size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, size);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_get_max_early_data_size(+ int (*fn)(void *, uint32_t *),+ void *conn, uint32_t *size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, size);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_send_early_data(+ int (*fn)(void *, const uint8_t *, ssize_t, ssize_t *, int *),+ void *conn, const uint8_t *data, ssize_t data_len, ssize_t *written, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, data, data_len, written, blocked);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_recv_early_data(+ int (*fn)(void *, uint8_t *, ssize_t, ssize_t *, int *),+ void *conn, uint8_t *data, ssize_t max_data_len, ssize_t *read, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, data, max_data_len, read, blocked);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_offered_early_data_get_context_length(+ int (*fn)(void *, uint16_t *),+ void *early_data, uint16_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(early_data, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_offered_early_data_get_context(+ int (*fn)(void *, uint8_t *, uint16_t),+ void *early_data, uint8_t *context, uint16_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(early_data, context, max_length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_offered_early_data_reject(+ int (*fn)(void *),+ void *early_data,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(early_data);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_offered_early_data_accept(+ int (*fn)(void *),+ void *early_data,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(early_data);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++/* ============================================================================+ * Connection Serialization+ * ============================================================================ */++int s2n_wrap_connection_serialization_length(+ int (*fn)(void *, uint32_t *),+ void *conn, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_serialize(+ int (*fn)(void *, uint8_t *, uint32_t),+ void *conn, uint8_t *buffer, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, buffer, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}++int s2n_wrap_connection_deserialize(+ int (*fn)(void *, const uint8_t *, uint32_t),+ void *conn, const uint8_t *buffer, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out)+{+ int result = fn(conn, buffer, length);+ if (result < 0)+ {+ S2N_FILL_ERROR(err_funcs, err_out);+ }+ return result;+}
+ cbits/s2n_wrapper.h view
@@ -0,0 +1,1294 @@+/*+ * s2n_wrapper.h - C wrappers for s2n-tls functions+ *+ * These wrappers capture error information from thread-local storage+ * immediately after s2n function calls, making error handling safe+ * for Haskell FFI where TLS can be unreliable.+ */++#ifndef S2N_WRAPPER_H+#define S2N_WRAPPER_H++#include <stddef.h>+#include <stdint.h>+#include <stdbool.h>+#include <string.h>+#include <sys/types.h>++/* Size of the owned debug string buffer in S2nErrorInfo */+#define S2N_ERROR_DEBUG_STRING_SIZE 256++/*+ * Error Functions Struct+ * Holds pointers to s2n error functions, loaded first during initialization.+ * These are used by all wrappers to capture error information.+ */+typedef struct+{+ int *(*errno_location)(void);+ const char *(*strerror_debug)(int error, const char *lang);+ int (*error_get_type)(int error);+} S2nErrorFuncs;++/*+ * Error Info Output Struct+ * Populated by wrappers on failure with full error information.+ * Uses an owned buffer for the debug string since s2n's string pointers+ * are ephemeral and may become invalid.+ */+typedef struct+{+ int error_code;+ char debug_string[S2N_ERROR_DEBUG_STRING_SIZE];+} S2nErrorInfo;++/*+ * Helper macro to populate error info on failure.+ * Copies the debug string into the owned buffer.+ */+#define S2N_FILL_ERROR_MAYBE(err_funcs, err_out, do_dbg) \+ do \+ { \+ (err_out)->error_code = *(err_funcs)->errno_location(); \+ const char *_dbg = (err_funcs)->strerror_debug((err_out)->error_code, "EN"); \+ if (_dbg && (do_dbg)) \+ { \+ strncpy((err_out)->debug_string, _dbg, S2N_ERROR_DEBUG_STRING_SIZE - 1); \+ (err_out)->debug_string[S2N_ERROR_DEBUG_STRING_SIZE - 1] = '\0'; \+ } \+ else \+ { \+ (err_out)->debug_string[0] = '\0'; \+ } \+ } while (0)++/*+ * Helper macro to populate error info on failure.+ * Copies the debug string into the owned buffer.+ */+#define S2N_FILL_ERROR(err_funcs, err_out) S2N_FILL_ERROR_MAYBE(err_funcs, err_out, true)++/* ============================================================================+ * Wrapper Function Declarations+ * ============================================================================+ * Each wrapper takes:+ * - Function pointer to the underlying s2n function+ * - Same arguments as the original function+ * - Pointer to S2nErrorFuncs struct+ * - Pointer to S2nErrorInfo output struct+ * Returns the same type as the underlying function.+ */++/* --- Initialization & Cleanup --- */+int s2n_wrap_init(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cleanup(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cleanup_final(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_crypto_disable_init(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_disable_atexit(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* s2n_get_openssl_version returns long, no error - no wrapper needed */+/* s2n_get_fips_mode takes output param */+int s2n_wrap_get_fips_mode(+ int (*fn)(int *),+ int *fips_mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Stack Traces --- */+/* s2n_stack_traces_enabled returns bool, no wrapper needed */++int s2n_wrap_stack_traces_enabled_set(+ int (*fn)(int),+ int enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_calculate_stacktrace(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_free_stacktrace(+ int (*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_get_stacktrace(+ int (*fn)(void *),+ void *stacktrace,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Config Management --- */+void *s2n_wrap_config_new(+ void *(*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++void *s2n_wrap_config_new_minimal(+ void *(*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_free(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_free_dhparams(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_free_cert_chain_and_key(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_wall_clock(+ int (*fn)(void *, void *, void *),+ void *config, void *clock_fn, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_monotonic_clock(+ int (*fn)(void *, void *, void *),+ void *config, void *clock_fn, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Cache Callbacks --- */+int s2n_wrap_config_set_cache_store_callback(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_cache_retrieve_callback(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_cache_delete_callback(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Memory & Random Callbacks --- */+int s2n_wrap_mem_set_callbacks(+ int (*fn)(void *, void *, void *, void *),+ void *init_cb, void *cleanup_cb, void *malloc_cb, void *free_cb,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_rand_set_callbacks(+ int (*fn)(void *, void *, void *, void *),+ void *init_cb, void *cleanup_cb, void *seed_cb, void *mix_cb,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Certificate Chain Management --- */+void *s2n_wrap_cert_chain_and_key_new(+ void *(*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_chain_and_key_load_pem(+ int (*fn)(void *, const char *, const char *),+ void *chain_and_key, const char *chain_pem, const char *private_key_pem,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_chain_and_key_load_pem_bytes(+ int (*fn)(void *, const uint8_t *, uint32_t, const uint8_t *, uint32_t),+ void *chain_and_key, const uint8_t *chain_pem, uint32_t chain_pem_len,+ const uint8_t *private_key_pem, uint32_t private_key_pem_len,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_chain_and_key_load_public_pem_bytes(+ int (*fn)(void *, const uint8_t *, uint32_t),+ void *chain_and_key, const uint8_t *chain_pem, uint32_t chain_pem_len,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_chain_and_key_free(+ int (*fn)(void *),+ void *chain_and_key,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_chain_and_key_set_ctx(+ int (*fn)(void *, void *),+ void *chain_and_key, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++void *s2n_wrap_cert_chain_and_key_get_ctx(+ void *(*fn)(void *),+ void *chain_and_key,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++void *s2n_wrap_cert_chain_and_key_get_private_key(+ void *(*fn)(void *),+ void *chain_and_key,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_chain_and_key_set_ocsp_data(+ int (*fn)(void *, const uint8_t *, uint32_t),+ void *chain_and_key, const uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_chain_and_key_set_sct_list(+ int (*fn)(void *, const uint8_t *, uint32_t),+ void *chain_and_key, const uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_cert_tiebreak_callback(+ int (*fn)(void *, void *),+ void *config, void *callback,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_add_cert_chain_and_key(+ int (*fn)(void *, const char *, const char *),+ void *config, const char *chain_pem, const char *private_key_pem,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_add_cert_chain_and_key_to_store(+ int (*fn)(void *, void *),+ void *config, void *chain_and_key,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_cert_chain_and_key_defaults(+ int (*fn)(void *, void **, uint32_t),+ void *config, void **chain_and_key_array, uint32_t count,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Trust Store --- */+int s2n_wrap_config_set_verification_ca_location(+ int (*fn)(void *, const char *, const char *),+ void *config, const char *ca_pem_filename, const char *ca_dir,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_add_pem_to_trust_store(+ int (*fn)(void *, const char *),+ void *config, const char *pem,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_wipe_trust_store(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_load_system_certs(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_cert_authorities_from_trust_store(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Verification & Validation --- */+int s2n_wrap_config_set_verify_after_sign(+ int (*fn)(void *, int),+ void *config, int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_check_stapled_ocsp_response(+ int (*fn)(void *, uint8_t),+ void *config, uint8_t check,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_disable_x509_time_verification(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_disable_x509_verification(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_max_cert_chain_depth(+ int (*fn)(void *, uint16_t),+ void *config, uint16_t depth,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_verify_host_callback(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- DH Parameters --- */+int s2n_wrap_config_add_dhparams(+ int (*fn)(void *, const char *),+ void *config, const char *dhparams_pem,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Security Policies & Preferences --- */+int s2n_wrap_config_set_cipher_preferences(+ int (*fn)(void *, const char *),+ void *config, const char *version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_append_protocol_preference(+ int (*fn)(void *, const uint8_t *, uint8_t),+ void *config, const uint8_t *protocol, uint8_t protocol_len,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_protocol_preferences(+ int (*fn)(void *, const char **, int),+ void *config, const char **protocols, int protocol_count,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_status_request_type(+ int (*fn)(void *, int),+ void *config, int type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_ct_support_level(+ int (*fn)(void *, int),+ void *config, int level,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_alert_behavior(+ int (*fn)(void *, int),+ void *config, int behavior,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Extension Data --- */+int s2n_wrap_config_set_extension_data(+ int (*fn)(void *, int, const uint8_t *, uint32_t),+ void *config, int extension_type, const uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_send_max_fragment_length(+ int (*fn)(void *, int),+ void *config, int mfl_code,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_accept_max_fragment_length(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Session & Ticket Configuration --- */+int s2n_wrap_config_set_session_state_lifetime(+ int (*fn)(void *, uint64_t),+ void *config, uint64_t lifetime,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_session_tickets_onoff(+ int (*fn)(void *, uint8_t),+ void *config, uint8_t enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_session_cache_onoff(+ int (*fn)(void *, uint8_t),+ void *config, uint8_t enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_ticket_encrypt_decrypt_key_lifetime(+ int (*fn)(void *, uint64_t),+ void *config, uint64_t lifetime,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_ticket_decrypt_key_lifetime(+ int (*fn)(void *, uint64_t),+ void *config, uint64_t lifetime,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_add_ticket_crypto_key(+ int (*fn)(void *, const uint8_t *, uint32_t, const uint8_t *, uint32_t, uint64_t),+ void *config, const uint8_t *name, uint32_t name_len,+ const uint8_t *key, uint32_t key_len, uint64_t intro_time_in_seconds_from_epoch,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_require_ticket_forward_secrecy(+ int (*fn)(void *, int),+ void *config, int enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Buffer & I/O Configuration --- */+int s2n_wrap_config_set_send_buffer_size(+ int (*fn)(void *, uint32_t),+ void *config, uint32_t size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_recv_multi_record(+ int (*fn)(void *, int),+ void *config, int enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Miscellaneous Config --- */+int s2n_wrap_config_set_ctx(+ int (*fn)(void *, void *),+ void *config, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_get_ctx(+ int (*fn)(void *, void **),+ void *config, void **ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_client_hello_cb(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_client_hello_cb_mode(+ int (*fn)(void *, int),+ void *config, int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_max_blinding_delay(+ int (*fn)(void *, uint32_t),+ void *config, uint32_t max_delay,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_get_client_auth_type(+ int (*fn)(void *, int *),+ void *config, int *auth_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_client_auth_type(+ int (*fn)(void *, int),+ void *config, int auth_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_initial_ticket_count(+ int (*fn)(void *, uint8_t),+ void *config, uint8_t count,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_psk_mode(+ int (*fn)(void *, int),+ void *config, int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_psk_selection_callback(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_async_pkey_callback(+ int (*fn)(void *, void *),+ void *config, void *callback,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_async_pkey_validation_mode(+ int (*fn)(void *, int),+ void *config, int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_session_ticket_cb(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_key_log_cb(+ int (*fn)(void *, void *, void *),+ void *config, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_enable_cert_req_dss_legacy_compat(+ int (*fn)(void *),+ void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_server_max_early_data_size(+ int (*fn)(void *, uint32_t),+ void *config, uint32_t size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_early_data_cb(+ int (*fn)(void *, void *),+ void *config, void *callback,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_get_supported_groups(+ int (*fn)(void *, uint16_t *, uint16_t, uint16_t *),+ void *config, uint16_t *groups, uint16_t groups_count, uint16_t *groups_count_out,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_config_set_serialization_version(+ int (*fn)(void *, int),+ void *config, int version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Connection Creation & Management --- */+void *s2n_wrap_connection_new(+ void *(*fn)(int),+ int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_config(+ int (*fn)(void *, void *),+ void *conn, void *config,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_ctx(+ int (*fn)(void *, void *),+ void *conn, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++void *s2n_wrap_connection_get_ctx(+ void *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_cb_done(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_server_name_extension_used(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Client Hello Access --- */+void *s2n_wrap_connection_get_client_hello(+ void *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++void *s2n_wrap_client_hello_parse_message(+ void *(*fn)(const uint8_t *, uint32_t),+ const uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_free(+ int (*fn)(void **),+ void **client_hello,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++ssize_t s2n_wrap_client_hello_get_raw_message_length(+ ssize_t (*fn)(void *),+ void *client_hello,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++ssize_t s2n_wrap_client_hello_get_raw_message(+ ssize_t (*fn)(void *, uint8_t *, uint32_t),+ void *client_hello, uint8_t *out, uint32_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++ssize_t s2n_wrap_client_hello_get_cipher_suites_length(+ ssize_t (*fn)(void *),+ void *client_hello,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++ssize_t s2n_wrap_client_hello_get_cipher_suites(+ ssize_t (*fn)(void *, uint8_t *, uint32_t),+ void *client_hello, uint8_t *out, uint32_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++ssize_t s2n_wrap_client_hello_get_extensions_length(+ ssize_t (*fn)(void *),+ void *client_hello,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++ssize_t s2n_wrap_client_hello_get_extensions(+ ssize_t (*fn)(void *, uint8_t *, uint32_t),+ void *client_hello, uint8_t *out, uint32_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++ssize_t s2n_wrap_client_hello_get_extension_length(+ ssize_t (*fn)(void *, int),+ void *client_hello, int extension_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++ssize_t s2n_wrap_client_hello_get_extension_by_id(+ ssize_t (*fn)(void *, int, uint8_t *, uint32_t),+ void *client_hello, int extension_type, uint8_t *out, uint32_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_has_extension(+ int (*fn)(void *, uint16_t, int *),+ void *client_hello, uint16_t extension_iana, int *exists,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_get_session_id_length(+ int (*fn)(void *, uint32_t *),+ void *client_hello, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_get_session_id(+ int (*fn)(void *, uint8_t *, uint32_t *, uint32_t),+ void *client_hello, uint8_t *out, uint32_t *out_length, uint32_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_get_compression_methods_length(+ int (*fn)(void *, uint32_t *),+ void *client_hello, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_get_compression_methods(+ int (*fn)(void *, uint8_t *, uint32_t, uint32_t *),+ void *client_hello, uint8_t *out, uint32_t max_length, uint32_t *out_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_get_legacy_protocol_version(+ int (*fn)(void *, uint8_t *),+ void *client_hello, uint8_t *version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_get_supported_groups(+ int (*fn)(void *, uint16_t *, uint16_t, uint16_t *),+ void *client_hello, uint16_t *groups, uint16_t groups_count, uint16_t *groups_count_out,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_get_server_name_length(+ int (*fn)(void *, uint16_t *),+ void *client_hello, uint16_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_get_server_name(+ int (*fn)(void *, uint8_t *, uint16_t, uint16_t *),+ void *client_hello, uint8_t *out, uint16_t max_length, uint16_t *out_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_client_hello_get_legacy_record_version(+ int (*fn)(void *, uint8_t *),+ void *client_hello, uint8_t *version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- File Descriptor & I/O --- */+int s2n_wrap_connection_set_fd(+ int (*fn)(void *, int),+ void *conn, int fd,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_read_fd(+ int (*fn)(void *, int),+ void *conn, int fd,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_write_fd(+ int (*fn)(void *, int),+ void *conn, int fd,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_read_fd(+ int (*fn)(void *, int *),+ void *conn, int *fd,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_write_fd(+ int (*fn)(void *, int *),+ void *conn, int *fd,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_use_corked_io(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_recv_ctx(+ int (*fn)(void *, void *),+ void *conn, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_send_ctx(+ int (*fn)(void *, void *),+ void *conn, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_recv_cb(+ int (*fn)(void *, void *),+ void *conn, void *callback,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_send_cb(+ int (*fn)(void *, void *),+ void *conn, void *callback,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Connection Preferences --- */+int s2n_wrap_connection_prefer_throughput(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_prefer_low_latency(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_recv_buffering(+ int (*fn)(void *, int),+ void *conn, int enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* s2n_peek_buffered returns uint32, no error - no wrapper needed */++int s2n_wrap_connection_set_dynamic_buffers(+ int (*fn)(void *, int),+ void *conn, int enabled,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_dynamic_record_threshold(+ int (*fn)(void *, uint32_t, uint16_t),+ void *conn, uint32_t resize_threshold, uint16_t timeout_threshold,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Host Verification --- */+int s2n_wrap_connection_set_verify_host_callback(+ int (*fn)(void *, void *, void *),+ void *conn, void *callback, void *ctx,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Blinding & Security --- */+int s2n_wrap_connection_set_blinding(+ int (*fn)(void *, int),+ void *conn, int blinding,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* s2n_connection_get_delay returns uint64, no error - no wrapper needed */++/* --- Cipher & Protocol Configuration --- */+int s2n_wrap_connection_set_cipher_preferences(+ int (*fn)(void *, const char *),+ void *conn, const char *version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_request_key_update(+ int (*fn)(void *, int),+ void *conn, int peer_request,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_append_protocol_preference(+ int (*fn)(void *, const uint8_t *, uint8_t),+ void *conn, const uint8_t *protocol, uint8_t protocol_len,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_protocol_preferences(+ int (*fn)(void *, const char **, int),+ void *conn, const char **protocols, int protocol_count,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Server Name (SNI) --- */+int s2n_wrap_set_server_name(+ int (*fn)(void *, const char *),+ void *conn, const char *server_name,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++const char *s2n_wrap_get_server_name(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Application Protocol (ALPN) --- */+const char *s2n_wrap_get_application_protocol(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- OCSP & Certificate Transparency --- */+const uint8_t *s2n_wrap_connection_get_ocsp_response(+ const uint8_t *(*fn)(void *, uint32_t *),+ void *conn, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++const uint8_t *s2n_wrap_connection_get_sct_list(+ const uint8_t *(*fn)(void *, uint32_t *),+ void *conn, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Handshake & TLS Operations --- */+int s2n_wrap_negotiate(+ int (*fn)(void *, int *),+ void *conn, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++ssize_t s2n_wrap_send(+ ssize_t (*fn)(void *, const void *, ssize_t, int *),+ void *conn, const void *buf, ssize_t size, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++ssize_t s2n_wrap_recv(+ ssize_t (*fn)(void *, void *, ssize_t, int *),+ void *conn, void *buf, ssize_t size, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* s2n_peek returns uint32, no error - no wrapper needed */++int s2n_wrap_connection_free_handshake(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_release_buffers(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_wipe(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_free(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_shutdown(+ int (*fn)(void *, int *),+ void *conn, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_shutdown_send(+ int (*fn)(void *, int *),+ void *conn, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Client Authentication --- */+int s2n_wrap_connection_get_client_auth_type(+ int (*fn)(void *, int *),+ void *conn, int *auth_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_client_auth_type(+ int (*fn)(void *, int),+ void *conn, int auth_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_client_cert_chain(+ int (*fn)(void *, const uint8_t **, uint32_t *),+ void *conn, const uint8_t **cert_chain, uint32_t *cert_chain_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_client_cert_used(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Session Management --- */+int s2n_wrap_connection_add_new_tickets_to_send(+ int (*fn)(void *, uint8_t),+ void *conn, uint8_t num_tickets,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_tickets_sent(+ int (*fn)(void *, uint16_t *),+ void *conn, uint16_t *tickets_sent,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_server_keying_material_lifetime(+ int (*fn)(void *, uint32_t),+ void *conn, uint32_t lifetime,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_session_ticket_get_data_len(+ int (*fn)(void *, size_t *),+ void *ticket, size_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_session_ticket_get_data(+ int (*fn)(void *, size_t, uint8_t *),+ void *ticket, size_t max_length, uint8_t *data,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_session_ticket_get_lifetime(+ int (*fn)(void *, uint32_t *),+ void *ticket, uint32_t *lifetime,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_session(+ int (*fn)(void *, const uint8_t *, size_t),+ void *conn, const uint8_t *session, size_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_session(+ int (*fn)(void *, uint8_t *, size_t),+ void *conn, uint8_t *session, size_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_session_ticket_lifetime_hint(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_session_length(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_session_id_length(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_session_id(+ int (*fn)(void *, uint8_t *, size_t),+ void *conn, uint8_t *session_id, size_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_is_session_resumed(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Certificate Information --- */+int s2n_wrap_connection_is_ocsp_stapled(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_selected_signature_algorithm(+ int (*fn)(void *, int *),+ void *conn, int *sig_alg,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_selected_digest_algorithm(+ int (*fn)(void *, int *),+ void *conn, int *hash_alg,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_selected_client_cert_signature_algorithm(+ int (*fn)(void *, int *),+ void *conn, int *sig_alg,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_selected_client_cert_digest_algorithm(+ int (*fn)(void *, int *),+ void *conn, int *hash_alg,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++void *s2n_wrap_connection_get_selected_cert(+ void *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_chain_get_length(+ int (*fn)(void *, uint32_t *),+ void *chain, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_chain_get_cert(+ int (*fn)(void *, void **, uint32_t),+ void *chain, void **cert, uint32_t index,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_get_der(+ int (*fn)(void *, const uint8_t **, uint32_t *),+ void *cert, const uint8_t **der, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_peer_cert_chain(+ int (*fn)(void *, void *),+ void *conn, void *cert_chain,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_get_x509_extension_value_length(+ int (*fn)(void *, const uint8_t *, uint32_t *),+ void *cert, const uint8_t *oid, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_get_x509_extension_value(+ int (*fn)(void *, const uint8_t *, uint8_t *, uint32_t *, int *),+ void *cert, const uint8_t *oid, uint8_t *value, uint32_t *length, int *critical,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_get_utf8_string_from_extension_data_length(+ int (*fn)(const uint8_t *, uint32_t, uint32_t *),+ const uint8_t *data, uint32_t data_length, uint32_t *utf8_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_cert_get_utf8_string_from_extension_data(+ int (*fn)(const uint8_t *, uint32_t, uint8_t *, uint32_t *),+ const uint8_t *data, uint32_t data_length, uint8_t *utf8, uint32_t *utf8_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Pre-Shared Keys (PSK) --- */+void *s2n_wrap_external_psk_new(+ void *(*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_psk_free(+ int (*fn)(void **),+ void **psk,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_psk_set_identity(+ int (*fn)(void *, const uint8_t *, uint16_t),+ void *psk, const uint8_t *identity, uint16_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_psk_set_secret(+ int (*fn)(void *, const uint8_t *, uint16_t),+ void *psk, const uint8_t *secret, uint16_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_psk_set_hmac(+ int (*fn)(void *, int),+ void *psk, int hmac,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_append_psk(+ int (*fn)(void *, void *),+ void *conn, void *psk,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_psk_mode(+ int (*fn)(void *, int),+ void *conn, int mode,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_negotiated_psk_identity_length(+ int (*fn)(void *, uint16_t *),+ void *conn, uint16_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_negotiated_psk_identity(+ int (*fn)(void *, uint8_t *, uint16_t),+ void *conn, uint8_t *identity, uint16_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++void *s2n_wrap_offered_psk_new(+ void *(*fn)(void),+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_offered_psk_free(+ int (*fn)(void **),+ void **psk,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_offered_psk_get_identity(+ int (*fn)(void *, uint8_t **, uint16_t *),+ void *psk, uint8_t **identity, uint16_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* s2n_offered_psk_list_has_next returns bool, no error - no wrapper needed */++int s2n_wrap_offered_psk_list_next(+ int (*fn)(void *, void *),+ void *psk_list, void *psk,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_offered_psk_list_reread(+ int (*fn)(void *),+ void *psk_list,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_offered_psk_list_choose_psk(+ int (*fn)(void *, void *),+ void *psk_list, void *psk,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_psk_configure_early_data(+ int (*fn)(void *, uint32_t, uint8_t, uint8_t),+ void *psk, uint32_t max_early_data_size, uint8_t cipher_suite_first_byte, uint8_t cipher_suite_second_byte,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_psk_set_application_protocol(+ int (*fn)(void *, const uint8_t *, uint8_t),+ void *psk, const uint8_t *protocol, uint8_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_psk_set_early_data_context(+ int (*fn)(void *, const uint8_t *, uint16_t),+ void *psk, const uint8_t *context, uint16_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Connection Statistics --- */+/* s2n_connection_get_wire_bytes_in returns uint64, no error - no wrapper needed */+/* s2n_connection_get_wire_bytes_out returns uint64, no error - no wrapper needed */++/* --- Protocol Version Information --- */+int s2n_wrap_connection_get_client_protocol_version(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_server_protocol_version(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_actual_protocol_version(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_client_hello_version(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Cipher & Security Information --- */+const char *s2n_wrap_connection_get_cipher(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_certificate_match(+ int (*fn)(void *, int *),+ void *conn, int *cert_match,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_master_secret(+ int (*fn)(void *, uint8_t *, size_t),+ void *conn, uint8_t *secret, size_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_tls_exporter(+ int (*fn)(void *, const uint8_t *, uint32_t, const uint8_t *, uint32_t, uint8_t *, uint32_t),+ void *conn, const uint8_t *label, uint32_t label_length,+ const uint8_t *context, uint32_t context_length,+ uint8_t *output, uint32_t output_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_cipher_iana_value(+ int (*fn)(void *, uint8_t *, uint8_t *),+ void *conn, uint8_t *first, uint8_t *second,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_is_valid_for_cipher_preferences(+ int (*fn)(void *, const char *),+ void *conn, const char *version,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++const char *s2n_wrap_connection_get_curve(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++const char *s2n_wrap_connection_get_kem_name(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++const char *s2n_wrap_connection_get_kem_group_name(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_key_exchange_group(+ int (*fn)(void *, const char **),+ void *conn, const char **group_name,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_alert(+ int (*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++const char *s2n_wrap_connection_get_handshake_type_name(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++const char *s2n_wrap_connection_get_last_message_name(+ const char *(*fn)(void *),+ void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Async Private Key Operations --- */+int s2n_wrap_async_pkey_op_perform(+ int (*fn)(void *, void *),+ void *op, void *key,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_async_pkey_op_apply(+ int (*fn)(void *, void *),+ void *op, void *conn,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_async_pkey_op_free(+ int (*fn)(void *),+ void *op,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_async_pkey_op_get_op_type(+ int (*fn)(void *, int *),+ void *op, int *op_type,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_async_pkey_op_get_input_size(+ int (*fn)(void *, uint32_t *),+ void *op, uint32_t *size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_async_pkey_op_get_input(+ int (*fn)(void *, uint8_t *, uint32_t),+ void *op, uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_async_pkey_op_set_output(+ int (*fn)(void *, const uint8_t *, uint32_t),+ void *op, const uint8_t *data, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Early Data --- */+int s2n_wrap_connection_set_server_max_early_data_size(+ int (*fn)(void *, uint32_t),+ void *conn, uint32_t size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_set_server_early_data_context(+ int (*fn)(void *, const uint8_t *, uint16_t),+ void *conn, const uint8_t *context, uint16_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_early_data_status(+ int (*fn)(void *, int *),+ void *conn, int *status,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_remaining_early_data_size(+ int (*fn)(void *, uint32_t *),+ void *conn, uint32_t *size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_get_max_early_data_size(+ int (*fn)(void *, uint32_t *),+ void *conn, uint32_t *size,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_send_early_data(+ int (*fn)(void *, const uint8_t *, ssize_t, ssize_t *, int *),+ void *conn, const uint8_t *data, ssize_t data_len, ssize_t *written, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_recv_early_data(+ int (*fn)(void *, uint8_t *, ssize_t, ssize_t *, int *),+ void *conn, uint8_t *data, ssize_t max_data_len, ssize_t *read, int *blocked,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_offered_early_data_get_context_length(+ int (*fn)(void *, uint16_t *),+ void *early_data, uint16_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_offered_early_data_get_context(+ int (*fn)(void *, uint8_t *, uint16_t),+ void *early_data, uint8_t *context, uint16_t max_length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_offered_early_data_reject(+ int (*fn)(void *),+ void *early_data,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_offered_early_data_accept(+ int (*fn)(void *),+ void *early_data,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++/* --- Connection Serialization --- */+int s2n_wrap_connection_serialization_length(+ int (*fn)(void *, uint32_t *),+ void *conn, uint32_t *length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_serialize(+ int (*fn)(void *, uint8_t *, uint32_t),+ void *conn, uint8_t *buffer, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++int s2n_wrap_connection_deserialize(+ int (*fn)(void *, const uint8_t *, uint32_t),+ void *conn, const uint8_t *buffer, uint32_t length,+ const S2nErrorFuncs *err_funcs, S2nErrorInfo *err_out);++#endif /* S2N_WRAPPER_H */
+ s2n-tls-ffi.cabal view
@@ -0,0 +1,60 @@+cabal-version: 3.0+name: s2n-tls-ffi+version: 0.1.0.0+synopsis: Low-level FFI bindings to the s2n-tls library+description:+ Low-level FFI bindings to the s2n-tls library.++license: Apache-2.0+license-file: LICENSE+author: Daniel Goertzen+maintainer: daniel.goertzen@gmail.com+copyright: 2026 Daniel Goertzen+category: Cryptography, FFI, Network+build-type: Simple+tested-with: GHC == 9.8.2+extra-doc-files:+ CHANGELOG.md+ README.md+extra-source-files: cbits/s2n_wrapper.h+homepage: https://github.com/goertzenator/s2n-tls-ffi+bug-reports: https://github.com/goertzenator/s2n-tls-ffi/issues++source-repository head+ type: git+ location: https://github.com/goertzenator/s2n-tls-ffi.git++source-repository this+ type: git+ location: https://github.com/goertzenator/s2n-tls-ffi.git+ tag: v0.1.0.0++library+ exposed-modules:+ S2nTls.Ffi+ S2nTls.Ffi.Types++ build-depends:+ base >= 4.14 && < 5+ , unix >= 2.7 && < 2.9++ hs-source-dirs: src+ default-language: GHC2021+ ghc-options: -Wall -haddock++ -- C wrapper for capturing error info from thread-local storage+ c-sources: cbits/s2n_wrapper.c+ include-dirs: cbits++ -- Required for Linked mode (symbols loaded via dlopen(NULL))+ extra-libraries: s2n++test-suite memory-safety+ type: exitcode-stdio-1.0+ main-is: MemorySafety.hs+ hs-source-dirs: test+ default-language: GHC2021+ build-depends:+ base >= 4.14 && < 5+ , s2n-tls-ffi+ ghc-options: -threaded -rtsopts "-with-rtsopts=-N"
+ src/S2nTls/Ffi.hs view
@@ -0,0 +1,918 @@+{-# LANGUAGE RecordWildCards #-}++{- |+Module : S2nTls.Ffi+Description : Low-level FFI bindings to the s2n-tls library+Copyright : (c) 2026 Daniel Goertzen+License : Apache-2.0+Maintainer : daniel.goertzen@gmail.com+Stability : experimental+Portability : non-portable (requires s2n-tls C library)++This module provides low-level FFI bindings to the s2n-tls library.++The core type is 'S2nTlsFfi', a record containing all FFI function+pointers. Use 'withS2nTlsFfi' with a 'Library' to obtain one:++* 'Linked': For executables that link s2n-tls at compile time.+ Uses dlopen(NULL) to load symbols from the running executable.++* @'Dynamic' path@: To load the library at runtime via dlopen.+ Pass the path to libs2n.so.++C wrappers are used to safely capture error information+(including TLS-dependent error strings) in the same C stack frame,+avoiding thread-local storage issues in Haskell FFI.++Symbol loading is forgiving - missing symbols don't cause failure+at load time. Instead, calling a missing symbol throws 'MissingSymbol'.+Check the 'missingSymbols' field to see which symbols weren't found.++= Memory Locking (mlock)++== What is mlock?++s2n-tls uses the Linux @mlock()@ system call to lock memory pages containing+cryptographic secrets (private keys, session keys, etc.) into RAM. This prevents+the operating system from swapping these pages to disk, where they could+potentially be recovered by an attacker after your application terminates.++== The RLIMIT_MEMLOCK Limit++Linux enforces a per-process limit on how much memory can be locked, controlled+by @RLIMIT_MEMLOCK@. On many systems, this defaults to just __64 KB__ (or even+32 KB on some Debian versions). Since s2n-tls locks memory for all TLS+connections and cryptographic operations, this limit can be exhausted quickly+in applications handling multiple connections.++When the limit is exceeded, you'll see errors like:++> Error Message: 'error calling mlock'+> Debug String: 'Error encountered in s2n_mem.c line 106'++== Solutions++__Option 1: Increase the mlock limit (recommended for production)__++Raise the limit for your shell session:++> ulimit -l unlimited++Or set it to a specific value (in KB):++> ulimit -l 65536 # 64 MB++For systemd services, add to your unit file:++> [Service]+> LimitMEMLOCK=infinity++For persistent user limits, add to @\/etc\/security\/limits.conf@:++> youruser soft memlock unlimited+> youruser hard memlock unlimited++__Option 2: Disable mlock (acceptable for development\/testing)__++Set the environment variable to disable memory locking entirely:++> S2N_DONT_MLOCK=1 ./your-application++== Security Considerations++* __With mlock enabled__: Secrets are protected from being written to swap,+ reducing the risk of recovery from disk. This is the recommended setting+ for production deployments handling sensitive data.++* __With mlock disabled__: Secrets may be swapped to disk under memory+ pressure. This is generally acceptable for development, testing, and+ applications where the threat model doesn't include disk forensics.++* __Note__: Even with mlock enabled, laptop suspend\/hibernate modes may+ save RAM contents to disk regardless of memory locks.++== Running Tests++Tests may exhaust the default mlock limit. Use:++> S2N_DONT_MLOCK=1 cabal test+-}+module S2nTls.Ffi (+ -- * Core Types+ S2nTlsFfi (..),++ -- * Library Loading+ Library (..),+ withS2nTlsFfi,+ LoadError (..),++ -- * Error Types+ MissingSymbol (..),+ S2nError (..),+ S2nErrorFuncs (..),+) where++import Control.Exception (Exception, bracket, throwIO)+import Control.Monad (when)+import Data.IORef (modifyIORef', newIORef, readIORef)+import Data.Word (Word16, Word32, Word64, Word8)+import Foreign.C.String (CString)+import Foreign.C.Types (CBool (..), CInt (..), CLong (..), CSize (..))+import Foreign.Marshal.Alloc (alloca, free, malloc)+import Foreign.Ptr (FunPtr, Ptr, nullFunPtr, nullPtr)+import Foreign.Storable (peek, poke)+import System.Posix.DynamicLinker (DL, RTLDFlags (RTLD_LAZY, RTLD_LOCAL), dlclose, dlopen, dlsym)+import System.Posix.Types (CSsize (..))++import S2nTls.Ffi.Types++-- | Specifies how to load the s2n-tls library.+data Library+ = -- | Load symbols from the currently linked executable (uses dlopen(NULL))+ Linked+ | -- | Load library dynamically from the given path+ Dynamic String+ deriving (Show, Eq)++-- | Errors that can occur when loading the s2n-tls library.+data LoadError+ = -- | Library file could not be opened+ LibraryNotFound FilePath String+ | -- | A required symbol was not found in the library+ RequiredSymbolNotFound String+ deriving (Show, Eq)++instance Exception LoadError++class TransformError a where+ transformError :: (Ptr S2nError -> IO a) -> IO (Either S2nError a)++instance TransformError CInt where+ transformError action = alloca $ \errInfoPtr -> do+ res <- action errInfoPtr+ if res < 0+ then Left <$> peek errInfoPtr+ else pure $ Right res++instance TransformError CSsize where+ transformError action = alloca $ \errInfoPtr -> do+ res <- action errInfoPtr+ if res < 0+ then Left <$> peek errInfoPtr+ else pure $ Right res++instance TransformError (Ptr a) where+ transformError action = alloca $ \errInfoPtr -> do+ res <- action errInfoPtr+ if res == nullPtr+ then Left <$> peek errInfoPtr+ else pure $ Right res++-- CSize is unsigned, so functions returning CSize typically can't fail+-- They always return a valid size value+instance TransformError CSize where+ transformError action = alloca $ \errInfoPtr -> do+ res <- action errInfoPtr+ pure $ Right res++const2 :: a -> b -> c -> a+const2 x _ _ = x++const3 :: a -> b -> c -> d -> a+const3 x _ _ _ = x++const4 :: a -> b -> c -> d -> e -> a+const4 x _ _ _ _ = x++const5 :: a -> b -> c -> d -> e -> f -> a+const5 x _ _ _ _ _ = x++const6 :: a -> b -> c -> d -> e -> f -> g -> a+const6 x _ _ _ _ _ _ = x++const7 :: a -> b -> c -> d -> e -> f -> g -> h -> a+const7 x _ _ _ _ _ _ _ = x++{- | Load the s2n-tls library and provide a 'S2nTlsFfi' record to the+given callback. The library is automatically unloaded when the callback+returns (or throws an exception).++@+-- Use symbols from the linked executable+withS2nTlsFfi Linked $ \\ffi -> do+ result <- s2n_init ffi+ ...++-- Load library dynamically+withS2nTlsFfi (Dynamic "libs2n.so") $ \\ffi -> do+ print (missingSymbols ffi) -- see which symbols weren't found+ ...+@+-}+withS2nTlsFfi ::+ -- | How to load the library+ Library ->+ -- | Callback that receives the populated 'S2nTlsFfi' record+ (S2nTlsFfi -> IO a) ->+ IO a+withS2nTlsFfi lib action =+ bracket (openLib (libraryPath lib)) dlclose $ \dl ->+ bracket (malloc :: IO (Ptr S2nErrorFuncs)) free $ \errFuncsPtr -> do+ -- Load error functions first (fatal if missing)+ errFuncs <- loadErrorFuncs dl+ poke errFuncsPtr errFuncs++ -- Load all other symbols (forgiving)+ (ffi, missing) <- loadSymbols dl errFuncsPtr+ action ffi{missingSymbols = missing}++-- | Convert Library to the path string for dlopen+libraryPath :: Library -> FilePath+libraryPath Linked = ""+libraryPath (Dynamic path) = path++-- | Open the library, handling empty path for dlopen(NULL)+openLib :: FilePath -> IO DL+openLib path = dlopen path [RTLD_LAZY, RTLD_LOCAL]++-- | Load the error functions (required for meaningful error reporting)+loadErrorFuncs :: DL -> IO S2nErrorFuncs+loadErrorFuncs dl = do+ el <- dlsym dl "s2n_errno_location"+ sd <- dlsym dl "s2n_strerror_debug"+ et <- dlsym dl "s2n_error_get_type"+ pure $ S2nErrorFuncs el sd et++-- | Create a closure that throws MissingSymbol+throwMissing :: String -> IO a+throwMissing name = throwIO (MissingSymbol name)++-- | Indicate where a symbol is required vs optional+data MethodRequirement = Mandatory | Optional+ deriving (Show, Eq)++{- | Load all s2n-tls symbols from the given dynamic library handle.+Returns the S2nTlsFfi record and list of missing symbol names.+-}+loadSymbols :: DL -> Ptr S2nErrorFuncs -> IO (S2nTlsFfi, [String])+loadSymbols dl errFuncsPtr = do+ missingRef <- newIORef []++ let+ -- Helper to load a symbol with forgiving behavior+ load :: String -> MethodRequirement -> IO (FunPtr a)+ load name req = do+ ptr <- dlsym dl name+ when (ptr == nullFunPtr) $ do+ modifyIORef' missingRef (name :)+ if ptr == nullFunPtr && req == Mandatory+ then do+ throwMissing name+ else do+ pure ptr++ mkMethod0Direct :: String -> MethodRequirement -> (FunPtr x -> IO r) -> IO (IO r)+ mkMethod0Direct name req action = do+ ptr <- load name req+ pure $+ if ptr == nullFunPtr+ then throwMissing name+ else action ptr++ mkMethod1Direct :: String -> MethodRequirement -> (FunPtr x -> a -> IO r) -> IO (a -> IO r)+ mkMethod1Direct name req action = do+ ptr <- load name req+ pure $+ if ptr == nullFunPtr+ then const (throwMissing name)+ else action ptr++ mkMethod2Direct :: String -> MethodRequirement -> (FunPtr x -> a -> b -> IO r) -> IO (a -> b -> IO r)+ mkMethod2Direct name req action = do+ ptr <- load name req+ pure $+ if ptr == nullFunPtr+ then const2 (throwMissing name)+ else action ptr++ -- Note: C wrappers have signature: FunPtr -> args... -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO r+ mkMethod0 :: (TransformError r) => String -> MethodRequirement -> (FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO r) -> IO (IO (Either S2nError r))+ mkMethod0 name req action = do+ ptr <- load name req+ pure $+ if ptr == nullFunPtr+ then throwMissing name+ else transformError (action ptr errFuncsPtr)++ mkMethod1 :: (TransformError r) => String -> MethodRequirement -> (FunPtr () -> a -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO r) -> IO (a -> IO (Either S2nError r))+ mkMethod1 name req action = do+ ptr <- load name req+ pure $+ if ptr == nullFunPtr+ then const (throwMissing name)+ else \a -> transformError (action ptr a errFuncsPtr)++ mkMethod2 :: (TransformError r) => String -> MethodRequirement -> (FunPtr () -> a -> b -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO r) -> IO (a -> b -> IO (Either S2nError r))+ mkMethod2 name req action = do+ ptr <- load name req+ pure $+ if ptr == nullFunPtr+ then const2 (throwMissing name)+ else \a b -> transformError (action ptr a b errFuncsPtr)++ mkMethod3 :: (TransformError r) => String -> MethodRequirement -> (FunPtr () -> a -> b -> c -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO r) -> IO (a -> b -> c -> IO (Either S2nError r))+ mkMethod3 name req action = do+ ptr <- load name req+ pure $+ if ptr == nullFunPtr+ then const3 (throwMissing name)+ else \a b c -> transformError (action ptr a b c errFuncsPtr)++ mkMethod4 :: (TransformError r) => String -> MethodRequirement -> (FunPtr () -> a -> b -> c -> d -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO r) -> IO (a -> b -> c -> d -> IO (Either S2nError r))+ mkMethod4 name req action = do+ ptr <- load name req+ pure $+ if ptr == nullFunPtr+ then const4 (throwMissing name)+ else \a b c d -> transformError (action ptr a b c d errFuncsPtr)++ mkMethod5 :: (TransformError r) => String -> MethodRequirement -> (FunPtr () -> a -> b -> c -> d -> e -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO r) -> IO (a -> b -> c -> d -> e -> IO (Either S2nError r))+ mkMethod5 name req action = do+ ptr <- load name req+ pure $+ if ptr == nullFunPtr+ then const5 (throwMissing name)+ else \a b c d e -> transformError (action ptr a b c d e errFuncsPtr)++ mkMethod6 :: (TransformError r) => String -> MethodRequirement -> (FunPtr () -> a -> b -> c -> d -> e -> f -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO r) -> IO (a -> b -> c -> d -> e -> f -> IO (Either S2nError r))+ mkMethod6 name req action = do+ ptr <- load name req+ pure $+ if ptr == nullFunPtr+ then const6 (throwMissing name)+ else \a b c d e f -> transformError (action ptr a b c d e f errFuncsPtr)++ mkMethod7 :: (TransformError r) => String -> MethodRequirement -> (FunPtr () -> a -> b -> c -> d -> e -> f -> g -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO r) -> IO (a -> b -> c -> d -> e -> f -> g -> IO (Either S2nError r))+ mkMethod7 name req action = do+ ptr <- load name req+ pure $+ if ptr == nullFunPtr+ then const7 (throwMissing name)+ else \a b c d e f g -> transformError (action ptr a b c d e f g errFuncsPtr)++ -- Initialization & Cleanup+ s2n_init <- mkMethod0 "s2n_init" Optional c_wrap_init+ s2n_cleanup <- mkMethod0 "s2n_cleanup" Optional c_wrap_cleanup+ s2n_cleanup_final <- mkMethod0 "s2n_cleanup_final" Optional c_wrap_cleanup_final+ s2n_crypto_disable_init <- mkMethod0 "s2n_crypto_disable_init" Optional c_wrap_crypto_disable_init+ s2n_disable_atexit <- mkMethod0 "s2n_disable_atexit" Optional c_wrap_disable_atexit+ s2n_get_openssl_version <- mkMethod0Direct "s2n_get_openssl_version" Mandatory mk_s2n_get_openssl_version+ s2n_get_fips_mode <- mkMethod1 "s2n_get_fips_mode" Optional c_wrap_get_fips_mode++ -- Error Handling (load function pointers and wrap directly)+ s2n_errno_location <- mkMethod0Direct "s2n_errno_location" Mandatory mk_s2n_errno_location+ s2n_strerror <- mkMethod2Direct "s2n_strerror" Mandatory mk_s2n_strerror+ s2n_strerror_debug <- mkMethod2Direct "s2n_strerror_debug" Mandatory mk_s2n_strerror_debug+ s2n_strerror_source <- mkMethod1Direct "s2n_strerror_source" Mandatory mk_s2n_strerror_source+ s2n_error_get_type <- mkMethod1Direct "s2n_error_get_type" Mandatory mk_s2n_error_get_type+ s2n_strerror_name <- mkMethod1Direct "s2n_strerror_name" Mandatory mk_s2n_strerror_name++ -- Stack Traces+ s2n_stack_traces_enabled <- mkMethod0Direct "s2n_stack_traces_enabled" Optional mk_s2n_stack_traces_enabled+ s2n_stack_traces_enabled_set <- mkMethod1 "s2n_stack_traces_enabled_set" Optional c_wrap_stack_traces_enabled_set+ s2n_calculate_stacktrace <- mkMethod0 "s2n_calculate_stacktrace" Optional c_wrap_calculate_stacktrace+ s2n_free_stacktrace <- mkMethod0 "s2n_free_stacktrace" Optional c_wrap_free_stacktrace+ s2n_get_stacktrace <- mkMethod1 "s2n_get_stacktrace" Optional c_wrap_get_stacktrace++ -- Config Management+ s2n_config_new <- mkMethod0 "s2n_config_new" Optional c_wrap_config_new+ s2n_config_new_minimal <- mkMethod0 "s2n_config_new_minimal" Optional c_wrap_config_new_minimal+ s2n_config_free <- mkMethod1 "s2n_config_free" Optional c_wrap_config_free+ s2n_config_free_dhparams <- mkMethod1 "s2n_config_free_dhparams" Optional c_wrap_config_free_dhparams+ s2n_config_free_cert_chain_and_key <- mkMethod1 "s2n_config_free_cert_chain_and_key" Optional c_wrap_config_free_cert_chain_and_key+ s2n_config_set_wall_clock <- mkMethod3 "s2n_config_set_wall_clock" Optional c_wrap_config_set_wall_clock+ s2n_config_set_monotonic_clock <- mkMethod3 "s2n_config_set_monotonic_clock" Optional c_wrap_config_set_monotonic_clock+ -- Cache Callbacks+ s2n_config_set_cache_store_callback <- mkMethod3 "s2n_config_set_cache_store_callback" Optional c_wrap_config_set_cache_store_callback+ s2n_config_set_cache_retrieve_callback <- mkMethod3 "s2n_config_set_cache_retrieve_callback" Optional c_wrap_config_set_cache_retrieve_callback+ s2n_config_set_cache_delete_callback <- mkMethod3 "s2n_config_set_cache_delete_callback" Optional c_wrap_config_set_cache_delete_callback+ -- Memory & Random Callbacks+ s2n_mem_set_callbacks <- mkMethod4 "s2n_mem_set_callbacks" Optional c_wrap_mem_set_callbacks+ s2n_rand_set_callbacks <- mkMethod4 "s2n_rand_set_callbacks" Optional c_wrap_rand_set_callbacks++ -- Certificate Chain Management+ s2n_cert_chain_and_key_new <- mkMethod0 "s2n_cert_chain_and_key_new" Optional c_wrap_cert_chain_and_key_new+ s2n_cert_chain_and_key_load_pem <- mkMethod3 "s2n_cert_chain_and_key_load_pem" Optional c_wrap_cert_chain_and_key_load_pem+ s2n_cert_chain_and_key_load_pem_bytes <- mkMethod5 "s2n_cert_chain_and_key_load_pem_bytes" Optional c_wrap_cert_chain_and_key_load_pem_bytes+ s2n_cert_chain_and_key_load_public_pem_bytes <- mkMethod3 "s2n_cert_chain_and_key_load_public_pem_bytes" Optional c_wrap_cert_chain_and_key_load_public_pem_bytes+ s2n_cert_chain_and_key_free <- mkMethod1 "s2n_cert_chain_and_key_free" Optional c_wrap_cert_chain_and_key_free+ s2n_cert_chain_and_key_set_ctx <- mkMethod2 "s2n_cert_chain_and_key_set_ctx" Optional c_wrap_cert_chain_and_key_set_ctx+ s2n_cert_chain_and_key_get_ctx <- mkMethod1Direct "s2n_cert_chain_and_key_get_ctx" Mandatory mk_s2n_cert_chain_and_key_get_ctx+ s2n_cert_chain_and_key_get_private_key <- mkMethod1 "s2n_cert_chain_and_key_get_private_key" Optional c_wrap_cert_chain_and_key_get_private_key+ s2n_cert_chain_and_key_set_ocsp_data <- mkMethod3 "s2n_cert_chain_and_key_set_ocsp_data" Optional c_wrap_cert_chain_and_key_set_ocsp_data+ s2n_cert_chain_and_key_set_sct_list <- mkMethod3 "s2n_cert_chain_and_key_set_sct_list" Optional c_wrap_cert_chain_and_key_set_sct_list+ s2n_config_set_cert_tiebreak_callback <- mkMethod2 "s2n_config_set_cert_tiebreak_callback" Optional c_wrap_config_set_cert_tiebreak_callback+ s2n_config_add_cert_chain_and_key <- mkMethod3 "s2n_config_add_cert_chain_and_key" Optional c_wrap_config_add_cert_chain_and_key+ s2n_config_add_cert_chain_and_key_to_store <- mkMethod2 "s2n_config_add_cert_chain_and_key_to_store" Optional c_wrap_config_add_cert_chain_and_key_to_store+ s2n_config_set_cert_chain_and_key_defaults <- mkMethod3 "s2n_config_set_cert_chain_and_key_defaults" Optional c_wrap_config_set_cert_chain_and_key_defaults++ -- Trust Store+ s2n_config_set_verification_ca_location <- mkMethod3 "s2n_config_set_verification_ca_location" Optional c_wrap_config_set_verification_ca_location+ s2n_config_add_pem_to_trust_store <- mkMethod2 "s2n_config_add_pem_to_trust_store" Optional c_wrap_config_add_pem_to_trust_store+ s2n_config_wipe_trust_store <- mkMethod1 "s2n_config_wipe_trust_store" Optional c_wrap_config_wipe_trust_store+ s2n_config_load_system_certs <- mkMethod1 "s2n_config_load_system_certs" Optional c_wrap_config_load_system_certs+ s2n_config_set_cert_authorities_from_trust_store <- mkMethod1 "s2n_config_set_cert_authorities_from_trust_store" Optional c_wrap_config_set_cert_authorities_from_trust_store++ -- Verification & Validation+ s2n_config_set_verify_after_sign <- mkMethod2 "s2n_config_set_verify_after_sign" Optional c_wrap_config_set_verify_after_sign+ s2n_config_set_check_stapled_ocsp_response <- mkMethod2 "s2n_config_set_check_stapled_ocsp_response" Optional c_wrap_config_set_check_stapled_ocsp_response+ s2n_config_disable_x509_time_verification <- mkMethod1 "s2n_config_disable_x509_time_verification" Optional c_wrap_config_disable_x509_time_verification+ s2n_config_disable_x509_verification <- mkMethod1 "s2n_config_disable_x509_verification" Optional c_wrap_config_disable_x509_verification+ s2n_config_set_max_cert_chain_depth <- mkMethod2 "s2n_config_set_max_cert_chain_depth" Optional c_wrap_config_set_max_cert_chain_depth+ s2n_config_set_verify_host_callback <- mkMethod3 "s2n_config_set_verify_host_callback" Optional c_wrap_config_set_verify_host_callback++ -- DH Parameters+ s2n_config_add_dhparams <- mkMethod2 "s2n_config_add_dhparams" Optional c_wrap_config_add_dhparams++ -- Security Policies & Preferences+ s2n_config_set_cipher_preferences <- mkMethod2 "s2n_config_set_cipher_preferences" Optional c_wrap_config_set_cipher_preferences+ s2n_config_append_protocol_preference <- mkMethod3 "s2n_config_append_protocol_preference" Optional c_wrap_config_append_protocol_preference+ s2n_config_set_protocol_preferences <- mkMethod3 "s2n_config_set_protocol_preferences" Optional c_wrap_config_set_protocol_preferences+ s2n_config_set_status_request_type <- mkMethod2 "s2n_config_set_status_request_type" Optional c_wrap_config_set_status_request_type+ s2n_config_set_ct_support_level <- mkMethod2 "s2n_config_set_ct_support_level" Optional c_wrap_config_set_ct_support_level+ s2n_config_set_alert_behavior <- mkMethod2 "s2n_config_set_alert_behavior" Optional c_wrap_config_set_alert_behavior++ -- Extension Data+ s2n_config_set_extension_data <- mkMethod4 "s2n_config_set_extension_data" Optional c_wrap_config_set_extension_data+ s2n_config_send_max_fragment_length <- mkMethod2 "s2n_config_send_max_fragment_length" Optional c_wrap_config_send_max_fragment_length+ s2n_config_accept_max_fragment_length <- mkMethod1 "s2n_config_accept_max_fragment_length" Optional c_wrap_config_accept_max_fragment_length++ -- Session & Ticket Configuration+ s2n_config_set_session_state_lifetime <- mkMethod2 "s2n_config_set_session_state_lifetime" Optional c_wrap_config_set_session_state_lifetime+ s2n_config_set_session_tickets_onoff <- mkMethod2 "s2n_config_set_session_tickets_onoff" Optional c_wrap_config_set_session_tickets_onoff+ s2n_config_set_session_cache_onoff <- mkMethod2 "s2n_config_set_session_cache_onoff" Optional c_wrap_config_set_session_cache_onoff+ s2n_config_set_ticket_encrypt_decrypt_key_lifetime <- mkMethod2 "s2n_config_set_ticket_encrypt_decrypt_key_lifetime" Optional c_wrap_config_set_ticket_encrypt_decrypt_key_lifetime+ s2n_config_set_ticket_decrypt_key_lifetime <- mkMethod2 "s2n_config_set_ticket_decrypt_key_lifetime" Optional c_wrap_config_set_ticket_decrypt_key_lifetime+ s2n_config_add_ticket_crypto_key <- mkMethod6 "s2n_config_add_ticket_crypto_key" Optional c_wrap_config_add_ticket_crypto_key+ s2n_config_require_ticket_forward_secrecy <- mkMethod2 "s2n_config_require_ticket_forward_secrecy" Optional c_wrap_config_require_ticket_forward_secrecy+ -- Buffer & I/O Configuration+ s2n_config_set_send_buffer_size <- mkMethod2 "s2n_config_set_send_buffer_size" Optional c_wrap_config_set_send_buffer_size+ s2n_config_set_recv_multi_record <- mkMethod2 "s2n_config_set_recv_multi_record" Optional c_wrap_config_set_recv_multi_record++ -- Miscellaneous Config+ s2n_config_set_ctx <- mkMethod2 "s2n_config_set_ctx" Optional c_wrap_config_set_ctx+ s2n_config_get_ctx <- mkMethod2 "s2n_config_get_ctx" Optional c_wrap_config_get_ctx+ s2n_config_set_client_hello_cb <- mkMethod3 "s2n_config_set_client_hello_cb" Optional c_wrap_config_set_client_hello_cb+ s2n_config_set_client_hello_cb_mode <- mkMethod2 "s2n_config_set_client_hello_cb_mode" Optional c_wrap_config_set_client_hello_cb_mode+ s2n_config_set_max_blinding_delay <- mkMethod2 "s2n_config_set_max_blinding_delay" Optional c_wrap_config_set_max_blinding_delay+ s2n_config_get_client_auth_type <- mkMethod2 "s2n_config_get_client_auth_type" Optional c_wrap_config_get_client_auth_type+ s2n_config_set_client_auth_type <- mkMethod2 "s2n_config_set_client_auth_type" Optional c_wrap_config_set_client_auth_type+ s2n_config_set_initial_ticket_count <- mkMethod2 "s2n_config_set_initial_ticket_count" Optional c_wrap_config_set_initial_ticket_count+ s2n_config_set_psk_mode <- mkMethod2 "s2n_config_set_psk_mode" Optional c_wrap_config_set_psk_mode+ s2n_config_set_psk_selection_callback <- mkMethod3 "s2n_config_set_psk_selection_callback" Optional c_wrap_config_set_psk_selection_callback+ s2n_config_set_async_pkey_callback <- mkMethod2 "s2n_config_set_async_pkey_callback" Optional c_wrap_config_set_async_pkey_callback+ s2n_config_set_async_pkey_validation_mode <- mkMethod2 "s2n_config_set_async_pkey_validation_mode" Optional c_wrap_config_set_async_pkey_validation_mode+ s2n_config_set_session_ticket_cb <- mkMethod3 "s2n_config_set_session_ticket_cb" Optional c_wrap_config_set_session_ticket_cb+ s2n_config_set_key_log_cb <- mkMethod3 "s2n_config_set_key_log_cb" Optional c_wrap_config_set_key_log_cb+ s2n_config_enable_cert_req_dss_legacy_compat <- mkMethod1 "s2n_config_enable_cert_req_dss_legacy_compat" Optional c_wrap_config_enable_cert_req_dss_legacy_compat+ s2n_config_set_server_max_early_data_size <- mkMethod2 "s2n_config_set_server_max_early_data_size" Optional c_wrap_config_set_server_max_early_data_size+ s2n_config_set_early_data_cb <- mkMethod2 "s2n_config_set_early_data_cb" Optional c_wrap_config_set_early_data_cb+ s2n_config_get_supported_groups <- mkMethod4 "s2n_config_get_supported_groups" Optional c_wrap_config_get_supported_groups+ s2n_config_set_serialization_version <- mkMethod2 "s2n_config_set_serialization_version" Optional c_wrap_config_set_serialization_version++ -- Connection Creation & Management+ s2n_connection_new <- mkMethod1 "s2n_connection_new" Optional c_wrap_connection_new+ s2n_connection_set_config <- mkMethod2 "s2n_connection_set_config" Optional c_wrap_connection_set_config+ s2n_connection_set_ctx <- mkMethod2 "s2n_connection_set_ctx" Optional c_wrap_connection_set_ctx+ s2n_connection_get_ctx <- mkMethod1 "s2n_connection_get_ctx" Optional c_wrap_connection_get_ctx+ s2n_client_hello_cb_done <- mkMethod1 "s2n_client_hello_cb_done" Optional c_wrap_client_hello_cb_done+ s2n_connection_server_name_extension_used <- mkMethod1 "s2n_connection_server_name_extension_used" Optional c_wrap_connection_server_name_extension_used++ -- Client Hello Access+ s2n_connection_get_client_hello <- mkMethod1 "s2n_connection_get_client_hello" Optional c_wrap_connection_get_client_hello+ s2n_client_hello_parse_message <- mkMethod2 "s2n_client_hello_parse_message" Optional c_wrap_client_hello_parse_message+ s2n_client_hello_free <- mkMethod1 "s2n_client_hello_free" Optional c_wrap_client_hello_free+ s2n_client_hello_get_raw_message_length <- mkMethod1 "s2n_client_hello_get_raw_message_length" Optional c_wrap_client_hello_get_raw_message_length+ s2n_client_hello_get_raw_message <- mkMethod3 "s2n_client_hello_get_raw_message" Optional c_wrap_client_hello_get_raw_message+ s2n_client_hello_get_cipher_suites_length <- mkMethod1 "s2n_client_hello_get_cipher_suites_length" Optional c_wrap_client_hello_get_cipher_suites_length+ s2n_client_hello_get_cipher_suites <- mkMethod3 "s2n_client_hello_get_cipher_suites" Optional c_wrap_client_hello_get_cipher_suites+ s2n_client_hello_get_extensions_length <- mkMethod1 "s2n_client_hello_get_extensions_length" Optional c_wrap_client_hello_get_extensions_length+ s2n_client_hello_get_extensions <- mkMethod3 "s2n_client_hello_get_extensions" Optional c_wrap_client_hello_get_extensions+ s2n_client_hello_get_extension_length <- mkMethod2 "s2n_client_hello_get_extension_length" Optional c_wrap_client_hello_get_extension_length+ s2n_client_hello_get_extension_by_id <- mkMethod4 "s2n_client_hello_get_extension_by_id" Optional c_wrap_client_hello_get_extension_by_id+ s2n_client_hello_has_extension <- mkMethod3 "s2n_client_hello_has_extension" Optional c_wrap_client_hello_has_extension+ s2n_client_hello_get_session_id_length <- mkMethod2 "s2n_client_hello_get_session_id_length" Optional c_wrap_client_hello_get_session_id_length+ s2n_client_hello_get_session_id <- mkMethod4 "s2n_client_hello_get_session_id" Optional c_wrap_client_hello_get_session_id+ s2n_client_hello_get_compression_methods_length <- mkMethod2 "s2n_client_hello_get_compression_methods_length" Optional c_wrap_client_hello_get_compression_methods_length+ s2n_client_hello_get_compression_methods <- mkMethod4 "s2n_client_hello_get_compression_methods" Optional c_wrap_client_hello_get_compression_methods+ s2n_client_hello_get_legacy_protocol_version <- mkMethod2 "s2n_client_hello_get_legacy_protocol_version" Optional c_wrap_client_hello_get_legacy_protocol_version+ s2n_client_hello_get_supported_groups <- mkMethod4 "s2n_client_hello_get_supported_groups" Optional c_wrap_client_hello_get_supported_groups+ s2n_client_hello_get_server_name_length <- mkMethod2 "s2n_client_hello_get_server_name_length" Optional c_wrap_client_hello_get_server_name_length+ s2n_client_hello_get_server_name <- mkMethod4 "s2n_client_hello_get_server_name" Optional c_wrap_client_hello_get_server_name+ s2n_client_hello_get_legacy_record_version <- mkMethod2 "s2n_client_hello_get_legacy_record_version" Optional c_wrap_client_hello_get_legacy_record_version++ -- File Descriptor & I/O+ s2n_connection_set_fd <- mkMethod2 "s2n_connection_set_fd" Optional c_wrap_connection_set_fd+ s2n_connection_set_read_fd <- mkMethod2 "s2n_connection_set_read_fd" Optional c_wrap_connection_set_read_fd+ s2n_connection_set_write_fd <- mkMethod2 "s2n_connection_set_write_fd" Optional c_wrap_connection_set_write_fd+ s2n_connection_get_read_fd <- mkMethod2 "s2n_connection_get_read_fd" Optional c_wrap_connection_get_read_fd+ s2n_connection_get_write_fd <- mkMethod2 "s2n_connection_get_write_fd" Optional c_wrap_connection_get_write_fd+ s2n_connection_use_corked_io <- mkMethod1 "s2n_connection_use_corked_io" Optional c_wrap_connection_use_corked_io+ s2n_connection_set_recv_ctx <- mkMethod2 "s2n_connection_set_recv_ctx" Optional c_wrap_connection_set_recv_ctx+ s2n_connection_set_send_ctx <- mkMethod2 "s2n_connection_set_send_ctx" Optional c_wrap_connection_set_send_ctx+ s2n_connection_set_recv_cb <- mkMethod2 "s2n_connection_set_recv_cb" Optional c_wrap_connection_set_recv_cb+ s2n_connection_set_send_cb <- mkMethod2 "s2n_connection_set_send_cb" Optional c_wrap_connection_set_send_cb+ -- Connection Preferences+ s2n_connection_prefer_throughput <- mkMethod1 "s2n_connection_prefer_throughput" Optional c_wrap_connection_prefer_throughput+ s2n_connection_prefer_low_latency <- mkMethod1 "s2n_connection_prefer_low_latency" Optional c_wrap_connection_prefer_low_latency+ s2n_connection_set_recv_buffering <- mkMethod2 "s2n_connection_set_recv_buffering" Optional c_wrap_connection_set_recv_buffering+ s2n_peek_buffered <- mkMethod1Direct "s2n_peek_buffered" Optional mk_s2n_peek_buffered+ s2n_connection_set_dynamic_buffers <- mkMethod2 "s2n_connection_set_dynamic_buffers" Optional c_wrap_connection_set_dynamic_buffers+ s2n_connection_set_dynamic_record_threshold <- mkMethod3 "s2n_connection_set_dynamic_record_threshold" Optional c_wrap_connection_set_dynamic_record_threshold++ -- Host Verification+ s2n_connection_set_verify_host_callback <- mkMethod3 "s2n_connection_set_verify_host_callback" Optional c_wrap_connection_set_verify_host_callback+ -- Blinding & Security+ s2n_connection_set_blinding <- mkMethod2 "s2n_connection_set_blinding" Optional c_wrap_connection_set_blinding+ s2n_connection_get_delay <- mkMethod1Direct "s2n_connection_get_delay" Optional mk_s2n_connection_get_delay+ -- Cipher & Protocol Configuration+ s2n_connection_set_cipher_preferences <- mkMethod2 "s2n_connection_set_cipher_preferences" Optional c_wrap_connection_set_cipher_preferences+ s2n_connection_request_key_update <- mkMethod2 "s2n_connection_request_key_update" Optional c_wrap_connection_request_key_update+ s2n_connection_append_protocol_preference <- mkMethod3 "s2n_connection_append_protocol_preference" Optional c_wrap_connection_append_protocol_preference+ s2n_connection_set_protocol_preferences <- mkMethod3 "s2n_connection_set_protocol_preferences" Optional c_wrap_connection_set_protocol_preferences+ -- Server Name (SNI)+ s2n_set_server_name <- mkMethod2 "s2n_set_server_name" Optional c_wrap_set_server_name+ s2n_get_server_name <- mkMethod1 "s2n_get_server_name" Optional c_wrap_get_server_name+ -- Application Protocol (ALPN)+ s2n_get_application_protocol <- mkMethod1 "s2n_get_application_protocol" Optional c_wrap_get_application_protocol+ -- OCSP & Certificate Transparency+ s2n_connection_get_ocsp_response <- mkMethod2 "s2n_connection_get_ocsp_response" Optional c_wrap_connection_get_ocsp_response+ s2n_connection_get_sct_list <- mkMethod2 "s2n_connection_get_sct_list" Optional c_wrap_connection_get_sct_list+ -- Handshake & TLS Operations+ s2n_negotiate <- mkMethod2 "s2n_negotiate" Optional c_wrap_negotiate+ s2n_send <- mkMethod4 "s2n_send" Optional c_wrap_send+ s2n_recv <- mkMethod4 "s2n_recv" Optional c_wrap_recv+ s2n_peek <- mkMethod1Direct "s2n_peek" Optional mk_s2n_peek+ s2n_connection_free_handshake <- mkMethod1 "s2n_connection_free_handshake" Optional c_wrap_connection_free_handshake+ s2n_connection_release_buffers <- mkMethod1 "s2n_connection_release_buffers" Optional c_wrap_connection_release_buffers+ s2n_connection_wipe <- mkMethod1 "s2n_connection_wipe" Optional c_wrap_connection_wipe+ s2n_connection_free <- mkMethod1 "s2n_connection_free" Optional c_wrap_connection_free+ s2n_shutdown <- mkMethod2 "s2n_shutdown" Optional c_wrap_shutdown+ s2n_shutdown_send <- mkMethod2 "s2n_shutdown_send" Optional c_wrap_shutdown_send+ -- Client Authentication+ s2n_connection_get_client_auth_type <- mkMethod2 "s2n_connection_get_client_auth_type" Optional c_wrap_connection_get_client_auth_type+ s2n_connection_set_client_auth_type <- mkMethod2 "s2n_connection_set_client_auth_type" Optional c_wrap_connection_set_client_auth_type+ s2n_connection_get_client_cert_chain <- mkMethod3 "s2n_connection_get_client_cert_chain" Optional c_wrap_connection_get_client_cert_chain+ s2n_connection_client_cert_used <- mkMethod1 "s2n_connection_client_cert_used" Optional c_wrap_connection_client_cert_used+ -- Session Management+ s2n_connection_add_new_tickets_to_send <- mkMethod2 "s2n_connection_add_new_tickets_to_send" Optional c_wrap_connection_add_new_tickets_to_send+ s2n_connection_get_tickets_sent <- mkMethod2 "s2n_connection_get_tickets_sent" Optional c_wrap_connection_get_tickets_sent+ s2n_connection_set_server_keying_material_lifetime <- mkMethod2 "s2n_connection_set_server_keying_material_lifetime" Optional c_wrap_connection_set_server_keying_material_lifetime+ s2n_session_ticket_get_data_len <- mkMethod2 "s2n_session_ticket_get_data_len" Optional c_wrap_session_ticket_get_data_len+ s2n_session_ticket_get_data <- mkMethod3 "s2n_session_ticket_get_data" Optional c_wrap_session_ticket_get_data+ s2n_session_ticket_get_lifetime <- mkMethod2 "s2n_session_ticket_get_lifetime" Optional c_wrap_session_ticket_get_lifetime+ s2n_connection_set_session <- mkMethod3 "s2n_connection_set_session" Optional c_wrap_connection_set_session+ s2n_connection_get_session <- mkMethod3 "s2n_connection_get_session" Optional c_wrap_connection_get_session+ s2n_connection_get_session_ticket_lifetime_hint <- mkMethod1 "s2n_connection_get_session_ticket_lifetime_hint" Optional c_wrap_connection_get_session_ticket_lifetime_hint+ s2n_connection_get_session_length <- mkMethod1 "s2n_connection_get_session_length" Optional c_wrap_connection_get_session_length+ s2n_connection_get_session_id_length <- mkMethod1 "s2n_connection_get_session_id_length" Optional c_wrap_connection_get_session_id_length+ s2n_connection_get_session_id <- mkMethod3 "s2n_connection_get_session_id" Optional c_wrap_connection_get_session_id+ s2n_connection_is_session_resumed <- mkMethod1 "s2n_connection_is_session_resumed" Optional c_wrap_connection_is_session_resumed+ -- Certificate Information+ s2n_connection_is_ocsp_stapled <- mkMethod1 "s2n_connection_is_ocsp_stapled" Optional c_wrap_connection_is_ocsp_stapled+ s2n_connection_get_selected_signature_algorithm <- mkMethod2 "s2n_connection_get_selected_signature_algorithm" Optional c_wrap_connection_get_selected_signature_algorithm+ s2n_connection_get_selected_digest_algorithm <- mkMethod2 "s2n_connection_get_selected_digest_algorithm" Optional c_wrap_connection_get_selected_digest_algorithm+ s2n_connection_get_selected_client_cert_signature_algorithm <- mkMethod2 "s2n_connection_get_selected_client_cert_signature_algorithm" Optional c_wrap_connection_get_selected_client_cert_signature_algorithm+ s2n_connection_get_selected_client_cert_digest_algorithm <- mkMethod2 "s2n_connection_get_selected_client_cert_digest_algorithm" Optional c_wrap_connection_get_selected_client_cert_digest_algorithm+ s2n_connection_get_selected_cert <- mkMethod1 "s2n_connection_get_selected_cert" Optional c_wrap_connection_get_selected_cert+ s2n_cert_chain_get_length <- mkMethod2 "s2n_cert_chain_get_length" Optional c_wrap_cert_chain_get_length+ s2n_cert_chain_get_cert <- mkMethod3 "s2n_cert_chain_get_cert" Optional c_wrap_cert_chain_get_cert+ s2n_cert_get_der <- mkMethod3 "s2n_cert_get_der" Optional c_wrap_cert_get_der+ s2n_connection_get_peer_cert_chain <- mkMethod2 "s2n_connection_get_peer_cert_chain" Optional c_wrap_connection_get_peer_cert_chain+ s2n_cert_get_x509_extension_value_length <- mkMethod3 "s2n_cert_get_x509_extension_value_length" Optional c_wrap_cert_get_x509_extension_value_length+ s2n_cert_get_x509_extension_value <- mkMethod5 "s2n_cert_get_x509_extension_value" Optional c_wrap_cert_get_x509_extension_value+ s2n_cert_get_utf8_string_from_extension_data_length <- mkMethod3 "s2n_cert_get_utf8_string_from_extension_data_length" Optional c_wrap_cert_get_utf8_string_from_extension_data_length+ s2n_cert_get_utf8_string_from_extension_data <- mkMethod4 "s2n_cert_get_utf8_string_from_extension_data" Optional c_wrap_cert_get_utf8_string_from_extension_data+ -- Pre-Shared Keys (PSK)+ s2n_external_psk_new <- mkMethod0 "s2n_external_psk_new" Optional c_wrap_external_psk_new+ s2n_psk_free <- mkMethod1 "s2n_psk_free" Optional c_wrap_psk_free+ s2n_psk_set_identity <- mkMethod3 "s2n_psk_set_identity" Optional c_wrap_psk_set_identity+ s2n_psk_set_secret <- mkMethod3 "s2n_psk_set_secret" Optional c_wrap_psk_set_secret+ s2n_psk_set_hmac <- mkMethod2 "s2n_psk_set_hmac" Optional c_wrap_psk_set_hmac+ s2n_connection_append_psk <- mkMethod2 "s2n_connection_append_psk" Optional c_wrap_connection_append_psk+ s2n_connection_set_psk_mode <- mkMethod2 "s2n_connection_set_psk_mode" Optional c_wrap_connection_set_psk_mode+ s2n_connection_get_negotiated_psk_identity_length <- mkMethod2 "s2n_connection_get_negotiated_psk_identity_length" Optional c_wrap_connection_get_negotiated_psk_identity_length+ s2n_connection_get_negotiated_psk_identity <- mkMethod3 "s2n_connection_get_negotiated_psk_identity" Optional c_wrap_connection_get_negotiated_psk_identity+ s2n_offered_psk_new <- mkMethod0 "s2n_offered_psk_new" Optional c_wrap_offered_psk_new+ s2n_offered_psk_free <- mkMethod1 "s2n_offered_psk_free" Optional c_wrap_offered_psk_free+ s2n_offered_psk_get_identity <- mkMethod3 "s2n_offered_psk_get_identity" Optional c_wrap_offered_psk_get_identity+ s2n_offered_psk_list_has_next <- mkMethod1Direct "s2n_offered_psk_list_has_next" Optional mk_s2n_offered_psk_list_has_next+ s2n_offered_psk_list_next <- mkMethod2 "s2n_offered_psk_list_next" Optional c_wrap_offered_psk_list_next+ s2n_offered_psk_list_reread <- mkMethod1 "s2n_offered_psk_list_reread" Optional c_wrap_offered_psk_list_reread+ s2n_offered_psk_list_choose_psk <- mkMethod2 "s2n_offered_psk_list_choose_psk" Optional c_wrap_offered_psk_list_choose_psk+ s2n_psk_configure_early_data <- mkMethod4 "s2n_psk_configure_early_data" Optional c_wrap_psk_configure_early_data+ s2n_psk_set_application_protocol <- mkMethod3 "s2n_psk_set_application_protocol" Optional c_wrap_psk_set_application_protocol+ s2n_psk_set_early_data_context <- mkMethod3 "s2n_psk_set_early_data_context" Optional c_wrap_psk_set_early_data_context+ -- Connection Statistics+ s2n_connection_get_wire_bytes_in <- mkMethod1Direct "s2n_connection_get_wire_bytes_in" Optional mk_s2n_connection_get_wire_bytes_in+ s2n_connection_get_wire_bytes_out <- mkMethod1Direct "s2n_connection_get_wire_bytes_out" Optional mk_s2n_connection_get_wire_bytes_out+ -- Protocol Version Information+ s2n_connection_get_client_protocol_version <- mkMethod1 "s2n_connection_get_client_protocol_version" Optional c_wrap_connection_get_client_protocol_version+ s2n_connection_get_server_protocol_version <- mkMethod1 "s2n_connection_get_server_protocol_version" Optional c_wrap_connection_get_server_protocol_version+ s2n_connection_get_actual_protocol_version <- mkMethod1 "s2n_connection_get_actual_protocol_version" Optional c_wrap_connection_get_actual_protocol_version+ s2n_connection_get_client_hello_version <- mkMethod1 "s2n_connection_get_client_hello_version" Optional c_wrap_connection_get_client_hello_version+ -- Cipher & Security Information+ s2n_connection_get_cipher <- mkMethod1 "s2n_connection_get_cipher" Optional c_wrap_connection_get_cipher+ s2n_connection_get_certificate_match <- mkMethod2 "s2n_connection_get_certificate_match" Optional c_wrap_connection_get_certificate_match+ s2n_connection_get_master_secret <- mkMethod3 "s2n_connection_get_master_secret" Optional c_wrap_connection_get_master_secret+ s2n_connection_tls_exporter <- mkMethod7 "s2n_connection_tls_exporter" Optional c_wrap_connection_tls_exporter+ s2n_connection_get_cipher_iana_value <- mkMethod3 "s2n_connection_get_cipher_iana_value" Optional c_wrap_connection_get_cipher_iana_value+ s2n_connection_is_valid_for_cipher_preferences <- mkMethod2 "s2n_connection_is_valid_for_cipher_preferences" Optional c_wrap_connection_is_valid_for_cipher_preferences+ s2n_connection_get_curve <- mkMethod1 "s2n_connection_get_curve" Optional c_wrap_connection_get_curve+ s2n_connection_get_kem_name <- mkMethod1 "s2n_connection_get_kem_name" Optional c_wrap_connection_get_kem_name+ s2n_connection_get_kem_group_name <- mkMethod1 "s2n_connection_get_kem_group_name" Optional c_wrap_connection_get_kem_group_name+ s2n_connection_get_key_exchange_group <- mkMethod2 "s2n_connection_get_key_exchange_group" Optional c_wrap_connection_get_key_exchange_group+ s2n_connection_get_alert <- mkMethod1 "s2n_connection_get_alert" Optional c_wrap_connection_get_alert+ s2n_connection_get_handshake_type_name <- mkMethod1 "s2n_connection_get_handshake_type_name" Optional c_wrap_connection_get_handshake_type_name+ s2n_connection_get_last_message_name <- mkMethod1 "s2n_connection_get_last_message_name" Optional c_wrap_connection_get_last_message_name+ -- Async Private Key Operations+ s2n_async_pkey_op_perform <- mkMethod2 "s2n_async_pkey_op_perform" Optional c_wrap_async_pkey_op_perform+ s2n_async_pkey_op_apply <- mkMethod2 "s2n_async_pkey_op_apply" Optional c_wrap_async_pkey_op_apply+ s2n_async_pkey_op_free <- mkMethod1 "s2n_async_pkey_op_free" Optional c_wrap_async_pkey_op_free+ s2n_async_pkey_op_get_op_type <- mkMethod2 "s2n_async_pkey_op_get_op_type" Optional c_wrap_async_pkey_op_get_op_type+ s2n_async_pkey_op_get_input_size <- mkMethod2 "s2n_async_pkey_op_get_input_size" Optional c_wrap_async_pkey_op_get_input_size+ s2n_async_pkey_op_get_input <- mkMethod3 "s2n_async_pkey_op_get_input" Optional c_wrap_async_pkey_op_get_input+ s2n_async_pkey_op_set_output <- mkMethod3 "s2n_async_pkey_op_set_output" Optional c_wrap_async_pkey_op_set_output+ -- Early Data+ s2n_connection_set_server_max_early_data_size <- mkMethod2 "s2n_connection_set_server_max_early_data_size" Optional c_wrap_connection_set_server_max_early_data_size+ s2n_connection_set_server_early_data_context <- mkMethod3 "s2n_connection_set_server_early_data_context" Optional c_wrap_connection_set_server_early_data_context+ s2n_connection_get_early_data_status <- mkMethod2 "s2n_connection_get_early_data_status" Optional c_wrap_connection_get_early_data_status+ s2n_connection_get_remaining_early_data_size <- mkMethod2 "s2n_connection_get_remaining_early_data_size" Optional c_wrap_connection_get_remaining_early_data_size+ s2n_connection_get_max_early_data_size <- mkMethod2 "s2n_connection_get_max_early_data_size" Optional c_wrap_connection_get_max_early_data_size+ s2n_send_early_data <- mkMethod5 "s2n_send_early_data" Optional c_wrap_send_early_data+ s2n_recv_early_data <- mkMethod5 "s2n_recv_early_data" Optional c_wrap_recv_early_data+ s2n_offered_early_data_get_context_length <- mkMethod2 "s2n_offered_early_data_get_context_length" Optional c_wrap_offered_early_data_get_context_length+ s2n_offered_early_data_get_context <- mkMethod3 "s2n_offered_early_data_get_context" Optional c_wrap_offered_early_data_get_context+ s2n_offered_early_data_reject <- mkMethod1 "s2n_offered_early_data_reject" Optional c_wrap_offered_early_data_reject+ s2n_offered_early_data_accept <- mkMethod1 "s2n_offered_early_data_accept" Optional c_wrap_offered_early_data_accept+ -- Connection Serialization+ s2n_connection_serialization_length <- mkMethod2 "s2n_connection_serialization_length" Optional c_wrap_connection_serialization_length+ s2n_connection_serialize <- mkMethod3 "s2n_connection_serialize" Optional c_wrap_connection_serialize+ s2n_connection_deserialize <- mkMethod3 "s2n_connection_deserialize" Optional c_wrap_connection_deserialize++ missingSymbols <- readIORef missingRef+ pure (S2nTlsFfi{..}, missingSymbols)++-- Foreign imports for C wrappers and direct function pointers+-- These are defined in cbits/s2n_wrapper.c++foreign import ccall "dynamic" mk_s2n_errno_location :: FunPtr (IO (Ptr CInt)) -> IO (Ptr CInt)+foreign import ccall "dynamic" mk_s2n_strerror :: FunPtr (CInt -> CString -> IO CString) -> CInt -> CString -> IO CString+foreign import ccall "dynamic" mk_s2n_strerror_debug :: FunPtr (CInt -> CString -> IO CString) -> CInt -> CString -> IO CString+foreign import ccall "dynamic" mk_s2n_strerror_source :: FunPtr (CInt -> IO CString) -> CInt -> IO CString+foreign import ccall "dynamic" mk_s2n_strerror_name :: FunPtr (CInt -> IO CString) -> CInt -> IO CString+foreign import ccall "dynamic" mk_s2n_error_get_type :: FunPtr (CInt -> IO S2nErrorType) -> CInt -> IO S2nErrorType+foreign import ccall "dynamic" mk_s2n_get_openssl_version :: FunPtr (IO CLong) -> IO CLong+foreign import ccall "dynamic" mk_s2n_stack_traces_enabled :: FunPtr (IO CBool) -> IO CBool+foreign import ccall "dynamic" mk_s2n_peek :: FunPtr (Ptr S2nConnection -> IO Word32) -> Ptr S2nConnection -> IO Word32+foreign import ccall "dynamic" mk_s2n_peek_buffered :: FunPtr (Ptr S2nConnection -> IO Word32) -> Ptr S2nConnection -> IO Word32+foreign import ccall "dynamic" mk_s2n_connection_get_delay :: FunPtr (Ptr S2nConnection -> IO Word64) -> Ptr S2nConnection -> IO Word64+foreign import ccall "dynamic" mk_s2n_connection_get_wire_bytes_in :: FunPtr (Ptr S2nConnection -> IO Word64) -> Ptr S2nConnection -> IO Word64+foreign import ccall "dynamic" mk_s2n_connection_get_wire_bytes_out :: FunPtr (Ptr S2nConnection -> IO Word64) -> Ptr S2nConnection -> IO Word64+foreign import ccall "dynamic" mk_s2n_cert_chain_and_key_get_ctx :: FunPtr (Ptr S2nCertChainAndKey -> IO (Ptr ())) -> Ptr S2nCertChainAndKey -> IO (Ptr ())+foreign import ccall "dynamic" mk_s2n_offered_psk_list_has_next :: FunPtr (Ptr S2nOfferedPskList -> IO CBool) -> Ptr S2nOfferedPskList -> IO CBool++-- C wrapper imports+foreign import ccall safe "s2n_wrap_init" c_wrap_init :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cleanup" c_wrap_cleanup :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cleanup_final" c_wrap_cleanup_final :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_crypto_disable_init" c_wrap_crypto_disable_init :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_disable_atexit" c_wrap_disable_atexit :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_get_fips_mode" c_wrap_get_fips_mode :: FunPtr () -> Ptr S2nFipsMode -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_stack_traces_enabled_set" c_wrap_stack_traces_enabled_set :: FunPtr () -> CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_calculate_stacktrace" c_wrap_calculate_stacktrace :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_free_stacktrace" c_wrap_free_stacktrace :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_get_stacktrace" c_wrap_get_stacktrace :: FunPtr () -> Ptr S2nStacktrace -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_new" c_wrap_config_new :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr S2nConfig)+foreign import ccall safe "s2n_wrap_config_new_minimal" c_wrap_config_new_minimal :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr S2nConfig)+foreign import ccall safe "s2n_wrap_config_free" c_wrap_config_free :: FunPtr () -> Ptr S2nConfig -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_free_dhparams" c_wrap_config_free_dhparams :: FunPtr () -> Ptr S2nConfig -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_free_cert_chain_and_key" c_wrap_config_free_cert_chain_and_key :: FunPtr () -> Ptr S2nConfig -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_wall_clock" c_wrap_config_set_wall_clock :: FunPtr () -> Ptr S2nConfig -> S2nClockTimeNanoseconds -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_monotonic_clock" c_wrap_config_set_monotonic_clock :: FunPtr () -> Ptr S2nConfig -> S2nClockTimeNanoseconds -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_cache_store_callback" c_wrap_config_set_cache_store_callback :: FunPtr () -> Ptr S2nConfig -> S2nCacheStoreCallback -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_cache_retrieve_callback" c_wrap_config_set_cache_retrieve_callback :: FunPtr () -> Ptr S2nConfig -> S2nCacheRetrieveCallback -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_cache_delete_callback" c_wrap_config_set_cache_delete_callback :: FunPtr () -> Ptr S2nConfig -> S2nCacheDeleteCallback -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_mem_set_callbacks" c_wrap_mem_set_callbacks :: FunPtr () -> S2nMemInitCallback -> S2nMemCleanupCallback -> S2nMemMallocCallback -> S2nMemFreeCallback -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_rand_set_callbacks" c_wrap_rand_set_callbacks :: FunPtr () -> S2nRandInitCallback -> S2nRandCleanupCallback -> S2nRandSeedCallback -> S2nRandMixCallback -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_chain_and_key_new" c_wrap_cert_chain_and_key_new :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr S2nCertChainAndKey)+foreign import ccall safe "s2n_wrap_cert_chain_and_key_load_pem" c_wrap_cert_chain_and_key_load_pem :: FunPtr () -> Ptr S2nCertChainAndKey -> CString -> CString -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_chain_and_key_load_pem_bytes" c_wrap_cert_chain_and_key_load_pem_bytes :: FunPtr () -> Ptr S2nCertChainAndKey -> Ptr Word8 -> Word32 -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_chain_and_key_load_public_pem_bytes" c_wrap_cert_chain_and_key_load_public_pem_bytes :: FunPtr () -> Ptr S2nCertChainAndKey -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_chain_and_key_free" c_wrap_cert_chain_and_key_free :: FunPtr () -> Ptr S2nCertChainAndKey -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_chain_and_key_set_ctx" c_wrap_cert_chain_and_key_set_ctx :: FunPtr () -> Ptr S2nCertChainAndKey -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_chain_and_key_get_private_key" c_wrap_cert_chain_and_key_get_private_key :: FunPtr () -> Ptr S2nCertChainAndKey -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr S2nCertPrivateKey)+foreign import ccall safe "s2n_wrap_cert_chain_and_key_set_ocsp_data" c_wrap_cert_chain_and_key_set_ocsp_data :: FunPtr () -> Ptr S2nCertChainAndKey -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_chain_and_key_set_sct_list" c_wrap_cert_chain_and_key_set_sct_list :: FunPtr () -> Ptr S2nCertChainAndKey -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_cert_tiebreak_callback" c_wrap_config_set_cert_tiebreak_callback :: FunPtr () -> Ptr S2nConfig -> S2nCertTiebreakCallback -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_add_cert_chain_and_key" c_wrap_config_add_cert_chain_and_key :: FunPtr () -> Ptr S2nConfig -> CString -> CString -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_add_cert_chain_and_key_to_store" c_wrap_config_add_cert_chain_and_key_to_store :: FunPtr () -> Ptr S2nConfig -> Ptr S2nCertChainAndKey -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_cert_chain_and_key_defaults" c_wrap_config_set_cert_chain_and_key_defaults :: FunPtr () -> Ptr S2nConfig -> Ptr (Ptr S2nCertChainAndKey) -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_verification_ca_location" c_wrap_config_set_verification_ca_location :: FunPtr () -> Ptr S2nConfig -> CString -> CString -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_add_pem_to_trust_store" c_wrap_config_add_pem_to_trust_store :: FunPtr () -> Ptr S2nConfig -> CString -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_wipe_trust_store" c_wrap_config_wipe_trust_store :: FunPtr () -> Ptr S2nConfig -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_load_system_certs" c_wrap_config_load_system_certs :: FunPtr () -> Ptr S2nConfig -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_cert_authorities_from_trust_store" c_wrap_config_set_cert_authorities_from_trust_store :: FunPtr () -> Ptr S2nConfig -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_verify_after_sign" c_wrap_config_set_verify_after_sign :: FunPtr () -> Ptr S2nConfig -> S2nVerifyAfterSign -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_check_stapled_ocsp_response" c_wrap_config_set_check_stapled_ocsp_response :: FunPtr () -> Ptr S2nConfig -> CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_disable_x509_time_verification" c_wrap_config_disable_x509_time_verification :: FunPtr () -> Ptr S2nConfig -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_disable_x509_verification" c_wrap_config_disable_x509_verification :: FunPtr () -> Ptr S2nConfig -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_max_cert_chain_depth" c_wrap_config_set_max_cert_chain_depth :: FunPtr () -> Ptr S2nConfig -> Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_verify_host_callback" c_wrap_config_set_verify_host_callback :: FunPtr () -> Ptr S2nConfig -> S2nVerifyHostFn -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_add_dhparams" c_wrap_config_add_dhparams :: FunPtr () -> Ptr S2nConfig -> CString -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_cipher_preferences" c_wrap_config_set_cipher_preferences :: FunPtr () -> Ptr S2nConfig -> CString -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_append_protocol_preference" c_wrap_config_append_protocol_preference :: FunPtr () -> Ptr S2nConfig -> Ptr Word8 -> Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_protocol_preferences" c_wrap_config_set_protocol_preferences :: FunPtr () -> Ptr S2nConfig -> Ptr CString -> CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_status_request_type" c_wrap_config_set_status_request_type :: FunPtr () -> Ptr S2nConfig -> S2nStatusRequestType -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_ct_support_level" c_wrap_config_set_ct_support_level :: FunPtr () -> Ptr S2nConfig -> S2nCtSupportLevel -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_alert_behavior" c_wrap_config_set_alert_behavior :: FunPtr () -> Ptr S2nConfig -> S2nAlertBehavior -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_extension_data" c_wrap_config_set_extension_data :: FunPtr () -> Ptr S2nConfig -> S2nTlsExtensionType -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_send_max_fragment_length" c_wrap_config_send_max_fragment_length :: FunPtr () -> Ptr S2nConfig -> S2nMaxFragLen -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_accept_max_fragment_length" c_wrap_config_accept_max_fragment_length :: FunPtr () -> Ptr S2nConfig -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_session_state_lifetime" c_wrap_config_set_session_state_lifetime :: FunPtr () -> Ptr S2nConfig -> Word64 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_session_tickets_onoff" c_wrap_config_set_session_tickets_onoff :: FunPtr () -> Ptr S2nConfig -> Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_session_cache_onoff" c_wrap_config_set_session_cache_onoff :: FunPtr () -> Ptr S2nConfig -> Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_ticket_encrypt_decrypt_key_lifetime" c_wrap_config_set_ticket_encrypt_decrypt_key_lifetime :: FunPtr () -> Ptr S2nConfig -> Word64 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_ticket_decrypt_key_lifetime" c_wrap_config_set_ticket_decrypt_key_lifetime :: FunPtr () -> Ptr S2nConfig -> Word64 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_add_ticket_crypto_key" c_wrap_config_add_ticket_crypto_key :: FunPtr () -> Ptr S2nConfig -> Ptr Word8 -> Word32 -> Ptr Word8 -> Word32 -> Word64 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_require_ticket_forward_secrecy" c_wrap_config_require_ticket_forward_secrecy :: FunPtr () -> Ptr S2nConfig -> CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_send_buffer_size" c_wrap_config_set_send_buffer_size :: FunPtr () -> Ptr S2nConfig -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_recv_multi_record" c_wrap_config_set_recv_multi_record :: FunPtr () -> Ptr S2nConfig -> CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_ctx" c_wrap_config_set_ctx :: FunPtr () -> Ptr S2nConfig -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_get_ctx" c_wrap_config_get_ctx :: FunPtr () -> Ptr S2nConfig -> Ptr (Ptr ()) -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_client_hello_cb" c_wrap_config_set_client_hello_cb :: FunPtr () -> Ptr S2nConfig -> S2nClientHelloFn -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_client_hello_cb_mode" c_wrap_config_set_client_hello_cb_mode :: FunPtr () -> Ptr S2nConfig -> S2nClientHelloCbMode -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_max_blinding_delay" c_wrap_config_set_max_blinding_delay :: FunPtr () -> Ptr S2nConfig -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_get_client_auth_type" c_wrap_config_get_client_auth_type :: FunPtr () -> Ptr S2nConfig -> Ptr S2nCertAuthType -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_client_auth_type" c_wrap_config_set_client_auth_type :: FunPtr () -> Ptr S2nConfig -> S2nCertAuthType -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_initial_ticket_count" c_wrap_config_set_initial_ticket_count :: FunPtr () -> Ptr S2nConfig -> Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_psk_mode" c_wrap_config_set_psk_mode :: FunPtr () -> Ptr S2nConfig -> S2nPskMode -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_psk_selection_callback" c_wrap_config_set_psk_selection_callback :: FunPtr () -> Ptr S2nConfig -> S2nPskSelectionCallback -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_async_pkey_callback" c_wrap_config_set_async_pkey_callback :: FunPtr () -> Ptr S2nConfig -> S2nAsyncPkeyFn -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_async_pkey_validation_mode" c_wrap_config_set_async_pkey_validation_mode :: FunPtr () -> Ptr S2nConfig -> S2nAsyncPkeyValidationMode -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_session_ticket_cb" c_wrap_config_set_session_ticket_cb :: FunPtr () -> Ptr S2nConfig -> S2nSessionTicketFn -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_key_log_cb" c_wrap_config_set_key_log_cb :: FunPtr () -> Ptr S2nConfig -> S2nKeyLogFn -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_enable_cert_req_dss_legacy_compat" c_wrap_config_enable_cert_req_dss_legacy_compat :: FunPtr () -> Ptr S2nConfig -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_server_max_early_data_size" c_wrap_config_set_server_max_early_data_size :: FunPtr () -> Ptr S2nConfig -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_early_data_cb" c_wrap_config_set_early_data_cb :: FunPtr () -> Ptr S2nConfig -> S2nEarlyDataCb -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_get_supported_groups" c_wrap_config_get_supported_groups :: FunPtr () -> Ptr S2nConfig -> Ptr Word16 -> Word16 -> Ptr Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_config_set_serialization_version" c_wrap_config_set_serialization_version :: FunPtr () -> Ptr S2nConfig -> S2nSerializationVersion -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_new" c_wrap_connection_new :: FunPtr () -> S2nMode -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr S2nConnection)+foreign import ccall safe "s2n_wrap_connection_set_config" c_wrap_connection_set_config :: FunPtr () -> Ptr S2nConnection -> Ptr S2nConfig -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_ctx" c_wrap_connection_set_ctx :: FunPtr () -> Ptr S2nConnection -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_ctx" c_wrap_connection_get_ctx :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr ())+foreign import ccall safe "s2n_wrap_client_hello_cb_done" c_wrap_client_hello_cb_done :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_server_name_extension_used" c_wrap_connection_server_name_extension_used :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_client_hello" c_wrap_connection_get_client_hello :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr S2nClientHello)+foreign import ccall safe "s2n_wrap_client_hello_parse_message" c_wrap_client_hello_parse_message :: FunPtr () -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr S2nClientHello)+foreign import ccall safe "s2n_wrap_client_hello_free" c_wrap_client_hello_free :: FunPtr () -> Ptr (Ptr S2nClientHello) -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_client_hello_get_raw_message_length" c_wrap_client_hello_get_raw_message_length :: FunPtr () -> Ptr S2nClientHello -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CSsize+foreign import ccall safe "s2n_wrap_client_hello_get_raw_message" c_wrap_client_hello_get_raw_message :: FunPtr () -> Ptr S2nClientHello -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CSsize+foreign import ccall safe "s2n_wrap_client_hello_get_cipher_suites_length" c_wrap_client_hello_get_cipher_suites_length :: FunPtr () -> Ptr S2nClientHello -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CSsize+foreign import ccall safe "s2n_wrap_client_hello_get_cipher_suites" c_wrap_client_hello_get_cipher_suites :: FunPtr () -> Ptr S2nClientHello -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CSsize+foreign import ccall safe "s2n_wrap_client_hello_get_extensions_length" c_wrap_client_hello_get_extensions_length :: FunPtr () -> Ptr S2nClientHello -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CSsize+foreign import ccall safe "s2n_wrap_client_hello_get_extensions" c_wrap_client_hello_get_extensions :: FunPtr () -> Ptr S2nClientHello -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CSsize+foreign import ccall safe "s2n_wrap_client_hello_get_extension_length" c_wrap_client_hello_get_extension_length :: FunPtr () -> Ptr S2nClientHello -> S2nTlsExtensionType -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CSsize+foreign import ccall safe "s2n_wrap_client_hello_get_extension_by_id" c_wrap_client_hello_get_extension_by_id :: FunPtr () -> Ptr S2nClientHello -> S2nTlsExtensionType -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CSsize+foreign import ccall safe "s2n_wrap_client_hello_has_extension" c_wrap_client_hello_has_extension :: FunPtr () -> Ptr S2nClientHello -> Word16 -> Ptr CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_client_hello_get_session_id_length" c_wrap_client_hello_get_session_id_length :: FunPtr () -> Ptr S2nClientHello -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_client_hello_get_session_id" c_wrap_client_hello_get_session_id :: FunPtr () -> Ptr S2nClientHello -> Ptr Word8 -> Ptr Word32 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_client_hello_get_compression_methods_length" c_wrap_client_hello_get_compression_methods_length :: FunPtr () -> Ptr S2nClientHello -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_client_hello_get_compression_methods" c_wrap_client_hello_get_compression_methods :: FunPtr () -> Ptr S2nClientHello -> Ptr Word8 -> Word32 -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_client_hello_get_legacy_protocol_version" c_wrap_client_hello_get_legacy_protocol_version :: FunPtr () -> Ptr S2nClientHello -> Ptr Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_client_hello_get_supported_groups" c_wrap_client_hello_get_supported_groups :: FunPtr () -> Ptr S2nClientHello -> Ptr Word16 -> Word16 -> Ptr Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_client_hello_get_server_name_length" c_wrap_client_hello_get_server_name_length :: FunPtr () -> Ptr S2nClientHello -> Ptr Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_client_hello_get_server_name" c_wrap_client_hello_get_server_name :: FunPtr () -> Ptr S2nClientHello -> Ptr Word8 -> Word16 -> Ptr Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_client_hello_get_legacy_record_version" c_wrap_client_hello_get_legacy_record_version :: FunPtr () -> Ptr S2nClientHello -> Ptr Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_fd" c_wrap_connection_set_fd :: FunPtr () -> Ptr S2nConnection -> CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_read_fd" c_wrap_connection_set_read_fd :: FunPtr () -> Ptr S2nConnection -> CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_write_fd" c_wrap_connection_set_write_fd :: FunPtr () -> Ptr S2nConnection -> CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_read_fd" c_wrap_connection_get_read_fd :: FunPtr () -> Ptr S2nConnection -> Ptr CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_write_fd" c_wrap_connection_get_write_fd :: FunPtr () -> Ptr S2nConnection -> Ptr CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_use_corked_io" c_wrap_connection_use_corked_io :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_recv_ctx" c_wrap_connection_set_recv_ctx :: FunPtr () -> Ptr S2nConnection -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_send_ctx" c_wrap_connection_set_send_ctx :: FunPtr () -> Ptr S2nConnection -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_recv_cb" c_wrap_connection_set_recv_cb :: FunPtr () -> Ptr S2nConnection -> S2nRecvFn -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_send_cb" c_wrap_connection_set_send_cb :: FunPtr () -> Ptr S2nConnection -> S2nSendFn -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_prefer_throughput" c_wrap_connection_prefer_throughput :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_prefer_low_latency" c_wrap_connection_prefer_low_latency :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_recv_buffering" c_wrap_connection_set_recv_buffering :: FunPtr () -> Ptr S2nConnection -> CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_dynamic_buffers" c_wrap_connection_set_dynamic_buffers :: FunPtr () -> Ptr S2nConnection -> CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_dynamic_record_threshold" c_wrap_connection_set_dynamic_record_threshold :: FunPtr () -> Ptr S2nConnection -> Word32 -> Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_verify_host_callback" c_wrap_connection_set_verify_host_callback :: FunPtr () -> Ptr S2nConnection -> S2nVerifyHostFn -> Ptr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_blinding" c_wrap_connection_set_blinding :: FunPtr () -> Ptr S2nConnection -> S2nBlinding -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_cipher_preferences" c_wrap_connection_set_cipher_preferences :: FunPtr () -> Ptr S2nConnection -> CString -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_request_key_update" c_wrap_connection_request_key_update :: FunPtr () -> Ptr S2nConnection -> S2nPeerKeyUpdate -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_append_protocol_preference" c_wrap_connection_append_protocol_preference :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_protocol_preferences" c_wrap_connection_set_protocol_preferences :: FunPtr () -> Ptr S2nConnection -> Ptr CString -> CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_set_server_name" c_wrap_set_server_name :: FunPtr () -> Ptr S2nConnection -> CString -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_get_server_name" c_wrap_get_server_name :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CString+foreign import ccall safe "s2n_wrap_get_application_protocol" c_wrap_get_application_protocol :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CString+foreign import ccall safe "s2n_wrap_connection_get_ocsp_response" c_wrap_connection_get_ocsp_response :: FunPtr () -> Ptr S2nConnection -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr Word8)+foreign import ccall safe "s2n_wrap_connection_get_sct_list" c_wrap_connection_get_sct_list :: FunPtr () -> Ptr S2nConnection -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr Word8)+foreign import ccall safe "s2n_wrap_negotiate" c_wrap_negotiate :: FunPtr () -> Ptr S2nConnection -> Ptr S2nBlockedStatus -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_send" c_wrap_send :: FunPtr () -> Ptr S2nConnection -> Ptr () -> CSsize -> Ptr S2nBlockedStatus -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CSsize+foreign import ccall safe "s2n_wrap_recv" c_wrap_recv :: FunPtr () -> Ptr S2nConnection -> Ptr () -> CSsize -> Ptr S2nBlockedStatus -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CSsize+foreign import ccall safe "s2n_wrap_connection_free_handshake" c_wrap_connection_free_handshake :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_release_buffers" c_wrap_connection_release_buffers :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_wipe" c_wrap_connection_wipe :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_free" c_wrap_connection_free :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_shutdown" c_wrap_shutdown :: FunPtr () -> Ptr S2nConnection -> Ptr S2nBlockedStatus -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_shutdown_send" c_wrap_shutdown_send :: FunPtr () -> Ptr S2nConnection -> Ptr S2nBlockedStatus -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_client_auth_type" c_wrap_connection_get_client_auth_type :: FunPtr () -> Ptr S2nConnection -> Ptr S2nCertAuthType -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_client_auth_type" c_wrap_connection_set_client_auth_type :: FunPtr () -> Ptr S2nConnection -> S2nCertAuthType -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_client_cert_chain" c_wrap_connection_get_client_cert_chain :: FunPtr () -> Ptr S2nConnection -> Ptr (Ptr Word8) -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_client_cert_used" c_wrap_connection_client_cert_used :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_add_new_tickets_to_send" c_wrap_connection_add_new_tickets_to_send :: FunPtr () -> Ptr S2nConnection -> Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_tickets_sent" c_wrap_connection_get_tickets_sent :: FunPtr () -> Ptr S2nConnection -> Ptr Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_server_keying_material_lifetime" c_wrap_connection_set_server_keying_material_lifetime :: FunPtr () -> Ptr S2nConnection -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_session_ticket_get_data_len" c_wrap_session_ticket_get_data_len :: FunPtr () -> Ptr S2nSessionTicket -> Ptr CSize -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_session_ticket_get_data" c_wrap_session_ticket_get_data :: FunPtr () -> Ptr S2nSessionTicket -> CSize -> Ptr Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_session_ticket_get_lifetime" c_wrap_session_ticket_get_lifetime :: FunPtr () -> Ptr S2nSessionTicket -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_session" c_wrap_connection_set_session :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> CSize -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_session" c_wrap_connection_get_session :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> CSize -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_session_ticket_lifetime_hint" c_wrap_connection_get_session_ticket_lifetime_hint :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_session_length" c_wrap_connection_get_session_length :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_session_id_length" c_wrap_connection_get_session_id_length :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_session_id" c_wrap_connection_get_session_id :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> CSize -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_is_session_resumed" c_wrap_connection_is_session_resumed :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_is_ocsp_stapled" c_wrap_connection_is_ocsp_stapled :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_selected_signature_algorithm" c_wrap_connection_get_selected_signature_algorithm :: FunPtr () -> Ptr S2nConnection -> Ptr S2nTlsSignatureAlgorithm -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_selected_digest_algorithm" c_wrap_connection_get_selected_digest_algorithm :: FunPtr () -> Ptr S2nConnection -> Ptr S2nTlsHashAlgorithm -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_selected_client_cert_signature_algorithm" c_wrap_connection_get_selected_client_cert_signature_algorithm :: FunPtr () -> Ptr S2nConnection -> Ptr S2nTlsSignatureAlgorithm -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_selected_client_cert_digest_algorithm" c_wrap_connection_get_selected_client_cert_digest_algorithm :: FunPtr () -> Ptr S2nConnection -> Ptr S2nTlsHashAlgorithm -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_selected_cert" c_wrap_connection_get_selected_cert :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr S2nCertChainAndKey)+foreign import ccall safe "s2n_wrap_cert_chain_get_length" c_wrap_cert_chain_get_length :: FunPtr () -> Ptr S2nCertChainAndKey -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_chain_get_cert" c_wrap_cert_chain_get_cert :: FunPtr () -> Ptr S2nCertChainAndKey -> Ptr (Ptr S2nCert) -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_get_der" c_wrap_cert_get_der :: FunPtr () -> Ptr S2nCert -> Ptr (Ptr Word8) -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_peer_cert_chain" c_wrap_connection_get_peer_cert_chain :: FunPtr () -> Ptr S2nConnection -> Ptr S2nCertChainAndKey -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_get_x509_extension_value_length" c_wrap_cert_get_x509_extension_value_length :: FunPtr () -> Ptr S2nCert -> Ptr Word8 -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_get_x509_extension_value" c_wrap_cert_get_x509_extension_value :: FunPtr () -> Ptr S2nCert -> Ptr Word8 -> Ptr Word8 -> Ptr Word32 -> Ptr CInt -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_get_utf8_string_from_extension_data_length" c_wrap_cert_get_utf8_string_from_extension_data_length :: FunPtr () -> Ptr Word8 -> Word32 -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_cert_get_utf8_string_from_extension_data" c_wrap_cert_get_utf8_string_from_extension_data :: FunPtr () -> Ptr Word8 -> Word32 -> Ptr Word8 -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_external_psk_new" c_wrap_external_psk_new :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr S2nPsk)+foreign import ccall safe "s2n_wrap_psk_free" c_wrap_psk_free :: FunPtr () -> Ptr (Ptr S2nPsk) -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_psk_set_identity" c_wrap_psk_set_identity :: FunPtr () -> Ptr S2nPsk -> Ptr Word8 -> Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_psk_set_secret" c_wrap_psk_set_secret :: FunPtr () -> Ptr S2nPsk -> Ptr Word8 -> Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_psk_set_hmac" c_wrap_psk_set_hmac :: FunPtr () -> Ptr S2nPsk -> S2nPskHmac -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_append_psk" c_wrap_connection_append_psk :: FunPtr () -> Ptr S2nConnection -> Ptr S2nPsk -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_psk_mode" c_wrap_connection_set_psk_mode :: FunPtr () -> Ptr S2nConnection -> S2nPskMode -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_negotiated_psk_identity_length" c_wrap_connection_get_negotiated_psk_identity_length :: FunPtr () -> Ptr S2nConnection -> Ptr Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_negotiated_psk_identity" c_wrap_connection_get_negotiated_psk_identity :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_offered_psk_new" c_wrap_offered_psk_new :: FunPtr () -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO (Ptr S2nOfferedPsk)+foreign import ccall safe "s2n_wrap_offered_psk_free" c_wrap_offered_psk_free :: FunPtr () -> Ptr (Ptr S2nOfferedPsk) -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_offered_psk_get_identity" c_wrap_offered_psk_get_identity :: FunPtr () -> Ptr S2nOfferedPsk -> Ptr (Ptr Word8) -> Ptr Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_offered_psk_list_next" c_wrap_offered_psk_list_next :: FunPtr () -> Ptr S2nOfferedPskList -> Ptr S2nOfferedPsk -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_offered_psk_list_reread" c_wrap_offered_psk_list_reread :: FunPtr () -> Ptr S2nOfferedPskList -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_offered_psk_list_choose_psk" c_wrap_offered_psk_list_choose_psk :: FunPtr () -> Ptr S2nOfferedPskList -> Ptr S2nOfferedPsk -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_psk_configure_early_data" c_wrap_psk_configure_early_data :: FunPtr () -> Ptr S2nPsk -> Word32 -> Word8 -> Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_psk_set_application_protocol" c_wrap_psk_set_application_protocol :: FunPtr () -> Ptr S2nPsk -> Ptr Word8 -> Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_psk_set_early_data_context" c_wrap_psk_set_early_data_context :: FunPtr () -> Ptr S2nPsk -> Ptr Word8 -> Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_client_protocol_version" c_wrap_connection_get_client_protocol_version :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_server_protocol_version" c_wrap_connection_get_server_protocol_version :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_actual_protocol_version" c_wrap_connection_get_actual_protocol_version :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_client_hello_version" c_wrap_connection_get_client_hello_version :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_cipher" c_wrap_connection_get_cipher :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CString+foreign import ccall safe "s2n_wrap_connection_get_certificate_match" c_wrap_connection_get_certificate_match :: FunPtr () -> Ptr S2nConnection -> Ptr S2nCertSniMatch -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_master_secret" c_wrap_connection_get_master_secret :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> CSize -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_tls_exporter" c_wrap_connection_tls_exporter :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> Word32 -> Ptr Word8 -> Word32 -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_cipher_iana_value" c_wrap_connection_get_cipher_iana_value :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> Ptr Word8 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_is_valid_for_cipher_preferences" c_wrap_connection_is_valid_for_cipher_preferences :: FunPtr () -> Ptr S2nConnection -> CString -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_curve" c_wrap_connection_get_curve :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CString+foreign import ccall safe "s2n_wrap_connection_get_kem_name" c_wrap_connection_get_kem_name :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CString+foreign import ccall safe "s2n_wrap_connection_get_kem_group_name" c_wrap_connection_get_kem_group_name :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CString+foreign import ccall safe "s2n_wrap_connection_get_key_exchange_group" c_wrap_connection_get_key_exchange_group :: FunPtr () -> Ptr S2nConnection -> Ptr CString -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_alert" c_wrap_connection_get_alert :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_handshake_type_name" c_wrap_connection_get_handshake_type_name :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CString+foreign import ccall safe "s2n_wrap_connection_get_last_message_name" c_wrap_connection_get_last_message_name :: FunPtr () -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CString+foreign import ccall safe "s2n_wrap_async_pkey_op_perform" c_wrap_async_pkey_op_perform :: FunPtr () -> Ptr S2nAsyncPkeyOp -> Ptr S2nCertPrivateKey -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_async_pkey_op_apply" c_wrap_async_pkey_op_apply :: FunPtr () -> Ptr S2nAsyncPkeyOp -> Ptr S2nConnection -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_async_pkey_op_free" c_wrap_async_pkey_op_free :: FunPtr () -> Ptr S2nAsyncPkeyOp -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_async_pkey_op_get_op_type" c_wrap_async_pkey_op_get_op_type :: FunPtr () -> Ptr S2nAsyncPkeyOp -> Ptr S2nAsyncPkeyOpType -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_async_pkey_op_get_input_size" c_wrap_async_pkey_op_get_input_size :: FunPtr () -> Ptr S2nAsyncPkeyOp -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_async_pkey_op_get_input" c_wrap_async_pkey_op_get_input :: FunPtr () -> Ptr S2nAsyncPkeyOp -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_async_pkey_op_set_output" c_wrap_async_pkey_op_set_output :: FunPtr () -> Ptr S2nAsyncPkeyOp -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_server_max_early_data_size" c_wrap_connection_set_server_max_early_data_size :: FunPtr () -> Ptr S2nConnection -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_set_server_early_data_context" c_wrap_connection_set_server_early_data_context :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_early_data_status" c_wrap_connection_get_early_data_status :: FunPtr () -> Ptr S2nConnection -> Ptr S2nEarlyDataStatus -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_remaining_early_data_size" c_wrap_connection_get_remaining_early_data_size :: FunPtr () -> Ptr S2nConnection -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_get_max_early_data_size" c_wrap_connection_get_max_early_data_size :: FunPtr () -> Ptr S2nConnection -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_send_early_data" c_wrap_send_early_data :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> CSsize -> Ptr CSsize -> Ptr S2nBlockedStatus -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_recv_early_data" c_wrap_recv_early_data :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> CSsize -> Ptr CSsize -> Ptr S2nBlockedStatus -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_offered_early_data_get_context_length" c_wrap_offered_early_data_get_context_length :: FunPtr () -> Ptr S2nOfferedEarlyData -> Ptr Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_offered_early_data_get_context" c_wrap_offered_early_data_get_context :: FunPtr () -> Ptr S2nOfferedEarlyData -> Ptr Word8 -> Word16 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_offered_early_data_reject" c_wrap_offered_early_data_reject :: FunPtr () -> Ptr S2nOfferedEarlyData -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_offered_early_data_accept" c_wrap_offered_early_data_accept :: FunPtr () -> Ptr S2nOfferedEarlyData -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_serialization_length" c_wrap_connection_serialization_length :: FunPtr () -> Ptr S2nConnection -> Ptr Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_serialize" c_wrap_connection_serialize :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt+foreign import ccall safe "s2n_wrap_connection_deserialize" c_wrap_connection_deserialize :: FunPtr () -> Ptr S2nConnection -> Ptr Word8 -> Word32 -> Ptr S2nErrorFuncs -> Ptr S2nError -> IO CInt
+ src/S2nTls/Ffi/Types.hs view
@@ -0,0 +1,1134 @@+{-# LANGUAGE PatternSynonyms #-}++{- |+Module : S2nTls.Ffi.Types+Description : Core types for s2n-tls FFI bindings+Copyright : (c) 2026 Daniel Goertzen+License : Apache-2.0+Maintainer : daniel.goertzen@gmail.com+Stability : experimental+Portability : non-portable (requires s2n-tls C library)++This module defines the core types used by the s2n-tls FFI bindings,+including the 'S2nTlsFfi' record that contains all FFI function pointers.+-}+module S2nTls.Ffi.Types (+ -- * Error Types+ S2nError (..),+ S2nErrorFuncs (..),+ MissingSymbol (..),++ -- * Opaque Types+ S2nConfig,+ S2nConnection,+ S2nCertChainAndKey,+ S2nCert,+ S2nClientHello,+ S2nPsk,+ S2nOfferedPsk,+ S2nOfferedPskList,+ S2nSessionTicket,+ S2nAsyncPkeyOp,+ S2nCertPrivateKey,+ S2nOfferedEarlyData,+ S2nStacktrace,++ -- * Return Codes+ pattern S2nSuccess,+ pattern S2nFailure,+ pattern S2nCallbackBlocked,++ -- * TLS Versions+ pattern S2nMinimumSupportedTlsRecordMajorVersion,+ pattern S2nMaximumSupportedTlsRecordMajorVersion,+ pattern S2nSslv2,+ pattern S2nSslv3,+ pattern S2nTls10,+ pattern S2nTls11,+ pattern S2nTls12,+ pattern S2nTls13,+ pattern S2nUnknownProtocolVersion,++ -- * Enumerations+ S2nErrorType (..),+ pattern S2nErrTOk,+ pattern S2nErrTIo,+ pattern S2nErrTClosed,+ pattern S2nErrTBlocked,+ pattern S2nErrTAlert,+ pattern S2nErrTProto,+ pattern S2nErrTInternal,+ pattern S2nErrTUsage,+ S2nMode (..),+ pattern S2nServer,+ pattern S2nClient,+ S2nBlinding (..),+ pattern S2nBuiltInBlinding,+ pattern S2nSelfServiceBlinding,+ S2nBlockedStatus (..),+ pattern S2nNotBlocked,+ pattern S2nBlockedOnRead,+ pattern S2nBlockedOnWrite,+ pattern S2nBlockedOnApplicationInput,+ pattern S2nBlockedOnEarlyData,+ S2nCertAuthType (..),+ pattern S2nCertAuthNone,+ pattern S2nCertAuthRequired,+ pattern S2nCertAuthOptional,+ S2nPskHmac (..),+ pattern S2nPskHmacSha256,+ pattern S2nPskHmacSha384,+ S2nPskMode (..),+ pattern S2nPskModeResumption,+ pattern S2nPskModeExternal,+ S2nEarlyDataStatus (..),+ pattern S2nEarlyDataStatusOk,+ pattern S2nEarlyDataStatusNotRequested,+ pattern S2nEarlyDataStatusRejected,+ pattern S2nEarlyDataStatusEnd,+ S2nAsyncPkeyOpType (..),+ pattern S2nAsyncDecrypt,+ pattern S2nAsyncSign,+ S2nAsyncPkeyValidationMode (..),+ pattern S2nAsyncPkeyValidationFast,+ pattern S2nAsyncPkeyValidationStrict,+ S2nSerializationVersion (..),+ pattern S2nSerializedConnNone,+ pattern S2nSerializedConnV1,+ S2nTlsExtensionType (..),+ pattern S2nExtensionServerName,+ pattern S2nExtensionMaxFragLen,+ pattern S2nExtensionOcspStapling,+ pattern S2nExtensionSupportedGroups,+ pattern S2nExtensionEcPointFormats,+ pattern S2nExtensionSignatureAlgorithms,+ pattern S2nExtensionAlpn,+ pattern S2nExtensionCertificateTransparency,+ pattern S2nExtensionRenegotiationInfo,+ S2nMaxFragLen (..),+ pattern S2nTlsMaxFragLen512,+ pattern S2nTlsMaxFragLen1024,+ pattern S2nTlsMaxFragLen2048,+ pattern S2nTlsMaxFragLen4096,+ S2nFipsMode (..),+ pattern S2nFipsModeDisabled,+ pattern S2nFipsModeEnabled,+ S2nStatusRequestType (..),+ pattern S2nStatusRequestNone,+ pattern S2nStatusRequestOcsp,+ S2nCtSupportLevel (..),+ pattern S2nCtSupportNone,+ pattern S2nCtSupportRequest,+ S2nAlertBehavior (..),+ pattern S2nAlertFailOnWarnings,+ pattern S2nAlertIgnoreWarnings,+ S2nClientHelloCbMode (..),+ pattern S2nClientHelloCbBlocking,+ pattern S2nClientHelloCbNonblocking,+ S2nTlsSignatureAlgorithm (..),+ pattern S2nTlsSignatureAnonymous,+ pattern S2nTlsSignatureRsa,+ pattern S2nTlsSignatureEcdsa,+ pattern S2nTlsSignatureRsaPssRsae,+ pattern S2nTlsSignatureRsaPssPss,+ S2nTlsHashAlgorithm (..),+ pattern S2nTlsHashNone,+ pattern S2nTlsHashMd5,+ pattern S2nTlsHashSha1,+ pattern S2nTlsHashSha224,+ pattern S2nTlsHashSha256,+ pattern S2nTlsHashSha384,+ pattern S2nTlsHashSha512,+ S2nCertSniMatch (..),+ pattern S2nCertSniMatchNotApplicable,+ pattern S2nCertSniMatched,+ pattern S2nCertSniNoMatchFound,+ S2nPeerKeyUpdate (..),+ pattern S2nKeyUpdateNotRequested,+ pattern S2nKeyUpdateRequested,+ S2nVerifyAfterSign (..),+ pattern S2nVerifyAfterSignDisabled,+ pattern S2nVerifyAfterSignEnabled,++ -- * Callback Types+ S2nClockTimeNanoseconds,+ S2nRecvFn,+ S2nSendFn,+ S2nCacheStoreCallback,+ S2nCacheRetrieveCallback,+ S2nCacheDeleteCallback,+ S2nMemInitCallback,+ S2nMemCleanupCallback,+ S2nMemMallocCallback,+ S2nMemFreeCallback,+ S2nRandInitCallback,+ S2nRandCleanupCallback,+ S2nRandSeedCallback,+ S2nRandMixCallback,+ S2nClientHelloFn,+ S2nCertTiebreakCallback,+ S2nVerifyHostFn,+ S2nPskSelectionCallback,+ S2nAsyncPkeyFn,+ S2nSessionTicketFn,+ S2nKeyLogFn,+ S2nEarlyDataCb,++ -- * FFI Record+ S2nTlsFfi (..),+) where++import Control.Exception (Exception)+import Data.Word (Word16, Word32, Word64, Word8)+import Foreign.C.String (CString, castCharToCChar, peekCString)+import Foreign.C.Types (CBool (..), CInt (..), CLong (..), CSize (..))+import Foreign.Marshal.Array (pokeArray0)+import Foreign.Ptr (FunPtr, Ptr, plusPtr)+import Foreign.Storable (Storable (..))+import System.Posix.Types (CSsize (..))++--------------------------------------------------------------------------------+-- Error Types+--------------------------------------------------------------------------------++{- | Exception thrown when calling an s2n function that wasn't loaded.+The string contains the name of the missing symbol.+-}+newtype MissingSymbol = MissingSymbol String+ deriving (Show, Eq)++instance Exception MissingSymbol++{- | Full error information captured from an s2n function call.+Contains the error code plus the string representations.+-}+data S2nError = S2nError+ { s2nErrorCode :: !CInt+ , s2nErrorDebugMessage :: String+ -- ^ Result of s2n_strerror_debug()+ }+ deriving (Show, Eq)++instance Exception S2nError++{- | Struct of error function pointers, passed to C wrappers.+Loaded first during initialization - fatal if any are missing.+-}+data S2nErrorFuncs = S2nErrorFuncs+ { errnoLocation :: !(FunPtr (IO (Ptr CInt)))+ , strerrorDebug :: !(FunPtr (CInt -> CString -> IO CString))+ , errorGetType :: !(FunPtr (CInt -> IO S2nErrorType))+ }++instance Storable S2nErrorFuncs where+ sizeOf _ = 3 * sizeOf (undefined :: FunPtr ())+ alignment _ = alignment (undefined :: FunPtr ())+ peek ptr = do+ a <- peekByteOff ptr 0+ b <- peekByteOff ptr (sizeOf (undefined :: FunPtr ()))+ c <- peekByteOff ptr (2 * sizeOf (undefined :: FunPtr ()))+ pure $ S2nErrorFuncs a b c+ poke ptr (S2nErrorFuncs a b c) = do+ pokeByteOff ptr 0 a+ pokeByteOff ptr (sizeOf (undefined :: FunPtr ())) b+ pokeByteOff ptr (2 * sizeOf (undefined :: FunPtr ())) c++-- | Size of the debug string buffer in S2nError (must match C S2N_ERROR_DEBUG_STRING_SIZE)+s2nErrorDebugStringSize :: Int+s2nErrorDebugStringSize = 256++{- | Output struct populated by C wrappers on error.+Contains error code and an owned copy of the debug string.+-}+instance Storable S2nError where+ sizeOf _ = sizeOf (undefined :: CInt) + s2nErrorDebugStringSize+ alignment _ = alignment (undefined :: CInt)+ peek ptr = do+ code <- peekByteOff ptr 0+ -- Read the fixed-size debug string buffer+ let strPtr = ptr `plusPtr` sizeOf (undefined :: CInt)+ dbgStr <- peekCString strPtr+ pure $ S2nError code dbgStr+ poke ptr (S2nError code dbgStr) = do+ pokeByteOff ptr 0 code+ -- Write the debug string to the fixed-size buffer+ let strPtr = ptr `plusPtr` sizeOf (undefined :: CInt)+ -- Zero out the buffer first, then copy the string+ _ <- memset strPtr 0 (fromIntegral s2nErrorDebugStringSize)+ let truncated = take (s2nErrorDebugStringSize - 1) dbgStr+ pokeArray0 0 strPtr (map castCharToCChar truncated)++-- | Foreign import for memset+foreign import ccall unsafe "string.h memset"+ memset :: Ptr a -> CInt -> CSize -> IO (Ptr a)++--------------------------------------------------------------------------------+-- Opaque Types+--------------------------------------------------------------------------------++-- | Opaque type representing an s2n configuration.+data S2nConfig++-- | Opaque type representing an s2n connection.+data S2nConnection++-- | Opaque type representing a certificate chain and private key pair.+data S2nCertChainAndKey++-- | Opaque type representing a certificate.+data S2nCert++-- | Opaque type representing a parsed ClientHello message.+data S2nClientHello++-- | Opaque type representing a pre-shared key.+data S2nPsk++-- | Opaque type representing an offered PSK during negotiation.+data S2nOfferedPsk++-- | Opaque type representing a list of offered PSKs.+data S2nOfferedPskList++-- | Opaque type representing a session ticket.+data S2nSessionTicket++-- | Opaque type representing an async private key operation.+data S2nAsyncPkeyOp++-- | Opaque type representing a certificate's private key.+data S2nCertPrivateKey++-- | Opaque type representing offered early data.+data S2nOfferedEarlyData++-- | Opaque type representing a stack trace.+data S2nStacktrace++--------------------------------------------------------------------------------+-- Return Codes+--------------------------------------------------------------------------------++-- | Function completed successfully.+pattern S2nSuccess :: CInt+pattern S2nSuccess = 0++-- | Function encountered an error.+pattern S2nFailure :: CInt+pattern S2nFailure = -1++-- | Callback was blocked and needs to be retried.+pattern S2nCallbackBlocked :: CInt+pattern S2nCallbackBlocked = -2++--------------------------------------------------------------------------------+-- TLS Versions+--------------------------------------------------------------------------------++-- | Minimum supported TLS record major version.+pattern S2nMinimumSupportedTlsRecordMajorVersion :: Word8+pattern S2nMinimumSupportedTlsRecordMajorVersion = 2++-- | Maximum supported TLS record major version.+pattern S2nMaximumSupportedTlsRecordMajorVersion :: Word8+pattern S2nMaximumSupportedTlsRecordMajorVersion = 3++-- | SSL version 2 (deprecated, insecure).+pattern S2nSslv2 :: CInt+pattern S2nSslv2 = 20++-- | SSL version 3 (deprecated, insecure).+pattern S2nSslv3 :: CInt+pattern S2nSslv3 = 30++-- | TLS version 1.0.+pattern S2nTls10 :: CInt+pattern S2nTls10 = 31++-- | TLS version 1.1.+pattern S2nTls11 :: CInt+pattern S2nTls11 = 32++-- | TLS version 1.2.+pattern S2nTls12 :: CInt+pattern S2nTls12 = 33++-- | TLS version 1.3.+pattern S2nTls13 :: CInt+pattern S2nTls13 = 34++-- | Unknown or unrecognized protocol version.+pattern S2nUnknownProtocolVersion :: CInt+pattern S2nUnknownProtocolVersion = 0++--------------------------------------------------------------------------------+-- Enumerations+--------------------------------------------------------------------------------++-- | Type of error returned by s2n functions.+newtype S2nErrorType = S2nErrorType CInt+ deriving (Eq, Ord, Show, Storable)++-- | No error occurred.+pattern S2nErrTOk :: S2nErrorType+pattern S2nErrTOk = S2nErrorType 0++-- | I\/O error (check errno).+pattern S2nErrTIo :: S2nErrorType+pattern S2nErrTIo = S2nErrorType 1++-- | Connection was closed.+pattern S2nErrTClosed :: S2nErrorType+pattern S2nErrTClosed = S2nErrorType 2++-- | Operation blocked (retry needed).+pattern S2nErrTBlocked :: S2nErrorType+pattern S2nErrTBlocked = S2nErrorType 3++-- | TLS alert received.+pattern S2nErrTAlert :: S2nErrorType+pattern S2nErrTAlert = S2nErrorType 4++-- | Protocol error.+pattern S2nErrTProto :: S2nErrorType+pattern S2nErrTProto = S2nErrorType 5++-- | Internal library error.+pattern S2nErrTInternal :: S2nErrorType+pattern S2nErrTInternal = S2nErrorType 6++-- | Incorrect API usage.+pattern S2nErrTUsage :: S2nErrorType+pattern S2nErrTUsage = S2nErrorType 7++-- | TLS connection mode (server or client).+newtype S2nMode = S2nMode CInt+ deriving (Eq, Ord, Show, Storable)++-- | Server mode.+pattern S2nServer :: S2nMode+pattern S2nServer = S2nMode 0++-- | Client mode.+pattern S2nClient :: S2nMode+pattern S2nClient = S2nMode 1++-- | Blinding mode for timing attack mitigation.+newtype S2nBlinding = S2nBlinding CInt+ deriving (Eq, Ord, Show, Storable)++-- | s2n handles blinding automatically.+pattern S2nBuiltInBlinding :: S2nBlinding+pattern S2nBuiltInBlinding = S2nBlinding 0++-- | Application handles blinding delays.+pattern S2nSelfServiceBlinding :: S2nBlinding+pattern S2nSelfServiceBlinding = S2nBlinding 1++-- | Status indicating why an operation was blocked.+newtype S2nBlockedStatus = S2nBlockedStatus CInt+ deriving (Eq, Ord, Show, Storable)++-- | Operation completed successfully.+pattern S2nNotBlocked :: S2nBlockedStatus+pattern S2nNotBlocked = S2nBlockedStatus 0++-- | Blocked waiting for data to read.+pattern S2nBlockedOnRead :: S2nBlockedStatus+pattern S2nBlockedOnRead = S2nBlockedStatus 1++-- | Blocked waiting to write data.+pattern S2nBlockedOnWrite :: S2nBlockedStatus+pattern S2nBlockedOnWrite = S2nBlockedStatus 2++-- | Blocked waiting for application input.+pattern S2nBlockedOnApplicationInput :: S2nBlockedStatus+pattern S2nBlockedOnApplicationInput = S2nBlockedStatus 3++-- | Blocked on early data processing.+pattern S2nBlockedOnEarlyData :: S2nBlockedStatus+pattern S2nBlockedOnEarlyData = S2nBlockedStatus 4++-- | Client certificate authentication mode.+newtype S2nCertAuthType = S2nCertAuthType CInt+ deriving (Eq, Ord, Show, Storable)++-- | No client authentication.+pattern S2nCertAuthNone :: S2nCertAuthType+pattern S2nCertAuthNone = S2nCertAuthType 0++-- | Client certificate required.+pattern S2nCertAuthRequired :: S2nCertAuthType+pattern S2nCertAuthRequired = S2nCertAuthType 1++-- | Client certificate optional.+pattern S2nCertAuthOptional :: S2nCertAuthType+pattern S2nCertAuthOptional = S2nCertAuthType 2++-- | HMAC algorithm for pre-shared keys.+newtype S2nPskHmac = S2nPskHmac CInt+ deriving (Eq, Ord, Show, Storable)++-- | HMAC-SHA256 for PSK.+pattern S2nPskHmacSha256 :: S2nPskHmac+pattern S2nPskHmacSha256 = S2nPskHmac 0++-- | HMAC-SHA384 for PSK.+pattern S2nPskHmacSha384 :: S2nPskHmac+pattern S2nPskHmacSha384 = S2nPskHmac 1++-- | Pre-shared key mode.+newtype S2nPskMode = S2nPskMode CInt+ deriving (Eq, Ord, Show, Storable)++-- | PSK for session resumption.+pattern S2nPskModeResumption :: S2nPskMode+pattern S2nPskModeResumption = S2nPskMode 0++-- | External\/out-of-band PSK.+pattern S2nPskModeExternal :: S2nPskMode+pattern S2nPskModeExternal = S2nPskMode 1++-- | Status of TLS 1.3 early data (0-RTT).+newtype S2nEarlyDataStatus = S2nEarlyDataStatus CInt+ deriving (Eq, Ord, Show, Storable)++-- | Early data accepted.+pattern S2nEarlyDataStatusOk :: S2nEarlyDataStatus+pattern S2nEarlyDataStatusOk = S2nEarlyDataStatus 0++-- | Early data not requested.+pattern S2nEarlyDataStatusNotRequested :: S2nEarlyDataStatus+pattern S2nEarlyDataStatusNotRequested = S2nEarlyDataStatus 1++-- | Early data rejected.+pattern S2nEarlyDataStatusRejected :: S2nEarlyDataStatus+pattern S2nEarlyDataStatusRejected = S2nEarlyDataStatus 2++-- | Early data processing complete.+pattern S2nEarlyDataStatusEnd :: S2nEarlyDataStatus+pattern S2nEarlyDataStatusEnd = S2nEarlyDataStatus 3++-- | Type of async private key operation.+newtype S2nAsyncPkeyOpType = S2nAsyncPkeyOpType CInt+ deriving (Eq, Ord, Show, Storable)++-- | Decryption operation.+pattern S2nAsyncDecrypt :: S2nAsyncPkeyOpType+pattern S2nAsyncDecrypt = S2nAsyncPkeyOpType 0++-- | Signing operation.+pattern S2nAsyncSign :: S2nAsyncPkeyOpType+pattern S2nAsyncSign = S2nAsyncPkeyOpType 1++-- | Validation mode for async private key operations.+newtype S2nAsyncPkeyValidationMode = S2nAsyncPkeyValidationMode CInt+ deriving (Eq, Ord, Show, Storable)++-- | Fast validation (less strict).+pattern S2nAsyncPkeyValidationFast :: S2nAsyncPkeyValidationMode+pattern S2nAsyncPkeyValidationFast = S2nAsyncPkeyValidationMode 0++-- | Strict validation.+pattern S2nAsyncPkeyValidationStrict :: S2nAsyncPkeyValidationMode+pattern S2nAsyncPkeyValidationStrict = S2nAsyncPkeyValidationMode 1++-- | Connection serialization format version.+newtype S2nSerializationVersion = S2nSerializationVersion CInt+ deriving (Eq, Ord, Show, Storable)++-- | No serialization.+pattern S2nSerializedConnNone :: S2nSerializationVersion+pattern S2nSerializedConnNone = S2nSerializationVersion 0++-- | Serialization format version 1.+pattern S2nSerializedConnV1 :: S2nSerializationVersion+pattern S2nSerializedConnV1 = S2nSerializationVersion 1++-- | TLS extension type identifier.+newtype S2nTlsExtensionType = S2nTlsExtensionType CInt+ deriving (Eq, Ord, Show, Storable)++-- | Server Name Indication (SNI) extension.+pattern S2nExtensionServerName :: S2nTlsExtensionType+pattern S2nExtensionServerName = S2nTlsExtensionType 0++-- | Maximum fragment length extension.+pattern S2nExtensionMaxFragLen :: S2nTlsExtensionType+pattern S2nExtensionMaxFragLen = S2nTlsExtensionType 1++-- | OCSP stapling extension.+pattern S2nExtensionOcspStapling :: S2nTlsExtensionType+pattern S2nExtensionOcspStapling = S2nTlsExtensionType 5++-- | Supported groups (elliptic curves) extension.+pattern S2nExtensionSupportedGroups :: S2nTlsExtensionType+pattern S2nExtensionSupportedGroups = S2nTlsExtensionType 10++-- | EC point formats extension.+pattern S2nExtensionEcPointFormats :: S2nTlsExtensionType+pattern S2nExtensionEcPointFormats = S2nTlsExtensionType 11++-- | Signature algorithms extension.+pattern S2nExtensionSignatureAlgorithms :: S2nTlsExtensionType+pattern S2nExtensionSignatureAlgorithms = S2nTlsExtensionType 13++-- | Application-Layer Protocol Negotiation (ALPN) extension.+pattern S2nExtensionAlpn :: S2nTlsExtensionType+pattern S2nExtensionAlpn = S2nTlsExtensionType 16++-- | Certificate Transparency extension.+pattern S2nExtensionCertificateTransparency :: S2nTlsExtensionType+pattern S2nExtensionCertificateTransparency = S2nTlsExtensionType 18++-- | Renegotiation info extension.+pattern S2nExtensionRenegotiationInfo :: S2nTlsExtensionType+pattern S2nExtensionRenegotiationInfo = S2nTlsExtensionType 65281++-- | Maximum TLS fragment length.+newtype S2nMaxFragLen = S2nMaxFragLen CInt+ deriving (Eq, Ord, Show, Storable)++-- | Maximum fragment length of 512 bytes.+pattern S2nTlsMaxFragLen512 :: S2nMaxFragLen+pattern S2nTlsMaxFragLen512 = S2nMaxFragLen 1++-- | Maximum fragment length of 1024 bytes.+pattern S2nTlsMaxFragLen1024 :: S2nMaxFragLen+pattern S2nTlsMaxFragLen1024 = S2nMaxFragLen 2++-- | Maximum fragment length of 2048 bytes.+pattern S2nTlsMaxFragLen2048 :: S2nMaxFragLen+pattern S2nTlsMaxFragLen2048 = S2nMaxFragLen 3++-- | Maximum fragment length of 4096 bytes.+pattern S2nTlsMaxFragLen4096 :: S2nMaxFragLen+pattern S2nTlsMaxFragLen4096 = S2nMaxFragLen 4++-- | FIPS mode status.+newtype S2nFipsMode = S2nFipsMode CInt+ deriving (Eq, Ord, Show, Storable)++-- | FIPS mode disabled.+pattern S2nFipsModeDisabled :: S2nFipsMode+pattern S2nFipsModeDisabled = S2nFipsMode 0++-- | FIPS mode enabled.+pattern S2nFipsModeEnabled :: S2nFipsMode+pattern S2nFipsModeEnabled = S2nFipsMode 1++-- | OCSP status request type.+newtype S2nStatusRequestType = S2nStatusRequestType CInt+ deriving (Eq, Ord, Show, Storable)++-- | No status request.+pattern S2nStatusRequestNone :: S2nStatusRequestType+pattern S2nStatusRequestNone = S2nStatusRequestType 0++-- | Request OCSP status.+pattern S2nStatusRequestOcsp :: S2nStatusRequestType+pattern S2nStatusRequestOcsp = S2nStatusRequestType 1++-- | Certificate Transparency support level.+newtype S2nCtSupportLevel = S2nCtSupportLevel CInt+ deriving (Eq, Ord, Show, Storable)++-- | No Certificate Transparency support.+pattern S2nCtSupportNone :: S2nCtSupportLevel+pattern S2nCtSupportNone = S2nCtSupportLevel 0++-- | Request Certificate Transparency.+pattern S2nCtSupportRequest :: S2nCtSupportLevel+pattern S2nCtSupportRequest = S2nCtSupportLevel 1++-- | TLS alert behavior on warnings.+newtype S2nAlertBehavior = S2nAlertBehavior CInt+ deriving (Eq, Ord, Show, Storable)++-- | Fail on warning alerts.+pattern S2nAlertFailOnWarnings :: S2nAlertBehavior+pattern S2nAlertFailOnWarnings = S2nAlertBehavior 0++-- | Ignore warning alerts.+pattern S2nAlertIgnoreWarnings :: S2nAlertBehavior+pattern S2nAlertIgnoreWarnings = S2nAlertBehavior 1++-- | Client hello callback mode.+newtype S2nClientHelloCbMode = S2nClientHelloCbMode CInt+ deriving (Eq, Ord, Show, Storable)++-- | Blocking callback mode.+pattern S2nClientHelloCbBlocking :: S2nClientHelloCbMode+pattern S2nClientHelloCbBlocking = S2nClientHelloCbMode 0++-- | Non-blocking callback mode.+pattern S2nClientHelloCbNonblocking :: S2nClientHelloCbMode+pattern S2nClientHelloCbNonblocking = S2nClientHelloCbMode 1++-- | TLS signature algorithm.+newtype S2nTlsSignatureAlgorithm = S2nTlsSignatureAlgorithm CInt+ deriving (Eq, Ord, Show, Storable)++-- | Anonymous (no signature).+pattern S2nTlsSignatureAnonymous :: S2nTlsSignatureAlgorithm+pattern S2nTlsSignatureAnonymous = S2nTlsSignatureAlgorithm 0++-- | RSA signature.+pattern S2nTlsSignatureRsa :: S2nTlsSignatureAlgorithm+pattern S2nTlsSignatureRsa = S2nTlsSignatureAlgorithm 1++-- | ECDSA signature.+pattern S2nTlsSignatureEcdsa :: S2nTlsSignatureAlgorithm+pattern S2nTlsSignatureEcdsa = S2nTlsSignatureAlgorithm 3++-- | RSA-PSS with RSAE key.+pattern S2nTlsSignatureRsaPssRsae :: S2nTlsSignatureAlgorithm+pattern S2nTlsSignatureRsaPssRsae = S2nTlsSignatureAlgorithm 4++-- | RSA-PSS with PSS key.+pattern S2nTlsSignatureRsaPssPss :: S2nTlsSignatureAlgorithm+pattern S2nTlsSignatureRsaPssPss = S2nTlsSignatureAlgorithm 5++-- | TLS hash algorithm.+newtype S2nTlsHashAlgorithm = S2nTlsHashAlgorithm CInt+ deriving (Eq, Ord, Show, Storable)++-- | No hash algorithm.+pattern S2nTlsHashNone :: S2nTlsHashAlgorithm+pattern S2nTlsHashNone = S2nTlsHashAlgorithm 0++-- | MD5 hash (deprecated).+pattern S2nTlsHashMd5 :: S2nTlsHashAlgorithm+pattern S2nTlsHashMd5 = S2nTlsHashAlgorithm 1++-- | SHA-1 hash (deprecated).+pattern S2nTlsHashSha1 :: S2nTlsHashAlgorithm+pattern S2nTlsHashSha1 = S2nTlsHashAlgorithm 2++-- | SHA-224 hash.+pattern S2nTlsHashSha224 :: S2nTlsHashAlgorithm+pattern S2nTlsHashSha224 = S2nTlsHashAlgorithm 3++-- | SHA-256 hash.+pattern S2nTlsHashSha256 :: S2nTlsHashAlgorithm+pattern S2nTlsHashSha256 = S2nTlsHashAlgorithm 4++-- | SHA-384 hash.+pattern S2nTlsHashSha384 :: S2nTlsHashAlgorithm+pattern S2nTlsHashSha384 = S2nTlsHashAlgorithm 5++-- | SHA-512 hash.+pattern S2nTlsHashSha512 :: S2nTlsHashAlgorithm+pattern S2nTlsHashSha512 = S2nTlsHashAlgorithm 6++-- | Certificate SNI match result.+newtype S2nCertSniMatch = S2nCertSniMatch CInt+ deriving (Eq, Ord, Show, Storable)++-- | SNI matching not applicable.+pattern S2nCertSniMatchNotApplicable :: S2nCertSniMatch+pattern S2nCertSniMatchNotApplicable = S2nCertSniMatch 0++-- | Certificate matches SNI.+pattern S2nCertSniMatched :: S2nCertSniMatch+pattern S2nCertSniMatched = S2nCertSniMatch 1++-- | No matching certificate found.+pattern S2nCertSniNoMatchFound :: S2nCertSniMatch+pattern S2nCertSniNoMatchFound = S2nCertSniMatch 2++-- | Peer key update request type.+newtype S2nPeerKeyUpdate = S2nPeerKeyUpdate CInt+ deriving (Eq, Ord, Show, Storable)++-- | Key update not requested.+pattern S2nKeyUpdateNotRequested :: S2nPeerKeyUpdate+pattern S2nKeyUpdateNotRequested = S2nPeerKeyUpdate 0++-- | Key update requested.+pattern S2nKeyUpdateRequested :: S2nPeerKeyUpdate+pattern S2nKeyUpdateRequested = S2nPeerKeyUpdate 1++-- | Verify-after-sign mode for signatures.+newtype S2nVerifyAfterSign = S2nVerifyAfterSign CInt+ deriving (Eq, Ord, Show, Storable)++-- | Verification after signing disabled.+pattern S2nVerifyAfterSignDisabled :: S2nVerifyAfterSign+pattern S2nVerifyAfterSignDisabled = S2nVerifyAfterSign 0++-- | Verification after signing enabled.+pattern S2nVerifyAfterSignEnabled :: S2nVerifyAfterSign+pattern S2nVerifyAfterSignEnabled = S2nVerifyAfterSign 1++--------------------------------------------------------------------------------+-- Callback Types+--------------------------------------------------------------------------------++-- | Clock callback: returns current time in nanoseconds.+type S2nClockTimeNanoseconds = FunPtr (Ptr () -> Ptr Word64 -> IO CInt)++-- | Receive callback for custom I/O.+type S2nRecvFn = FunPtr (Ptr () -> Ptr Word8 -> Word32 -> IO CInt)++-- | Send callback for custom I/O.+type S2nSendFn = FunPtr (Ptr () -> Ptr Word8 -> Word32 -> IO CInt)++-- | Cache store callback.+type S2nCacheStoreCallback = FunPtr (Ptr S2nConnection -> Ptr () -> Word64 -> Ptr Word8 -> Word64 -> Ptr Word8 -> Word64 -> IO CInt)++-- | Cache retrieve callback.+type S2nCacheRetrieveCallback = FunPtr (Ptr S2nConnection -> Ptr () -> Ptr Word8 -> Word64 -> Ptr Word8 -> Ptr Word64 -> IO CInt)++-- | Cache delete callback.+type S2nCacheDeleteCallback = FunPtr (Ptr S2nConnection -> Ptr () -> Ptr Word8 -> Word64 -> IO CInt)++-- | Memory initialization callback.+type S2nMemInitCallback = FunPtr (IO CInt)++-- | Memory cleanup callback.+type S2nMemCleanupCallback = FunPtr (IO CInt)++-- | Memory allocation callback.+type S2nMemMallocCallback = FunPtr (Ptr (Ptr ()) -> Word32 -> Word32 -> IO CInt)++-- | Memory free callback.+type S2nMemFreeCallback = FunPtr (Ptr () -> Word32 -> IO CInt)++-- | Random initialization callback.+type S2nRandInitCallback = FunPtr (IO CInt)++-- | Random cleanup callback.+type S2nRandCleanupCallback = FunPtr (IO CInt)++-- | Random seed callback.+type S2nRandSeedCallback = FunPtr (Ptr () -> Word32 -> IO CInt)++-- | Random mix callback.+type S2nRandMixCallback = FunPtr (Ptr () -> Word32 -> IO CInt)++-- | Client hello callback.+type S2nClientHelloFn = FunPtr (Ptr S2nConnection -> Ptr () -> IO CInt)++-- | Certificate tiebreak callback.+type S2nCertTiebreakCallback = FunPtr (Ptr S2nCertChainAndKey -> Ptr S2nCertChainAndKey -> Word8 -> Ptr (Ptr S2nCertChainAndKey) -> IO CInt)++-- | Verify host callback.+type S2nVerifyHostFn = FunPtr (CString -> CSize -> Ptr () -> IO Word8)++-- | PSK selection callback.+type S2nPskSelectionCallback = FunPtr (Ptr S2nConnection -> Ptr () -> Ptr S2nOfferedPskList -> IO CInt)++-- | Async private key callback.+type S2nAsyncPkeyFn = FunPtr (Ptr S2nConnection -> Ptr S2nAsyncPkeyOp -> IO CInt)++-- | Session ticket callback.+type S2nSessionTicketFn = FunPtr (Ptr S2nConnection -> Ptr () -> Ptr S2nSessionTicket -> IO CInt)++-- | Key log callback (for debugging).+type S2nKeyLogFn = FunPtr (Ptr () -> Ptr S2nConnection -> Ptr Word8 -> CSize -> IO CInt)++-- | Early data callback.+type S2nEarlyDataCb = FunPtr (Ptr S2nConnection -> Ptr S2nOfferedEarlyData -> IO CInt)++--------------------------------------------------------------------------------+-- S2nTlsFfi Record+--------------------------------------------------------------------------------++{- | A record containing all FFI bindings to the s2n-tls library.++This record is populated by 'S2nTls.Ffi.withS2nTlsFfi' with the 'S2nTls.Ffi.Library'+parameter specifying either 'S2nTls.Ffi.Linked' or 'S2nTls.Ffi.Dynamic' loading.+-}+data S2nTlsFfi = S2nTlsFfi+ { missingSymbols :: [String]+ -- ^ List of symbol names that couldn't be loaded.+ -- Calling functions for these symbols will throw 'MissingSymbol'.+ , s2n_init :: IO (Either S2nError CInt)+ -- ^ __Initialization & Cleanup__+ , s2n_cleanup :: IO (Either S2nError CInt)+ , s2n_cleanup_final :: IO (Either S2nError CInt)+ , s2n_crypto_disable_init :: IO (Either S2nError CInt)+ , s2n_disable_atexit :: IO (Either S2nError CInt)+ , s2n_get_openssl_version :: IO CLong+ , s2n_get_fips_mode :: Ptr S2nFipsMode -> IO (Either S2nError CInt)+ , s2n_errno_location :: IO (Ptr CInt)+ -- ^ __Error Handling__+ , s2n_error_get_type :: CInt -> IO S2nErrorType+ , s2n_strerror :: CInt -> CString -> IO CString+ , s2n_strerror_debug :: CInt -> CString -> IO CString+ , s2n_strerror_name :: CInt -> IO CString+ , s2n_strerror_source :: CInt -> IO CString+ , s2n_stack_traces_enabled :: IO CBool+ -- ^ __Stack Traces__+ , s2n_stack_traces_enabled_set :: CInt -> IO (Either S2nError CInt)+ , s2n_calculate_stacktrace :: IO (Either S2nError CInt)+ , s2n_free_stacktrace :: IO (Either S2nError CInt)+ , s2n_get_stacktrace :: Ptr S2nStacktrace -> IO (Either S2nError CInt)+ , s2n_config_new :: IO (Either S2nError (Ptr S2nConfig))+ -- ^ __Config Management__+ , s2n_config_new_minimal :: IO (Either S2nError (Ptr S2nConfig))+ , s2n_config_free :: Ptr S2nConfig -> IO (Either S2nError CInt)+ , s2n_config_free_dhparams :: Ptr S2nConfig -> IO (Either S2nError CInt)+ , s2n_config_free_cert_chain_and_key :: Ptr S2nConfig -> IO (Either S2nError CInt)+ , s2n_config_set_wall_clock :: Ptr S2nConfig -> S2nClockTimeNanoseconds -> Ptr () -> IO (Either S2nError CInt)+ , s2n_config_set_monotonic_clock :: Ptr S2nConfig -> S2nClockTimeNanoseconds -> Ptr () -> IO (Either S2nError CInt)+ , s2n_config_set_cache_store_callback :: Ptr S2nConfig -> S2nCacheStoreCallback -> Ptr () -> IO (Either S2nError CInt)+ -- ^ __Cache Callbacks__+ , s2n_config_set_cache_retrieve_callback :: Ptr S2nConfig -> S2nCacheRetrieveCallback -> Ptr () -> IO (Either S2nError CInt)+ , s2n_config_set_cache_delete_callback :: Ptr S2nConfig -> S2nCacheDeleteCallback -> Ptr () -> IO (Either S2nError CInt)+ , s2n_mem_set_callbacks :: S2nMemInitCallback -> S2nMemCleanupCallback -> S2nMemMallocCallback -> S2nMemFreeCallback -> IO (Either S2nError CInt)+ -- ^ __Memory & Random Callbacks__+ , s2n_rand_set_callbacks :: S2nRandInitCallback -> S2nRandCleanupCallback -> S2nRandSeedCallback -> S2nRandMixCallback -> IO (Either S2nError CInt)+ , s2n_cert_chain_and_key_new :: IO (Either S2nError (Ptr S2nCertChainAndKey))+ -- ^ __Certificate Chain Management__+ , s2n_cert_chain_and_key_load_pem :: Ptr S2nCertChainAndKey -> CString -> CString -> IO (Either S2nError CInt)+ , s2n_cert_chain_and_key_load_pem_bytes :: Ptr S2nCertChainAndKey -> Ptr Word8 -> Word32 -> Ptr Word8 -> Word32 -> IO (Either S2nError CInt)+ , s2n_cert_chain_and_key_load_public_pem_bytes :: Ptr S2nCertChainAndKey -> Ptr Word8 -> Word32 -> IO (Either S2nError CInt)+ , s2n_cert_chain_and_key_free :: Ptr S2nCertChainAndKey -> IO (Either S2nError CInt)+ , s2n_cert_chain_and_key_set_ctx :: Ptr S2nCertChainAndKey -> Ptr () -> IO (Either S2nError CInt)+ , s2n_cert_chain_and_key_get_ctx :: Ptr S2nCertChainAndKey -> IO (Ptr ())+ , s2n_cert_chain_and_key_get_private_key :: Ptr S2nCertChainAndKey -> IO (Either S2nError (Ptr S2nCertPrivateKey))+ , s2n_cert_chain_and_key_set_ocsp_data :: Ptr S2nCertChainAndKey -> Ptr Word8 -> Word32 -> IO (Either S2nError CInt)+ , s2n_cert_chain_and_key_set_sct_list :: Ptr S2nCertChainAndKey -> Ptr Word8 -> Word32 -> IO (Either S2nError CInt)+ , s2n_config_set_cert_tiebreak_callback :: Ptr S2nConfig -> S2nCertTiebreakCallback -> IO (Either S2nError CInt)+ , s2n_config_add_cert_chain_and_key :: Ptr S2nConfig -> CString -> CString -> IO (Either S2nError CInt)+ , s2n_config_add_cert_chain_and_key_to_store :: Ptr S2nConfig -> Ptr S2nCertChainAndKey -> IO (Either S2nError CInt)+ , s2n_config_set_cert_chain_and_key_defaults :: Ptr S2nConfig -> Ptr (Ptr S2nCertChainAndKey) -> Word32 -> IO (Either S2nError CInt)+ , s2n_config_set_verification_ca_location :: Ptr S2nConfig -> CString -> CString -> IO (Either S2nError CInt)+ -- ^ __Trust Store__+ , s2n_config_add_pem_to_trust_store :: Ptr S2nConfig -> CString -> IO (Either S2nError CInt)+ , s2n_config_wipe_trust_store :: Ptr S2nConfig -> IO (Either S2nError CInt)+ , s2n_config_load_system_certs :: Ptr S2nConfig -> IO (Either S2nError CInt)+ , s2n_config_set_cert_authorities_from_trust_store :: Ptr S2nConfig -> IO (Either S2nError CInt)+ , s2n_config_set_verify_after_sign :: Ptr S2nConfig -> S2nVerifyAfterSign -> IO (Either S2nError CInt)+ -- ^ __Verification & Validation__+ , s2n_config_set_check_stapled_ocsp_response :: Ptr S2nConfig -> CInt -> IO (Either S2nError CInt)+ , s2n_config_disable_x509_time_verification :: Ptr S2nConfig -> IO (Either S2nError CInt)+ , -- , s2n_config_disable_x509_intent_verification :: Ptr S2nConfig -> IO (Either S2nError CInt)+ s2n_config_disable_x509_verification :: Ptr S2nConfig -> IO (Either S2nError CInt)+ , s2n_config_set_max_cert_chain_depth :: Ptr S2nConfig -> Word16 -> IO (Either S2nError CInt)+ , s2n_config_set_verify_host_callback :: Ptr S2nConfig -> S2nVerifyHostFn -> Ptr () -> IO (Either S2nError CInt)+ , s2n_config_add_dhparams :: Ptr S2nConfig -> CString -> IO (Either S2nError CInt)+ -- ^ __DH Parameters__+ , s2n_config_set_cipher_preferences :: Ptr S2nConfig -> CString -> IO (Either S2nError CInt)+ -- ^ __Security Policies & Preferences__+ , s2n_config_append_protocol_preference :: Ptr S2nConfig -> Ptr Word8 -> Word8 -> IO (Either S2nError CInt)+ , s2n_config_set_protocol_preferences :: Ptr S2nConfig -> Ptr CString -> CInt -> IO (Either S2nError CInt)+ , s2n_config_set_status_request_type :: Ptr S2nConfig -> S2nStatusRequestType -> IO (Either S2nError CInt)+ , s2n_config_set_ct_support_level :: Ptr S2nConfig -> S2nCtSupportLevel -> IO (Either S2nError CInt)+ , s2n_config_set_alert_behavior :: Ptr S2nConfig -> S2nAlertBehavior -> IO (Either S2nError CInt)+ , s2n_config_set_extension_data :: Ptr S2nConfig -> S2nTlsExtensionType -> Ptr Word8 -> Word32 -> IO (Either S2nError CInt)+ -- ^ __Extension Data__+ , s2n_config_send_max_fragment_length :: Ptr S2nConfig -> S2nMaxFragLen -> IO (Either S2nError CInt)+ , s2n_config_accept_max_fragment_length :: Ptr S2nConfig -> IO (Either S2nError CInt)+ , s2n_config_set_session_state_lifetime :: Ptr S2nConfig -> Word64 -> IO (Either S2nError CInt)+ -- ^ __Session & Ticket Configuration__+ , s2n_config_set_session_tickets_onoff :: Ptr S2nConfig -> Word8 -> IO (Either S2nError CInt)+ , s2n_config_set_session_cache_onoff :: Ptr S2nConfig -> Word8 -> IO (Either S2nError CInt)+ , s2n_config_set_ticket_encrypt_decrypt_key_lifetime :: Ptr S2nConfig -> Word64 -> IO (Either S2nError CInt)+ , s2n_config_set_ticket_decrypt_key_lifetime :: Ptr S2nConfig -> Word64 -> IO (Either S2nError CInt)+ , s2n_config_add_ticket_crypto_key :: Ptr S2nConfig -> Ptr Word8 -> Word32 -> Ptr Word8 -> Word32 -> Word64 -> IO (Either S2nError CInt)+ , s2n_config_require_ticket_forward_secrecy :: Ptr S2nConfig -> CInt -> IO (Either S2nError CInt)+ , s2n_config_set_send_buffer_size :: Ptr S2nConfig -> Word32 -> IO (Either S2nError CInt)+ -- ^ __Buffer & I\/O Configuration__+ , s2n_config_set_recv_multi_record :: Ptr S2nConfig -> CInt -> IO (Either S2nError CInt)+ , s2n_config_set_ctx :: Ptr S2nConfig -> Ptr () -> IO (Either S2nError CInt)+ -- ^ __Miscellaneous Config__+ , s2n_config_get_ctx :: Ptr S2nConfig -> Ptr (Ptr ()) -> IO (Either S2nError CInt)+ , s2n_config_set_client_hello_cb :: Ptr S2nConfig -> S2nClientHelloFn -> Ptr () -> IO (Either S2nError CInt)+ , s2n_config_set_client_hello_cb_mode :: Ptr S2nConfig -> S2nClientHelloCbMode -> IO (Either S2nError CInt)+ , s2n_config_set_max_blinding_delay :: Ptr S2nConfig -> Word32 -> IO (Either S2nError CInt)+ , s2n_config_get_client_auth_type :: Ptr S2nConfig -> Ptr S2nCertAuthType -> IO (Either S2nError CInt)+ , s2n_config_set_client_auth_type :: Ptr S2nConfig -> S2nCertAuthType -> IO (Either S2nError CInt)+ , s2n_config_set_initial_ticket_count :: Ptr S2nConfig -> Word8 -> IO (Either S2nError CInt)+ , s2n_config_set_psk_mode :: Ptr S2nConfig -> S2nPskMode -> IO (Either S2nError CInt)+ , s2n_config_set_psk_selection_callback :: Ptr S2nConfig -> S2nPskSelectionCallback -> Ptr () -> IO (Either S2nError CInt)+ , s2n_config_set_async_pkey_callback :: Ptr S2nConfig -> S2nAsyncPkeyFn -> IO (Either S2nError CInt)+ , s2n_config_set_async_pkey_validation_mode :: Ptr S2nConfig -> S2nAsyncPkeyValidationMode -> IO (Either S2nError CInt)+ , s2n_config_set_session_ticket_cb :: Ptr S2nConfig -> S2nSessionTicketFn -> Ptr () -> IO (Either S2nError CInt)+ , s2n_config_set_key_log_cb :: Ptr S2nConfig -> S2nKeyLogFn -> Ptr () -> IO (Either S2nError CInt)+ , s2n_config_enable_cert_req_dss_legacy_compat :: Ptr S2nConfig -> IO (Either S2nError CInt)+ , s2n_config_set_server_max_early_data_size :: Ptr S2nConfig -> Word32 -> IO (Either S2nError CInt)+ , s2n_config_set_early_data_cb :: Ptr S2nConfig -> S2nEarlyDataCb -> IO (Either S2nError CInt)+ , s2n_config_get_supported_groups :: Ptr S2nConfig -> Ptr Word16 -> Word16 -> Ptr Word16 -> IO (Either S2nError CInt)+ , s2n_config_set_serialization_version :: Ptr S2nConfig -> S2nSerializationVersion -> IO (Either S2nError CInt)+ , s2n_connection_new :: S2nMode -> IO (Either S2nError (Ptr S2nConnection))+ -- ^ __Connection Creation & Management__+ , s2n_connection_set_config :: Ptr S2nConnection -> Ptr S2nConfig -> IO (Either S2nError CInt)+ , s2n_connection_set_ctx :: Ptr S2nConnection -> Ptr () -> IO (Either S2nError CInt)+ , s2n_connection_get_ctx :: Ptr S2nConnection -> IO (Either S2nError (Ptr ()))+ , s2n_client_hello_cb_done :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_server_name_extension_used :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_get_client_hello :: Ptr S2nConnection -> IO (Either S2nError (Ptr S2nClientHello))+ -- ^ __Client Hello Access__+ , s2n_client_hello_parse_message :: Ptr Word8 -> Word32 -> IO (Either S2nError (Ptr S2nClientHello))+ , s2n_client_hello_free :: Ptr (Ptr S2nClientHello) -> IO (Either S2nError CInt)+ , s2n_client_hello_get_raw_message_length :: Ptr S2nClientHello -> IO (Either S2nError CSsize)+ , s2n_client_hello_get_raw_message :: Ptr S2nClientHello -> Ptr Word8 -> Word32 -> IO (Either S2nError CSsize)+ , s2n_client_hello_get_cipher_suites_length :: Ptr S2nClientHello -> IO (Either S2nError CSsize)+ , s2n_client_hello_get_cipher_suites :: Ptr S2nClientHello -> Ptr Word8 -> Word32 -> IO (Either S2nError CSsize)+ , s2n_client_hello_get_extensions_length :: Ptr S2nClientHello -> IO (Either S2nError CSsize)+ , s2n_client_hello_get_extensions :: Ptr S2nClientHello -> Ptr Word8 -> Word32 -> IO (Either S2nError CSsize)+ , s2n_client_hello_get_extension_length :: Ptr S2nClientHello -> S2nTlsExtensionType -> IO (Either S2nError CSsize)+ , s2n_client_hello_get_extension_by_id :: Ptr S2nClientHello -> S2nTlsExtensionType -> Ptr Word8 -> Word32 -> IO (Either S2nError CSsize)+ , s2n_client_hello_has_extension :: Ptr S2nClientHello -> Word16 -> Ptr CInt -> IO (Either S2nError CInt)+ , s2n_client_hello_get_session_id_length :: Ptr S2nClientHello -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_client_hello_get_session_id :: Ptr S2nClientHello -> Ptr Word8 -> Ptr Word32 -> Word32 -> IO (Either S2nError CInt)+ , s2n_client_hello_get_compression_methods_length :: Ptr S2nClientHello -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_client_hello_get_compression_methods :: Ptr S2nClientHello -> Ptr Word8 -> Word32 -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_client_hello_get_legacy_protocol_version :: Ptr S2nClientHello -> Ptr Word8 -> IO (Either S2nError CInt)+ , -- , s2n_client_hello_get_random :: Ptr S2nClientHello -> Ptr Word8 -> Word32 -> IO (Either S2nError CInt)+ s2n_client_hello_get_supported_groups :: Ptr S2nClientHello -> Ptr Word16 -> Word16 -> Ptr Word16 -> IO (Either S2nError CInt)+ , s2n_client_hello_get_server_name_length :: Ptr S2nClientHello -> Ptr Word16 -> IO (Either S2nError CInt)+ , s2n_client_hello_get_server_name :: Ptr S2nClientHello -> Ptr Word8 -> Word16 -> Ptr Word16 -> IO (Either S2nError CInt)+ , s2n_client_hello_get_legacy_record_version :: Ptr S2nClientHello -> Ptr Word8 -> IO (Either S2nError CInt)+ , s2n_connection_set_fd :: Ptr S2nConnection -> CInt -> IO (Either S2nError CInt)+ -- ^ __File Descriptor & I\/O__+ , s2n_connection_set_read_fd :: Ptr S2nConnection -> CInt -> IO (Either S2nError CInt)+ , s2n_connection_set_write_fd :: Ptr S2nConnection -> CInt -> IO (Either S2nError CInt)+ , s2n_connection_get_read_fd :: Ptr S2nConnection -> Ptr CInt -> IO (Either S2nError CInt)+ , s2n_connection_get_write_fd :: Ptr S2nConnection -> Ptr CInt -> IO (Either S2nError CInt)+ , s2n_connection_use_corked_io :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_set_recv_ctx :: Ptr S2nConnection -> Ptr () -> IO (Either S2nError CInt)+ , s2n_connection_set_send_ctx :: Ptr S2nConnection -> Ptr () -> IO (Either S2nError CInt)+ , s2n_connection_set_recv_cb :: Ptr S2nConnection -> S2nRecvFn -> IO (Either S2nError CInt)+ , s2n_connection_set_send_cb :: Ptr S2nConnection -> S2nSendFn -> IO (Either S2nError CInt)+ , s2n_connection_prefer_throughput :: Ptr S2nConnection -> IO (Either S2nError CInt)+ -- ^ __Connection Preferences__+ , s2n_connection_prefer_low_latency :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_set_recv_buffering :: Ptr S2nConnection -> CInt -> IO (Either S2nError CInt)+ , s2n_peek_buffered :: Ptr S2nConnection -> IO Word32+ , s2n_connection_set_dynamic_buffers :: Ptr S2nConnection -> CInt -> IO (Either S2nError CInt)+ , s2n_connection_set_dynamic_record_threshold :: Ptr S2nConnection -> Word32 -> Word16 -> IO (Either S2nError CInt)+ , s2n_connection_set_verify_host_callback :: Ptr S2nConnection -> S2nVerifyHostFn -> Ptr () -> IO (Either S2nError CInt)+ -- ^ __Host Verification__+ , s2n_connection_set_blinding :: Ptr S2nConnection -> S2nBlinding -> IO (Either S2nError CInt)+ -- ^ __Blinding & Security__+ , s2n_connection_get_delay :: Ptr S2nConnection -> IO Word64+ , s2n_connection_set_cipher_preferences :: Ptr S2nConnection -> CString -> IO (Either S2nError CInt)+ -- ^ __Cipher & Protocol Configuration__+ , s2n_connection_request_key_update :: Ptr S2nConnection -> S2nPeerKeyUpdate -> IO (Either S2nError CInt)+ , s2n_connection_append_protocol_preference :: Ptr S2nConnection -> Ptr Word8 -> Word8 -> IO (Either S2nError CInt)+ , s2n_connection_set_protocol_preferences :: Ptr S2nConnection -> Ptr CString -> CInt -> IO (Either S2nError CInt)+ , s2n_set_server_name :: Ptr S2nConnection -> CString -> IO (Either S2nError CInt)+ -- ^ __Server Name (SNI)__+ , s2n_get_server_name :: Ptr S2nConnection -> IO (Either S2nError CString)+ , s2n_get_application_protocol :: Ptr S2nConnection -> IO (Either S2nError CString)+ -- ^ __Application Protocol (ALPN)__+ , s2n_connection_get_ocsp_response :: Ptr S2nConnection -> Ptr Word32 -> IO (Either S2nError (Ptr Word8))+ -- ^ __OCSP & Certificate Transparency__+ , s2n_connection_get_sct_list :: Ptr S2nConnection -> Ptr Word32 -> IO (Either S2nError (Ptr Word8))+ , s2n_negotiate :: Ptr S2nConnection -> Ptr S2nBlockedStatus -> IO (Either S2nError CInt)+ -- ^ __Handshake & TLS Operations__+ , s2n_send :: Ptr S2nConnection -> Ptr () -> CSsize -> Ptr S2nBlockedStatus -> IO (Either S2nError CSsize)+ , s2n_recv :: Ptr S2nConnection -> Ptr () -> CSsize -> Ptr S2nBlockedStatus -> IO (Either S2nError CSsize)+ , s2n_peek :: Ptr S2nConnection -> IO Word32+ , s2n_connection_free_handshake :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_release_buffers :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_wipe :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_free :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_shutdown :: Ptr S2nConnection -> Ptr S2nBlockedStatus -> IO (Either S2nError CInt)+ , s2n_shutdown_send :: Ptr S2nConnection -> Ptr S2nBlockedStatus -> IO (Either S2nError CInt)+ , s2n_connection_get_client_auth_type :: Ptr S2nConnection -> Ptr S2nCertAuthType -> IO (Either S2nError CInt)+ -- ^ __Client Authentication__+ , s2n_connection_set_client_auth_type :: Ptr S2nConnection -> S2nCertAuthType -> IO (Either S2nError CInt)+ , s2n_connection_get_client_cert_chain :: Ptr S2nConnection -> Ptr (Ptr Word8) -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_connection_client_cert_used :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_add_new_tickets_to_send :: Ptr S2nConnection -> Word8 -> IO (Either S2nError CInt)+ -- ^ __Session Management__+ , s2n_connection_get_tickets_sent :: Ptr S2nConnection -> Ptr Word16 -> IO (Either S2nError CInt)+ , s2n_connection_set_server_keying_material_lifetime :: Ptr S2nConnection -> Word32 -> IO (Either S2nError CInt)+ , s2n_session_ticket_get_data_len :: Ptr S2nSessionTicket -> Ptr CSize -> IO (Either S2nError CInt)+ , s2n_session_ticket_get_data :: Ptr S2nSessionTicket -> CSize -> Ptr Word8 -> IO (Either S2nError CInt)+ , s2n_session_ticket_get_lifetime :: Ptr S2nSessionTicket -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_connection_set_session :: Ptr S2nConnection -> Ptr Word8 -> CSize -> IO (Either S2nError CInt)+ , s2n_connection_get_session :: Ptr S2nConnection -> Ptr Word8 -> CSize -> IO (Either S2nError CInt)+ , s2n_connection_get_session_ticket_lifetime_hint :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_get_session_length :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_get_session_id_length :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_get_session_id :: Ptr S2nConnection -> Ptr Word8 -> CSize -> IO (Either S2nError CInt)+ , s2n_connection_is_session_resumed :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_is_ocsp_stapled :: Ptr S2nConnection -> IO (Either S2nError CInt)+ -- ^ __Certificate Information__+ , s2n_connection_get_selected_signature_algorithm :: Ptr S2nConnection -> Ptr S2nTlsSignatureAlgorithm -> IO (Either S2nError CInt)+ , s2n_connection_get_selected_digest_algorithm :: Ptr S2nConnection -> Ptr S2nTlsHashAlgorithm -> IO (Either S2nError CInt)+ , s2n_connection_get_selected_client_cert_signature_algorithm :: Ptr S2nConnection -> Ptr S2nTlsSignatureAlgorithm -> IO (Either S2nError CInt)+ , s2n_connection_get_selected_client_cert_digest_algorithm :: Ptr S2nConnection -> Ptr S2nTlsHashAlgorithm -> IO (Either S2nError CInt)+ , -- , s2n_connection_get_signature_scheme :: Ptr S2nConnection -> Ptr CString -> IO (Either S2nError CInt)+ s2n_connection_get_selected_cert :: Ptr S2nConnection -> IO (Either S2nError (Ptr S2nCertChainAndKey))+ , s2n_cert_chain_get_length :: Ptr S2nCertChainAndKey -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_cert_chain_get_cert :: Ptr S2nCertChainAndKey -> Ptr (Ptr S2nCert) -> Word32 -> IO (Either S2nError CInt)+ , s2n_cert_get_der :: Ptr S2nCert -> Ptr (Ptr Word8) -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_connection_get_peer_cert_chain :: Ptr S2nConnection -> Ptr S2nCertChainAndKey -> IO (Either S2nError CInt)+ , s2n_cert_get_x509_extension_value_length :: Ptr S2nCert -> Ptr Word8 -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_cert_get_x509_extension_value :: Ptr S2nCert -> Ptr Word8 -> Ptr Word8 -> Ptr Word32 -> Ptr CInt -> IO (Either S2nError CInt)+ , s2n_cert_get_utf8_string_from_extension_data_length :: Ptr Word8 -> Word32 -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_cert_get_utf8_string_from_extension_data :: Ptr Word8 -> Word32 -> Ptr Word8 -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_external_psk_new :: IO (Either S2nError (Ptr S2nPsk))+ -- ^ __Pre-Shared Keys (PSK)__+ , s2n_psk_free :: Ptr (Ptr S2nPsk) -> IO (Either S2nError CInt)+ , s2n_psk_set_identity :: Ptr S2nPsk -> Ptr Word8 -> Word16 -> IO (Either S2nError CInt)+ , s2n_psk_set_secret :: Ptr S2nPsk -> Ptr Word8 -> Word16 -> IO (Either S2nError CInt)+ , s2n_psk_set_hmac :: Ptr S2nPsk -> S2nPskHmac -> IO (Either S2nError CInt)+ , s2n_connection_append_psk :: Ptr S2nConnection -> Ptr S2nPsk -> IO (Either S2nError CInt)+ , s2n_connection_set_psk_mode :: Ptr S2nConnection -> S2nPskMode -> IO (Either S2nError CInt)+ , s2n_connection_get_negotiated_psk_identity_length :: Ptr S2nConnection -> Ptr Word16 -> IO (Either S2nError CInt)+ , s2n_connection_get_negotiated_psk_identity :: Ptr S2nConnection -> Ptr Word8 -> Word16 -> IO (Either S2nError CInt)+ , s2n_offered_psk_new :: IO (Either S2nError (Ptr S2nOfferedPsk))+ , s2n_offered_psk_free :: Ptr (Ptr S2nOfferedPsk) -> IO (Either S2nError CInt)+ , s2n_offered_psk_get_identity :: Ptr S2nOfferedPsk -> Ptr (Ptr Word8) -> Ptr Word16 -> IO (Either S2nError CInt)+ , s2n_offered_psk_list_has_next :: Ptr S2nOfferedPskList -> IO CBool+ , s2n_offered_psk_list_next :: Ptr S2nOfferedPskList -> Ptr S2nOfferedPsk -> IO (Either S2nError CInt)+ , s2n_offered_psk_list_reread :: Ptr S2nOfferedPskList -> IO (Either S2nError CInt)+ , s2n_offered_psk_list_choose_psk :: Ptr S2nOfferedPskList -> Ptr S2nOfferedPsk -> IO (Either S2nError CInt)+ , s2n_psk_configure_early_data :: Ptr S2nPsk -> Word32 -> Word8 -> Word8 -> IO (Either S2nError CInt)+ , s2n_psk_set_application_protocol :: Ptr S2nPsk -> Ptr Word8 -> Word8 -> IO (Either S2nError CInt)+ , s2n_psk_set_early_data_context :: Ptr S2nPsk -> Ptr Word8 -> Word16 -> IO (Either S2nError CInt)+ , s2n_connection_get_wire_bytes_in :: Ptr S2nConnection -> IO Word64+ -- ^ __Connection Statistics__+ , s2n_connection_get_wire_bytes_out :: Ptr S2nConnection -> IO Word64+ , s2n_connection_get_client_protocol_version :: Ptr S2nConnection -> IO (Either S2nError CInt)+ -- ^ __Protocol Version Information__+ , s2n_connection_get_server_protocol_version :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_get_actual_protocol_version :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_get_client_hello_version :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_get_cipher :: Ptr S2nConnection -> IO (Either S2nError CString)+ -- ^ __Cipher & Security Information__+ , s2n_connection_get_certificate_match :: Ptr S2nConnection -> Ptr S2nCertSniMatch -> IO (Either S2nError CInt)+ , s2n_connection_get_master_secret :: Ptr S2nConnection -> Ptr Word8 -> CSize -> IO (Either S2nError CInt)+ , s2n_connection_tls_exporter :: Ptr S2nConnection -> Ptr Word8 -> Word32 -> Ptr Word8 -> Word32 -> Ptr Word8 -> Word32 -> IO (Either S2nError CInt)+ , s2n_connection_get_cipher_iana_value :: Ptr S2nConnection -> Ptr Word8 -> Ptr Word8 -> IO (Either S2nError CInt)+ , s2n_connection_is_valid_for_cipher_preferences :: Ptr S2nConnection -> CString -> IO (Either S2nError CInt)+ , s2n_connection_get_curve :: Ptr S2nConnection -> IO (Either S2nError CString)+ , s2n_connection_get_kem_name :: Ptr S2nConnection -> IO (Either S2nError CString)+ , s2n_connection_get_kem_group_name :: Ptr S2nConnection -> IO (Either S2nError CString)+ , s2n_connection_get_key_exchange_group :: Ptr S2nConnection -> Ptr CString -> IO (Either S2nError CInt)+ , s2n_connection_get_alert :: Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_connection_get_handshake_type_name :: Ptr S2nConnection -> IO (Either S2nError CString)+ , s2n_connection_get_last_message_name :: Ptr S2nConnection -> IO (Either S2nError CString)+ , s2n_async_pkey_op_perform :: Ptr S2nAsyncPkeyOp -> Ptr S2nCertPrivateKey -> IO (Either S2nError CInt)+ -- ^ __Async Private Key Operations__+ , s2n_async_pkey_op_apply :: Ptr S2nAsyncPkeyOp -> Ptr S2nConnection -> IO (Either S2nError CInt)+ , s2n_async_pkey_op_free :: Ptr S2nAsyncPkeyOp -> IO (Either S2nError CInt)+ , s2n_async_pkey_op_get_op_type :: Ptr S2nAsyncPkeyOp -> Ptr S2nAsyncPkeyOpType -> IO (Either S2nError CInt)+ , s2n_async_pkey_op_get_input_size :: Ptr S2nAsyncPkeyOp -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_async_pkey_op_get_input :: Ptr S2nAsyncPkeyOp -> Ptr Word8 -> Word32 -> IO (Either S2nError CInt)+ , s2n_async_pkey_op_set_output :: Ptr S2nAsyncPkeyOp -> Ptr Word8 -> Word32 -> IO (Either S2nError CInt)+ , s2n_connection_set_server_max_early_data_size :: Ptr S2nConnection -> Word32 -> IO (Either S2nError CInt)+ -- ^ __Early Data__+ , s2n_connection_set_server_early_data_context :: Ptr S2nConnection -> Ptr Word8 -> Word16 -> IO (Either S2nError CInt)+ , s2n_connection_get_early_data_status :: Ptr S2nConnection -> Ptr S2nEarlyDataStatus -> IO (Either S2nError CInt)+ , s2n_connection_get_remaining_early_data_size :: Ptr S2nConnection -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_connection_get_max_early_data_size :: Ptr S2nConnection -> Ptr Word32 -> IO (Either S2nError CInt)+ , s2n_send_early_data :: Ptr S2nConnection -> Ptr Word8 -> CSsize -> Ptr CSsize -> Ptr S2nBlockedStatus -> IO (Either S2nError CInt)+ , s2n_recv_early_data :: Ptr S2nConnection -> Ptr Word8 -> CSsize -> Ptr CSsize -> Ptr S2nBlockedStatus -> IO (Either S2nError CInt)+ , s2n_offered_early_data_get_context_length :: Ptr S2nOfferedEarlyData -> Ptr Word16 -> IO (Either S2nError CInt)+ , s2n_offered_early_data_get_context :: Ptr S2nOfferedEarlyData -> Ptr Word8 -> Word16 -> IO (Either S2nError CInt)+ , s2n_offered_early_data_reject :: Ptr S2nOfferedEarlyData -> IO (Either S2nError CInt)+ , s2n_offered_early_data_accept :: Ptr S2nOfferedEarlyData -> IO (Either S2nError CInt)+ , s2n_connection_serialization_length :: Ptr S2nConnection -> Ptr Word32 -> IO (Either S2nError CInt)+ -- ^ __Connection Serialization__+ , s2n_connection_serialize :: Ptr S2nConnection -> Ptr Word8 -> Word32 -> IO (Either S2nError CInt)+ , s2n_connection_deserialize :: Ptr S2nConnection -> Ptr Word8 -> Word32 -> IO (Either S2nError CInt)+ }
+ test/MemorySafety.hs view
@@ -0,0 +1,499 @@+{-# LANGUAGE NumericUnderscores #-}++{- |+Module : Main+Description : Memory safety tests for s2n-tls FFI bindings++This test invokes all FFI functions to check for segfaults and memory errors.+Each function name is printed before invocation so crashes can be identified.+-}+module Main where++import Control.Exception (SomeException, catch)+import Control.Monad (void)+import Data.Word (Word16, Word32, Word8)+import Foreign.C.String (withCString)+import Foreign.C.Types (CInt (..))+import Foreign.Marshal.Alloc (alloca, allocaBytes)+import Foreign.Marshal.Array (allocaArray, pokeArray)+import Foreign.Ptr (Ptr, nullFunPtr, nullPtr)+import Foreign.Storable (poke)+import System.IO (hFlush, stdout)++import S2nTls.Ffi+import S2nTls.Ffi.Types++-- | Print function name and flush, then invoke it. Catches exceptions (only segfaults crash).+invoke :: String -> IO a -> IO ()+invoke name action = do+ putStrLn $ " " ++ name+ hFlush stdout+ result <- (Right <$> action) `catch` \(e :: SomeException) -> pure (Left e)+ case result of+ Right _ -> pure ()+ Left _ -> pure () -- Exceptions are OK, we only care about segfaults++main :: IO ()+main = withS2nTlsFfi Linked $ \ffi -> do+ putStrLn "=== s2n-tls Memory Safety Tests ==="+ hFlush stdout++ runInitTests ffi+ runErrorTests ffi+ runStackTraceTests ffi+ runConfigTests ffi+ runCertChainTests ffi+ runConnectionTests ffi+ runPskTests ffi+ runCleanupTests ffi++ putStrLn "=== All tests completed ==="+ hFlush stdout++--------------------------------------------------------------------------------+-- Initialization Tests+--------------------------------------------------------------------------------++runInitTests :: S2nTlsFfi -> IO ()+runInitTests ffi = do+ putStrLn "\n[Initialization]"+ hFlush stdout+ invoke "s2n_init" $ s2n_init ffi+ invoke "s2n_crypto_disable_init" $ s2n_crypto_disable_init ffi+ invoke "s2n_disable_atexit" $ s2n_disable_atexit ffi+ invoke "s2n_get_openssl_version" $ s2n_get_openssl_version ffi+ alloca $ \ptr ->+ invoke "s2n_get_fips_mode" $ s2n_get_fips_mode ffi ptr++--------------------------------------------------------------------------------+-- Error Handling Tests+--------------------------------------------------------------------------------++runErrorTests :: S2nTlsFfi -> IO ()+runErrorTests ffi = do+ putStrLn "\n[Error Handling]"+ hFlush stdout+ invoke "s2n_errno_location" $ s2n_errno_location ffi+ invoke "s2n_error_get_type" $ s2n_error_get_type ffi 0+ withCString "EN" $ \lang -> do+ invoke "s2n_strerror" $ s2n_strerror ffi 0 lang+ invoke "s2n_strerror_debug" $ s2n_strerror_debug ffi 0 lang+ invoke "s2n_strerror_name" $ s2n_strerror_name ffi 0+ invoke "s2n_strerror_source" $ s2n_strerror_source ffi 0++--------------------------------------------------------------------------------+-- Stack Trace Tests+--------------------------------------------------------------------------------++runStackTraceTests :: S2nTlsFfi -> IO ()+runStackTraceTests ffi = do+ putStrLn "\n[Stack Traces]"+ hFlush stdout+ invoke "s2n_stack_traces_enabled" $ s2n_stack_traces_enabled ffi+ invoke "s2n_stack_traces_enabled_set" $ s2n_stack_traces_enabled_set ffi 0+ invoke "s2n_calculate_stacktrace" $ s2n_calculate_stacktrace ffi+ allocaBytes 8 $ \ptr ->+ invoke "s2n_get_stacktrace" $ s2n_get_stacktrace ffi ptr+ invoke "s2n_free_stacktrace" $ s2n_free_stacktrace ffi++--------------------------------------------------------------------------------+-- Config Tests+--------------------------------------------------------------------------------++runConfigTests :: S2nTlsFfi -> IO ()+runConfigTests ffi = do+ putStrLn "\n[Config]"+ hFlush stdout+ invoke "s2n_config_new" $ s2n_config_new ffi+ invoke "s2n_config_new_minimal" $ s2n_config_new_minimal ffi++ -- Run config operation tests with a fresh config+ withConfig ffi $ \cfg -> do+ putStrLn "\n[Config Operations]"+ hFlush stdout+ invoke "s2n_config_set_wall_clock" $ s2n_config_set_wall_clock ffi cfg nullFunPtr nullPtr+ invoke "s2n_config_set_monotonic_clock" $ s2n_config_set_monotonic_clock ffi cfg nullFunPtr nullPtr+ invoke "s2n_config_set_cache_store_callback" $ s2n_config_set_cache_store_callback ffi cfg nullFunPtr nullPtr+ invoke "s2n_config_set_cache_retrieve_callback" $ s2n_config_set_cache_retrieve_callback ffi cfg nullFunPtr nullPtr+ invoke "s2n_config_set_cache_delete_callback" $ s2n_config_set_cache_delete_callback ffi cfg nullFunPtr nullPtr+ invoke "s2n_config_wipe_trust_store" $ s2n_config_wipe_trust_store ffi cfg+ invoke "s2n_config_load_system_certs" $ s2n_config_load_system_certs ffi cfg+ withCString "/nonexistent" $ \path ->+ invoke "s2n_config_set_verification_ca_location" $ s2n_config_set_verification_ca_location ffi cfg path nullPtr+ withCString "-----BEGIN CERTIFICATE-----\ntest\n-----END CERTIFICATE-----" $ \pem ->+ invoke "s2n_config_add_pem_to_trust_store" $ s2n_config_add_pem_to_trust_store ffi cfg pem+ invoke "s2n_config_set_cert_authorities_from_trust_store" $ s2n_config_set_cert_authorities_from_trust_store ffi cfg+ invoke "s2n_config_set_verify_after_sign" $ s2n_config_set_verify_after_sign ffi cfg (S2nVerifyAfterSign 0)+ invoke "s2n_config_set_check_stapled_ocsp_response" $ s2n_config_set_check_stapled_ocsp_response ffi cfg 0+ invoke "s2n_config_disable_x509_time_verification" $ s2n_config_disable_x509_time_verification ffi cfg+ invoke "s2n_config_disable_x509_verification" $ s2n_config_disable_x509_verification ffi cfg+ invoke "s2n_config_set_max_cert_chain_depth" $ s2n_config_set_max_cert_chain_depth ffi cfg 10+ invoke "s2n_config_set_verify_host_callback" $ s2n_config_set_verify_host_callback ffi cfg nullFunPtr nullPtr+ withCString "-----BEGIN DH PARAMETERS-----\ntest\n-----END DH PARAMETERS-----" $ \dh ->+ invoke "s2n_config_add_dhparams" $ s2n_config_add_dhparams ffi cfg dh+ withCString "default_tls13" $ \policy ->+ invoke "s2n_config_set_cipher_preferences" $ s2n_config_set_cipher_preferences ffi cfg policy+ allocaArray 10 $ \protoPtr ->+ invoke "s2n_config_append_protocol_preference" $ s2n_config_append_protocol_preference ffi cfg protoPtr 5+ withCString "h2" $ \proto1 ->+ allocaArray 1 $ \protos -> do+ pokeArray protos [proto1]+ invoke "s2n_config_set_protocol_preferences" $ s2n_config_set_protocol_preferences ffi cfg protos 1+ invoke "s2n_config_set_status_request_type" $ s2n_config_set_status_request_type ffi cfg (S2nStatusRequestType 0)+ invoke "s2n_config_set_ct_support_level" $ s2n_config_set_ct_support_level ffi cfg (S2nCtSupportLevel 0)+ invoke "s2n_config_set_alert_behavior" $ s2n_config_set_alert_behavior ffi cfg (S2nAlertBehavior 0)+ allocaBytes 16 $ \buf ->+ invoke "s2n_config_set_extension_data" $ s2n_config_set_extension_data ffi cfg (S2nTlsExtensionType 0) buf 16+ invoke "s2n_config_send_max_fragment_length" $ s2n_config_send_max_fragment_length ffi cfg (S2nMaxFragLen 1)+ invoke "s2n_config_accept_max_fragment_length" $ s2n_config_accept_max_fragment_length ffi cfg+ invoke "s2n_config_set_session_state_lifetime" $ s2n_config_set_session_state_lifetime ffi cfg 3600+ invoke "s2n_config_set_session_tickets_onoff" $ s2n_config_set_session_tickets_onoff ffi cfg 1+ invoke "s2n_config_set_session_cache_onoff" $ s2n_config_set_session_cache_onoff ffi cfg 1+ invoke "s2n_config_set_ticket_encrypt_decrypt_key_lifetime" $ s2n_config_set_ticket_encrypt_decrypt_key_lifetime ffi cfg 3600+ invoke "s2n_config_set_ticket_decrypt_key_lifetime" $ s2n_config_set_ticket_decrypt_key_lifetime ffi cfg 7200+ allocaBytes 16 $ \keyName -> allocaBytes 32 $ \keyData ->+ invoke "s2n_config_add_ticket_crypto_key" $ s2n_config_add_ticket_crypto_key ffi cfg keyName 16 keyData 32 0+ invoke "s2n_config_require_ticket_forward_secrecy" $ s2n_config_require_ticket_forward_secrecy ffi cfg 1+ invoke "s2n_config_set_send_buffer_size" $ s2n_config_set_send_buffer_size ffi cfg 16384+ invoke "s2n_config_set_recv_multi_record" $ s2n_config_set_recv_multi_record ffi cfg 1+ invoke "s2n_config_set_client_hello_cb" $ s2n_config_set_client_hello_cb ffi cfg nullFunPtr nullPtr+ invoke "s2n_config_set_client_hello_cb_mode" $ s2n_config_set_client_hello_cb_mode ffi cfg (S2nClientHelloCbMode 0)+ invoke "s2n_config_set_max_blinding_delay" $ s2n_config_set_max_blinding_delay ffi cfg 30+ alloca $ \authType ->+ invoke "s2n_config_get_client_auth_type" $ s2n_config_get_client_auth_type ffi cfg authType+ invoke "s2n_config_set_client_auth_type" $ s2n_config_set_client_auth_type ffi cfg (S2nCertAuthType 0)+ invoke "s2n_config_set_initial_ticket_count" $ s2n_config_set_initial_ticket_count ffi cfg 2+ invoke "s2n_config_set_psk_mode" $ s2n_config_set_psk_mode ffi cfg (S2nPskMode 0)+ invoke "s2n_config_set_psk_selection_callback" $ s2n_config_set_psk_selection_callback ffi cfg nullFunPtr nullPtr+ invoke "s2n_config_set_async_pkey_callback" $ s2n_config_set_async_pkey_callback ffi cfg nullFunPtr+ invoke "s2n_config_set_async_pkey_validation_mode" $ s2n_config_set_async_pkey_validation_mode ffi cfg (S2nAsyncPkeyValidationMode 0)+ invoke "s2n_config_set_session_ticket_cb" $ s2n_config_set_session_ticket_cb ffi cfg nullFunPtr nullPtr+ invoke "s2n_config_set_key_log_cb" $ s2n_config_set_key_log_cb ffi cfg nullFunPtr nullPtr+ invoke "s2n_config_enable_cert_req_dss_legacy_compat" $ s2n_config_enable_cert_req_dss_legacy_compat ffi cfg+ invoke "s2n_config_set_server_max_early_data_size" $ s2n_config_set_server_max_early_data_size ffi cfg 16384+ invoke "s2n_config_set_early_data_cb" $ s2n_config_set_early_data_cb ffi cfg nullFunPtr+ invoke "s2n_config_set_ctx" $ s2n_config_set_ctx ffi cfg nullPtr+ alloca $ \ctxPtr ->+ invoke "s2n_config_get_ctx" $ s2n_config_get_ctx ffi cfg ctxPtr+ allocaArray 10 $ \groups -> alloca $ \count ->+ invoke "s2n_config_get_supported_groups" $ s2n_config_get_supported_groups ffi cfg groups 10 count+ invoke "s2n_config_set_serialization_version" $ s2n_config_set_serialization_version ffi cfg (S2nSerializationVersion 0)+ invoke "s2n_config_set_cert_tiebreak_callback" $ s2n_config_set_cert_tiebreak_callback ffi cfg nullFunPtr+ withCString "" $ \emptyPath ->+ invoke "s2n_config_add_cert_chain_and_key" $ s2n_config_add_cert_chain_and_key ffi cfg emptyPath emptyPath+ invoke "s2n_config_free_dhparams" $ s2n_config_free_dhparams ffi cfg+ invoke "s2n_config_free_cert_chain_and_key" $ s2n_config_free_cert_chain_and_key ffi cfg++ -- Test s2n_config_free separately+ result <- s2n_config_new ffi+ case result of+ Left _ -> pure ()+ Right cfg -> invoke "s2n_config_free" $ s2n_config_free ffi cfg++-- | Helper to run tests with a fresh config+withConfig :: S2nTlsFfi -> (Ptr S2nConfig -> IO ()) -> IO ()+withConfig ffi action = do+ result <- s2n_config_new ffi+ case result of+ Left _ -> putStrLn " [skipped - config creation failed]"+ Right cfg -> do+ action cfg+ void $ s2n_config_free ffi cfg++--------------------------------------------------------------------------------+-- Certificate Chain Tests+--------------------------------------------------------------------------------++runCertChainTests :: S2nTlsFfi -> IO ()+runCertChainTests ffi = do+ putStrLn "\n[Certificate Chain]"+ hFlush stdout+ invoke "s2n_cert_chain_and_key_new" $ s2n_cert_chain_and_key_new ffi++ withCertChain ffi $ \cert -> do+ withCString "-----BEGIN CERTIFICATE-----\ntest\n-----END CERTIFICATE-----" $ \pemCert ->+ withCString "-----BEGIN PRIVATE KEY-----\ntest\n-----END PRIVATE KEY-----" $ \pemKey ->+ invoke "s2n_cert_chain_and_key_load_pem" $ s2n_cert_chain_and_key_load_pem ffi cert pemCert pemKey+ allocaBytes 100 $ \certBuf -> allocaBytes 100 $ \keyBuf ->+ invoke "s2n_cert_chain_and_key_load_pem_bytes" $ s2n_cert_chain_and_key_load_pem_bytes ffi cert certBuf 100 keyBuf 100+ allocaBytes 100 $ \buf ->+ invoke "s2n_cert_chain_and_key_load_public_pem_bytes" $ s2n_cert_chain_and_key_load_public_pem_bytes ffi cert buf 100+ invoke "s2n_cert_chain_and_key_set_ctx" $ s2n_cert_chain_and_key_set_ctx ffi cert nullPtr+ invoke "s2n_cert_chain_and_key_get_ctx" $ s2n_cert_chain_and_key_get_ctx ffi cert+ invoke "s2n_cert_chain_and_key_get_private_key" $ s2n_cert_chain_and_key_get_private_key ffi cert+ allocaBytes 100 $ \buf ->+ invoke "s2n_cert_chain_and_key_set_ocsp_data" $ s2n_cert_chain_and_key_set_ocsp_data ffi cert buf 100+ allocaBytes 100 $ \buf ->+ invoke "s2n_cert_chain_and_key_set_sct_list" $ s2n_cert_chain_and_key_set_sct_list ffi cert buf 100+ alloca $ \lengthPtr ->+ invoke "s2n_cert_chain_get_length" $ s2n_cert_chain_get_length ffi cert lengthPtr+ alloca $ \certPtr ->+ invoke "s2n_cert_chain_get_cert" $ s2n_cert_chain_get_cert ffi cert certPtr 0++ -- Test s2n_cert_chain_and_key_free separately+ result <- s2n_cert_chain_and_key_new ffi+ case result of+ Left _ -> pure ()+ Right cert -> invoke "s2n_cert_chain_and_key_free" $ s2n_cert_chain_and_key_free ffi cert++-- | Helper to run tests with a fresh cert chain+withCertChain :: S2nTlsFfi -> (Ptr S2nCertChainAndKey -> IO ()) -> IO ()+withCertChain ffi action = do+ result <- s2n_cert_chain_and_key_new ffi+ case result of+ Left _ -> putStrLn " [skipped - cert chain creation failed]"+ Right cert -> do+ action cert+ void $ s2n_cert_chain_and_key_free ffi cert++--------------------------------------------------------------------------------+-- Connection Tests+--------------------------------------------------------------------------------++runConnectionTests :: S2nTlsFfi -> IO ()+runConnectionTests ffi = do+ putStrLn "\n[Connection]"+ hFlush stdout+ invoke "s2n_connection_new (client)" $ s2n_connection_new ffi S2nClient+ invoke "s2n_connection_new (server)" $ s2n_connection_new ffi S2nServer++ withConnection ffi $ \conn -> do+ putStrLn "\n[Connection Operations]"+ hFlush stdout++ -- Config assignment+ cfgResult <- s2n_config_new ffi+ case cfgResult of+ Left _ -> pure ()+ Right cfg -> do+ invoke "s2n_connection_set_config" $ s2n_connection_set_config ffi conn cfg+ void $ s2n_config_free ffi cfg++ invoke "s2n_connection_set_ctx" $ s2n_connection_set_ctx ffi conn nullPtr+ invoke "s2n_connection_get_ctx" $ s2n_connection_get_ctx ffi conn+ invoke "s2n_client_hello_cb_done" $ s2n_client_hello_cb_done ffi conn+ invoke "s2n_connection_server_name_extension_used" $ s2n_connection_server_name_extension_used ffi conn+ invoke "s2n_connection_get_client_hello" $ s2n_connection_get_client_hello ffi conn+ allocaBytes 100 $ \buf ->+ invoke "s2n_client_hello_parse_message" $ s2n_client_hello_parse_message ffi buf 100+ invoke "s2n_connection_set_fd" $ s2n_connection_set_fd ffi conn (-1)+ invoke "s2n_connection_set_read_fd" $ s2n_connection_set_read_fd ffi conn (-1)+ invoke "s2n_connection_set_write_fd" $ s2n_connection_set_write_fd ffi conn (-1)+ alloca $ \fdPtr -> do+ invoke "s2n_connection_get_read_fd" $ s2n_connection_get_read_fd ffi conn fdPtr+ invoke "s2n_connection_get_write_fd" $ s2n_connection_get_write_fd ffi conn fdPtr+ invoke "s2n_connection_use_corked_io" $ s2n_connection_use_corked_io ffi conn+ invoke "s2n_connection_set_recv_ctx" $ s2n_connection_set_recv_ctx ffi conn nullPtr+ invoke "s2n_connection_set_send_ctx" $ s2n_connection_set_send_ctx ffi conn nullPtr+ invoke "s2n_connection_set_recv_cb" $ s2n_connection_set_recv_cb ffi conn nullFunPtr+ invoke "s2n_connection_set_send_cb" $ s2n_connection_set_send_cb ffi conn nullFunPtr+ invoke "s2n_connection_prefer_throughput" $ s2n_connection_prefer_throughput ffi conn+ invoke "s2n_connection_prefer_low_latency" $ s2n_connection_prefer_low_latency ffi conn+ invoke "s2n_connection_set_recv_buffering" $ s2n_connection_set_recv_buffering ffi conn 1+ invoke "s2n_peek_buffered" $ s2n_peek_buffered ffi conn+ invoke "s2n_connection_set_dynamic_buffers" $ s2n_connection_set_dynamic_buffers ffi conn 1+ invoke "s2n_connection_set_dynamic_record_threshold" $ s2n_connection_set_dynamic_record_threshold ffi conn 1400 100+ invoke "s2n_connection_set_verify_host_callback" $ s2n_connection_set_verify_host_callback ffi conn nullFunPtr nullPtr+ invoke "s2n_connection_set_blinding" $ s2n_connection_set_blinding ffi conn S2nSelfServiceBlinding+ invoke "s2n_connection_get_delay" $ s2n_connection_get_delay ffi conn+ withCString "default_tls13" $ \policy ->+ invoke "s2n_connection_set_cipher_preferences" $ s2n_connection_set_cipher_preferences ffi conn policy+ invoke "s2n_connection_request_key_update" $ s2n_connection_request_key_update ffi conn (S2nPeerKeyUpdate 0)+ allocaBytes 10 $ \proto ->+ invoke "s2n_connection_append_protocol_preference" $ s2n_connection_append_protocol_preference ffi conn proto 5+ withCString "h2" $ \proto1 ->+ allocaArray 1 $ \protos -> do+ pokeArray protos [proto1]+ invoke "s2n_connection_set_protocol_preferences" $ s2n_connection_set_protocol_preferences ffi conn protos 1+ withCString "example.com" $ \name ->+ invoke "s2n_set_server_name" $ s2n_set_server_name ffi conn name+ invoke "s2n_get_server_name" $ s2n_get_server_name ffi conn+ invoke "s2n_get_application_protocol" $ s2n_get_application_protocol ffi conn+ alloca $ \lenPtr -> do+ invoke "s2n_connection_get_ocsp_response" $ s2n_connection_get_ocsp_response ffi conn lenPtr+ invoke "s2n_connection_get_sct_list" $ s2n_connection_get_sct_list ffi conn lenPtr+ alloca $ \blocked -> do+ invoke "s2n_negotiate" $ s2n_negotiate ffi conn blocked+ allocaBytes 100 $ \buf -> do+ invoke "s2n_send" $ s2n_send ffi conn buf 100 blocked+ invoke "s2n_recv" $ s2n_recv ffi conn buf 100 blocked+ invoke "s2n_shutdown" $ s2n_shutdown ffi conn blocked+ invoke "s2n_shutdown_send" $ s2n_shutdown_send ffi conn blocked+ invoke "s2n_peek" $ s2n_peek ffi conn+ alloca $ \authType ->+ invoke "s2n_connection_get_client_auth_type" $ s2n_connection_get_client_auth_type ffi conn authType+ invoke "s2n_connection_set_client_auth_type" $ s2n_connection_set_client_auth_type ffi conn (S2nCertAuthType 0)+ alloca $ \certPtr -> alloca $ \lenPtr ->+ invoke "s2n_connection_get_client_cert_chain" $ s2n_connection_get_client_cert_chain ffi conn certPtr lenPtr+ invoke "s2n_connection_client_cert_used" $ s2n_connection_client_cert_used ffi conn+ invoke "s2n_connection_add_new_tickets_to_send" $ s2n_connection_add_new_tickets_to_send ffi conn 1+ alloca $ \ticketsPtr ->+ invoke "s2n_connection_get_tickets_sent" $ s2n_connection_get_tickets_sent ffi conn ticketsPtr+ invoke "s2n_connection_set_server_keying_material_lifetime" $ s2n_connection_set_server_keying_material_lifetime ffi conn 86400+ allocaBytes 256 $ \buf -> do+ invoke "s2n_connection_set_session" $ s2n_connection_set_session ffi conn buf 256+ invoke "s2n_connection_get_session" $ s2n_connection_get_session ffi conn buf 256+ invoke "s2n_connection_get_session_ticket_lifetime_hint" $ s2n_connection_get_session_ticket_lifetime_hint ffi conn+ invoke "s2n_connection_get_session_length" $ s2n_connection_get_session_length ffi conn+ invoke "s2n_connection_get_session_id_length" $ s2n_connection_get_session_id_length ffi conn+ allocaBytes 32 $ \buf ->+ invoke "s2n_connection_get_session_id" $ s2n_connection_get_session_id ffi conn buf 32+ invoke "s2n_connection_is_session_resumed" $ s2n_connection_is_session_resumed ffi conn+ invoke "s2n_connection_is_ocsp_stapled" $ s2n_connection_is_ocsp_stapled ffi conn+ alloca $ \sigAlg -> do+ invoke "s2n_connection_get_selected_signature_algorithm" $ s2n_connection_get_selected_signature_algorithm ffi conn sigAlg+ invoke "s2n_connection_get_selected_client_cert_signature_algorithm" $ s2n_connection_get_selected_client_cert_signature_algorithm ffi conn sigAlg+ alloca $ \hashAlg -> do+ invoke "s2n_connection_get_selected_digest_algorithm" $ s2n_connection_get_selected_digest_algorithm ffi conn hashAlg+ invoke "s2n_connection_get_selected_client_cert_digest_algorithm" $ s2n_connection_get_selected_client_cert_digest_algorithm ffi conn hashAlg+ invoke "s2n_connection_get_selected_cert" $ s2n_connection_get_selected_cert ffi conn+ certResult <- s2n_cert_chain_and_key_new ffi+ case certResult of+ Left _ -> pure ()+ Right peerCert -> do+ invoke "s2n_connection_get_peer_cert_chain" $ s2n_connection_get_peer_cert_chain ffi conn peerCert+ void $ s2n_cert_chain_and_key_free ffi peerCert+ invoke "s2n_connection_get_wire_bytes_in" $ s2n_connection_get_wire_bytes_in ffi conn+ invoke "s2n_connection_get_wire_bytes_out" $ s2n_connection_get_wire_bytes_out ffi conn+ invoke "s2n_connection_get_client_protocol_version" $ s2n_connection_get_client_protocol_version ffi conn+ invoke "s2n_connection_get_server_protocol_version" $ s2n_connection_get_server_protocol_version ffi conn+ invoke "s2n_connection_get_actual_protocol_version" $ s2n_connection_get_actual_protocol_version ffi conn+ invoke "s2n_connection_get_client_hello_version" $ s2n_connection_get_client_hello_version ffi conn+ invoke "s2n_connection_get_cipher" $ s2n_connection_get_cipher ffi conn+ alloca $ \sniMatch ->+ invoke "s2n_connection_get_certificate_match" $ s2n_connection_get_certificate_match ffi conn sniMatch+ allocaBytes 48 $ \buf ->+ invoke "s2n_connection_get_master_secret" $ s2n_connection_get_master_secret ffi conn buf 48+ allocaBytes 32 $ \label -> allocaBytes 32 $ \context -> allocaBytes 32 $ \output ->+ invoke "s2n_connection_tls_exporter" $ s2n_connection_tls_exporter ffi conn label 32 context 32 output 32+ alloca $ \first -> alloca $ \second ->+ invoke "s2n_connection_get_cipher_iana_value" $ s2n_connection_get_cipher_iana_value ffi conn first second+ withCString "default_tls13" $ \policy ->+ invoke "s2n_connection_is_valid_for_cipher_preferences" $ s2n_connection_is_valid_for_cipher_preferences ffi conn policy+ invoke "s2n_connection_get_curve" $ s2n_connection_get_curve ffi conn+ invoke "s2n_connection_get_kem_name" $ s2n_connection_get_kem_name ffi conn+ invoke "s2n_connection_get_kem_group_name" $ s2n_connection_get_kem_group_name ffi conn+ alloca $ \groupName ->+ invoke "s2n_connection_get_key_exchange_group" $ s2n_connection_get_key_exchange_group ffi conn groupName+ invoke "s2n_connection_get_alert" $ s2n_connection_get_alert ffi conn+ invoke "s2n_connection_get_handshake_type_name" $ s2n_connection_get_handshake_type_name ffi conn+ invoke "s2n_connection_get_last_message_name" $ s2n_connection_get_last_message_name ffi conn+ invoke "s2n_connection_set_psk_mode" $ s2n_connection_set_psk_mode ffi conn (S2nPskMode 0)+ alloca $ \lenPtr ->+ invoke "s2n_connection_get_negotiated_psk_identity_length" $ s2n_connection_get_negotiated_psk_identity_length ffi conn lenPtr+ allocaBytes 32 $ \buf ->+ invoke "s2n_connection_get_negotiated_psk_identity" $ s2n_connection_get_negotiated_psk_identity ffi conn buf 32+ invoke "s2n_connection_set_server_max_early_data_size" $ s2n_connection_set_server_max_early_data_size ffi conn 16384+ allocaBytes 100 $ \ctx ->+ invoke "s2n_connection_set_server_early_data_context" $ s2n_connection_set_server_early_data_context ffi conn ctx 100+ alloca $ \status ->+ invoke "s2n_connection_get_early_data_status" $ s2n_connection_get_early_data_status ffi conn status+ alloca $ \remaining ->+ invoke "s2n_connection_get_remaining_early_data_size" $ s2n_connection_get_remaining_early_data_size ffi conn remaining+ alloca $ \maxSize ->+ invoke "s2n_connection_get_max_early_data_size" $ s2n_connection_get_max_early_data_size ffi conn maxSize+ alloca $ \blocked -> allocaBytes 100 $ \buf -> alloca $ \written -> do+ invoke "s2n_send_early_data" $ s2n_send_early_data ffi conn buf 100 written blocked+ invoke "s2n_recv_early_data" $ s2n_recv_early_data ffi conn buf 100 written blocked+ alloca $ \lenPtr ->+ invoke "s2n_connection_serialization_length" $ s2n_connection_serialization_length ffi conn lenPtr+ allocaBytes 1024 $ \buf -> do+ invoke "s2n_connection_serialize" $ s2n_connection_serialize ffi conn buf 1024+ invoke "s2n_connection_deserialize" $ s2n_connection_deserialize ffi conn buf 1024+ invoke "s2n_connection_free_handshake" $ s2n_connection_free_handshake ffi conn+ invoke "s2n_connection_release_buffers" $ s2n_connection_release_buffers ffi conn+ invoke "s2n_connection_wipe" $ s2n_connection_wipe ffi conn++ -- Test s2n_connection_free separately+ result <- s2n_connection_new ffi S2nClient+ case result of+ Left _ -> pure ()+ Right conn -> invoke "s2n_connection_free" $ s2n_connection_free ffi conn++-- | Helper to run tests with a fresh connection+withConnection :: S2nTlsFfi -> (Ptr S2nConnection -> IO ()) -> IO ()+withConnection ffi action = do+ result <- s2n_connection_new ffi S2nClient+ case result of+ Left _ -> putStrLn " [skipped - connection creation failed]"+ Right conn -> do+ action conn+ void $ s2n_connection_free ffi conn++--------------------------------------------------------------------------------+-- PSK Tests+--------------------------------------------------------------------------------++runPskTests :: S2nTlsFfi -> IO ()+runPskTests ffi = do+ putStrLn "\n[PSK]"+ hFlush stdout+ invoke "s2n_external_psk_new" $ s2n_external_psk_new ffi++ withPsk ffi $ \psk -> do+ allocaBytes 32 $ \identity ->+ invoke "s2n_psk_set_identity" $ s2n_psk_set_identity ffi psk identity 32+ allocaBytes 32 $ \secret ->+ invoke "s2n_psk_set_secret" $ s2n_psk_set_secret ffi psk secret 32+ invoke "s2n_psk_set_hmac" $ s2n_psk_set_hmac ffi psk S2nPskHmacSha256+ invoke "s2n_psk_configure_early_data" $ s2n_psk_configure_early_data ffi psk 16384 33 34+ allocaBytes 10 $ \proto ->+ invoke "s2n_psk_set_application_protocol" $ s2n_psk_set_application_protocol ffi psk proto 10+ allocaBytes 32 $ \ctx ->+ invoke "s2n_psk_set_early_data_context" $ s2n_psk_set_early_data_context ffi psk ctx 32++ -- Test s2n_connection_append_psk+ pskResult <- s2n_external_psk_new ffi+ connResult <- s2n_connection_new ffi S2nClient+ case (pskResult, connResult) of+ (Right psk, Right conn) -> do+ invoke "s2n_connection_append_psk" $ s2n_connection_append_psk ffi conn psk+ void $ s2n_connection_free ffi conn+ alloca $ \pskPtr -> do+ poke pskPtr psk+ void $ s2n_psk_free ffi pskPtr+ _ -> pure ()++ -- Test s2n_psk_free+ pskResult2 <- s2n_external_psk_new ffi+ case pskResult2 of+ Left _ -> pure ()+ Right psk ->+ alloca $ \pskPtr -> do+ poke pskPtr psk+ invoke "s2n_psk_free" $ s2n_psk_free ffi pskPtr++ -- Test offered PSK functions+ invoke "s2n_offered_psk_new" $ s2n_offered_psk_new ffi+ offeredResult <- s2n_offered_psk_new ffi+ case offeredResult of+ Left _ -> pure ()+ Right offered -> do+ alloca $ \identityPtr -> alloca $ \lenPtr ->+ invoke "s2n_offered_psk_get_identity" $ s2n_offered_psk_get_identity ffi offered identityPtr lenPtr+ alloca $ \offeredPtr -> do+ poke offeredPtr offered+ invoke "s2n_offered_psk_free" $ s2n_offered_psk_free ffi offeredPtr++-- | Helper to run tests with a fresh PSK+withPsk :: S2nTlsFfi -> (Ptr S2nPsk -> IO ()) -> IO ()+withPsk ffi action = do+ result <- s2n_external_psk_new ffi+ case result of+ Left _ -> putStrLn " [skipped - PSK creation failed]"+ Right psk -> do+ action psk+ alloca $ \pskPtr -> do+ poke pskPtr psk+ void $ s2n_psk_free ffi pskPtr++--------------------------------------------------------------------------------+-- Cleanup Tests+--------------------------------------------------------------------------------++runCleanupTests :: S2nTlsFfi -> IO ()+runCleanupTests ffi = do+ putStrLn "\n[Cleanup]"+ hFlush stdout+ invoke "s2n_cleanup" $ s2n_cleanup ffi+ invoke "s2n_cleanup_final" $ s2n_cleanup_final ffi