From 8826ad1aa22b34fdf25bfaf38b02fcb15be2c930 Mon Sep 17 00:00:00 2001 From: mosuem Date: Wed, 15 Jul 2026 12:50:32 +0000 Subject: [PATCH 1/9] refactor: migrate ffigen configs to Dart and upgrade to ^20.0.0 - Upgrade ffigen dependency to ^20.0.0 in pubspec.yaml - Consolidate YAML ffigen configs into tool/ffigen.dart - Update tool/update-bindings.sh to run dart run tool/ffigen.dart - Re-generate native bindings --- lib/src/boringssl/bindings/ffigen.yaml | 43 - .../bindings/generated_bindings.dart | 152 +- lib/src/third_party/boringssl/ffigen.yaml | 266 ---- .../boringssl/generated_bindings.dart | 1238 +++++++++++------ pubspec.yaml | 2 +- tool/ffigen.dart | 357 +++++ tool/update-bindings.sh | 3 +- 7 files changed, 1292 insertions(+), 769 deletions(-) delete mode 100644 lib/src/boringssl/bindings/ffigen.yaml delete mode 100644 lib/src/third_party/boringssl/ffigen.yaml create mode 100644 tool/ffigen.dart diff --git a/lib/src/boringssl/bindings/ffigen.yaml b/lib/src/boringssl/bindings/ffigen.yaml deleted file mode 100644 index 444fdc066..000000000 --- a/lib/src/boringssl/bindings/ffigen.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: WebCrypto -description: 'Bindings to src/webcrypto.h.' -output: generated_bindings.dart -ffi-native: - assetId: 'package:webcrypto/webcrypto.dart' -headers: - entry-points: - - ../../../../src/webcrypto.h -comments: - style: any - length: full -sort: true -macros: - include: [] -enums: - include: [] -unnamed-enums: - include: [] -globals: - include: [] -structs: - include: [] - dependency-only: opaque -functions: - include: - - webcrypto_get_CBB_size -preamble: | - // Copyright 2021 Google LLC - // - // 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. - // - // ignore_for_file: unused_element - // ignore_for_file: non_constant_identifier_names diff --git a/lib/src/boringssl/bindings/generated_bindings.dart b/lib/src/boringssl/bindings/generated_bindings.dart index decbb4a9f..7f5c7d513 100644 --- a/lib/src/boringssl/bindings/generated_bindings.dart +++ b/lib/src/boringssl/bindings/generated_bindings.dart @@ -18,12 +18,154 @@ // AUTO GENERATED FILE, DO NOT EDIT. // // Generated by `package:ffigen`. -// ignore_for_file: type=lint +// ignore_for_file: type=lint, unused_import +@ffi.DefaultAsset('package:webcrypto/webcrypto.dart') +library; + import 'dart:ffi' as ffi; /// Helper function to get the size of CBB structure for FFI allocation. -@ffi.Native( - symbol: 'webcrypto_get_CBB_size', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native() external int webcrypto_get_CBB_size(); + +typedef __blkcnt64_t = ffi.Long; +typedef Dart__blkcnt64_t = int; +typedef __blkcnt_t = ffi.Long; +typedef Dart__blkcnt_t = int; +typedef __blksize_t = ffi.Long; +typedef Dart__blksize_t = int; +typedef __caddr_t = ffi.Pointer; +typedef __clock_t = ffi.Long; +typedef Dart__clock_t = int; +typedef __clockid_t = ffi.Int; +typedef Dart__clockid_t = int; +typedef __daddr_t = ffi.Int; +typedef Dart__daddr_t = int; +typedef __dev_t = ffi.UnsignedLong; +typedef Dart__dev_t = int; +typedef __fsblkcnt64_t = ffi.UnsignedLong; +typedef Dart__fsblkcnt64_t = int; +typedef __fsblkcnt_t = ffi.UnsignedLong; +typedef Dart__fsblkcnt_t = int; +typedef __fsfilcnt64_t = ffi.UnsignedLong; +typedef Dart__fsfilcnt64_t = int; +typedef __fsfilcnt_t = ffi.UnsignedLong; +typedef Dart__fsfilcnt_t = int; +typedef __fsword_t = ffi.Long; +typedef Dart__fsword_t = int; +typedef __gid_t = ffi.UnsignedInt; +typedef Dart__gid_t = int; +typedef __id_t = ffi.UnsignedInt; +typedef Dart__id_t = int; +typedef __ino64_t = ffi.UnsignedLong; +typedef Dart__ino64_t = int; +typedef __ino_t = ffi.UnsignedLong; +typedef Dart__ino_t = int; +typedef __int16_t = ffi.Short; +typedef Dart__int16_t = int; +typedef __int32_t = ffi.Int; +typedef Dart__int32_t = int; +typedef __int64_t = ffi.Long; +typedef Dart__int64_t = int; +typedef __int8_t = ffi.SignedChar; +typedef Dart__int8_t = int; +typedef __int_least16_t = __int16_t; +typedef __int_least32_t = __int32_t; +typedef __int_least64_t = __int64_t; +typedef __int_least8_t = __int8_t; +typedef __intmax_t = ffi.Long; +typedef Dart__intmax_t = int; +typedef __intptr_t = ffi.Long; +typedef Dart__intptr_t = int; +typedef __key_t = ffi.Int; +typedef Dart__key_t = int; +typedef __loff_t = __off64_t; +typedef __mode_t = ffi.UnsignedInt; +typedef Dart__mode_t = int; +typedef __nlink_t = ffi.UnsignedLong; +typedef Dart__nlink_t = int; +typedef __off64_t = ffi.Long; +typedef Dart__off64_t = int; +typedef __off_t = ffi.Long; +typedef Dart__off_t = int; +typedef __pid_t = ffi.Int; +typedef Dart__pid_t = int; +typedef __quad_t = ffi.Long; +typedef Dart__quad_t = int; +typedef __rlim64_t = ffi.UnsignedLong; +typedef Dart__rlim64_t = int; +typedef __rlim_t = ffi.UnsignedLong; +typedef Dart__rlim_t = int; +typedef __sig_atomic_t = ffi.Int; +typedef Dart__sig_atomic_t = int; +typedef __socklen_t = ffi.UnsignedInt; +typedef Dart__socklen_t = int; +typedef __ssize_t = ffi.Long; +typedef Dart__ssize_t = int; +typedef __suseconds64_t = ffi.Long; +typedef Dart__suseconds64_t = int; +typedef __suseconds_t = ffi.Long; +typedef Dart__suseconds_t = int; +typedef __syscall_slong_t = ffi.Long; +typedef Dart__syscall_slong_t = int; +typedef __syscall_ulong_t = ffi.UnsignedLong; +typedef Dart__syscall_ulong_t = int; +typedef __time_t = ffi.Long; +typedef Dart__time_t = int; +typedef __timer_t = ffi.Pointer; +typedef __u_char = ffi.UnsignedChar; +typedef Dart__u_char = int; +typedef __u_int = ffi.UnsignedInt; +typedef Dart__u_int = int; +typedef __u_long = ffi.UnsignedLong; +typedef Dart__u_long = int; +typedef __u_quad_t = ffi.UnsignedLong; +typedef Dart__u_quad_t = int; +typedef __u_short = ffi.UnsignedShort; +typedef Dart__u_short = int; +typedef __uid_t = ffi.UnsignedInt; +typedef Dart__uid_t = int; +typedef __uint16_t = ffi.UnsignedShort; +typedef Dart__uint16_t = int; +typedef __uint32_t = ffi.UnsignedInt; +typedef Dart__uint32_t = int; +typedef __uint64_t = ffi.UnsignedLong; +typedef Dart__uint64_t = int; +typedef __uint8_t = ffi.UnsignedChar; +typedef Dart__uint8_t = int; +typedef __uint_least16_t = __uint16_t; +typedef __uint_least32_t = __uint32_t; +typedef __uint_least64_t = __uint64_t; +typedef __uint_least8_t = __uint8_t; +typedef __uintmax_t = ffi.UnsignedLong; +typedef Dart__uintmax_t = int; +typedef __useconds_t = ffi.UnsignedInt; +typedef Dart__useconds_t = int; +typedef int_fast16_t = ffi.Long; +typedef Dartint_fast16_t = int; +typedef int_fast32_t = ffi.Long; +typedef Dartint_fast32_t = int; +typedef int_fast64_t = ffi.Long; +typedef Dartint_fast64_t = int; +typedef int_fast8_t = ffi.SignedChar; +typedef Dartint_fast8_t = int; +typedef int_least16_t = __int_least16_t; +typedef int_least32_t = __int_least32_t; +typedef int_least64_t = __int_least64_t; +typedef int_least8_t = __int_least8_t; +typedef intmax_t = __intmax_t; +typedef ptrdiff_t = ffi.Long; +typedef Dartptrdiff_t = int; +typedef uint_fast16_t = ffi.UnsignedLong; +typedef Dartuint_fast16_t = int; +typedef uint_fast32_t = ffi.UnsignedLong; +typedef Dartuint_fast32_t = int; +typedef uint_fast64_t = ffi.UnsignedLong; +typedef Dartuint_fast64_t = int; +typedef uint_fast8_t = ffi.UnsignedChar; +typedef Dartuint_fast8_t = int; +typedef uint_least16_t = __uint_least16_t; +typedef uint_least32_t = __uint_least32_t; +typedef uint_least64_t = __uint_least64_t; +typedef uint_least8_t = __uint_least8_t; +typedef uintmax_t = __uintmax_t; diff --git a/lib/src/third_party/boringssl/ffigen.yaml b/lib/src/third_party/boringssl/ffigen.yaml deleted file mode 100644 index 2ba91c638..000000000 --- a/lib/src/third_party/boringssl/ffigen.yaml +++ /dev/null @@ -1,266 +0,0 @@ -name: BoringSsl -description: 'Bindings to BoringSSL.' -language: c -output: 'generated_bindings.dart' -ffi-native: - assetId: 'package:webcrypto/webcrypto.dart' -headers: - entry-points: - - '../../../../third_party/boringssl/src/include/openssl/aead.h' - - '../../../../third_party/boringssl/src/include/openssl/aes.h' - - '../../../../third_party/boringssl/src/include/openssl/bn.h' - - '../../../../third_party/boringssl/src/include/openssl/bytestring.h' - - '../../../../third_party/boringssl/src/include/openssl/cipher.h' - - '../../../../third_party/boringssl/src/include/openssl/crypto.h' - - '../../../../third_party/boringssl/src/include/openssl/digest.h' - - '../../../../third_party/boringssl/src/include/openssl/ec.h' - - '../../../../third_party/boringssl/src/include/openssl/ecdh.h' - - '../../../../third_party/boringssl/src/include/openssl/ec_key.h' - - '../../../../third_party/boringssl/src/include/openssl/ecdsa.h' - - '../../../../third_party/boringssl/src/include/openssl/err.h' - - '../../../../third_party/boringssl/src/include/openssl/evp.h' - - '../../../../third_party/boringssl/src/include/openssl/hkdf.h' - - '../../../../third_party/boringssl/src/include/openssl/hmac.h' - - '../../../../third_party/boringssl/src/include/openssl/mem.h' - - '../../../../third_party/boringssl/src/include/openssl/rand.h' - - '../../../../third_party/boringssl/src/include/openssl/rsa.h' -compiler-opts: - - '-Ithird_party/boringssl/src/include' - # Make Clang see BoringSSL's prefixed declarations instead of recording the - # original names with `#pragma redefine_extname`. - - '-DBORINGSSL_PREFIX=webcrypto' - - '-U__PRAGMA_REDEFINE_EXTNAME' -comments: - style: any - length: full -sort: true -macros: - include: - - AES_BLOCK_SIZE - - EC_PKEY_NO_PUBKEY - - EVP_PKEY_EC - - EVP_PKEY_RSA - - HKDF_R_OUTPUT_TOO_LARGE - - NID_secp384r1 - - NID_secp521r1 - - NID_X9_62_prime256v1 - - RSA_PKCS1_OAEP_PADDING - - RSA_PKCS1_PADDING - - RSA_PKCS1_PSS_PADDING -enums: - include: - - point_conversion_form_t -unnamed-enums: - include: - - ERR_LIB_HKDF -structs: - include: - - cbs_st - - cbb_st - dependency-only: opaque -unions: - include: [] - dependency-only: opaque -globals: - include: [] -functions: - rename: - 'webcrypto_(.*)': '$1' - include: - # Source of truth for BoringSSL entry points bound from Dart. - - webcrypto_BN_bin2bn - - webcrypto_BN_bn2bin_padded - - webcrypto_BN_free - - webcrypto_BN_new - - webcrypto_BN_num_bytes - - webcrypto_BN_set_word - - webcrypto_CBB_cleanup - - webcrypto_CBB_data - - webcrypto_CBB_flush - - webcrypto_CBB_init - - webcrypto_CBB_len - - webcrypto_CBB_zero - - webcrypto_CRYPTO_memcmp - - webcrypto_ECDH_compute_key - - webcrypto_ECDSA_SIG_free - - webcrypto_ECDSA_SIG_get0 - - webcrypto_ECDSA_SIG_marshal - - webcrypto_ECDSA_SIG_new - - webcrypto_ECDSA_SIG_parse - - webcrypto_EC_GROUP_get0_order - - webcrypto_EC_GROUP_get_curve_name - - webcrypto_EC_GROUP_get_degree - - webcrypto_EC_KEY_check_key - - webcrypto_EC_KEY_free - - webcrypto_EC_KEY_generate_key - - webcrypto_EC_KEY_get0_group - - webcrypto_EC_KEY_get0_private_key - - webcrypto_EC_KEY_get0_public_key - - webcrypto_EC_KEY_get_enc_flags - - webcrypto_EC_KEY_new_by_curve_name - - webcrypto_EC_KEY_set_enc_flags - - webcrypto_EC_KEY_set_private_key - - webcrypto_EC_KEY_set_public_key - - webcrypto_EC_KEY_set_public_key_affine_coordinates - - webcrypto_EC_POINT_free - - webcrypto_EC_POINT_get_affine_coordinates_GFp - - webcrypto_EC_POINT_new - - webcrypto_EC_POINT_oct2point - - webcrypto_EC_POINT_point2cbb - - webcrypto_ERR_clear_error - - webcrypto_ERR_error_string_n - - webcrypto_ERR_get_error - - webcrypto_ERR_peek_error - - webcrypto_EVP_aead_aes_128_gcm - - webcrypto_EVP_aead_aes_256_gcm - - webcrypto_EVP_AEAD_CTX_free - - webcrypto_EVP_AEAD_CTX_new - - webcrypto_EVP_AEAD_CTX_open - - webcrypto_EVP_AEAD_CTX_seal - - webcrypto_EVP_AEAD_max_overhead - - webcrypto_EVP_aes_128_cbc - - webcrypto_EVP_aes_128_ctr - - webcrypto_EVP_aes_256_cbc - - webcrypto_EVP_aes_256_ctr - - webcrypto_EVP_CIPHER_CTX_free - - webcrypto_EVP_CIPHER_CTX_new - - webcrypto_EVP_CipherFinal_ex - - webcrypto_EVP_CipherInit_ex - - webcrypto_EVP_CIPHER_iv_length - - webcrypto_EVP_CipherUpdate - - webcrypto_EVP_DigestFinal - - webcrypto_EVP_DigestInit - - webcrypto_EVP_DigestSignFinal - - webcrypto_EVP_DigestSignInit - - webcrypto_EVP_DigestSignUpdate - - webcrypto_EVP_DigestUpdate - - webcrypto_EVP_DigestVerifyFinal - - webcrypto_EVP_DigestVerifyInit - - webcrypto_EVP_DigestVerifyUpdate - - webcrypto_EVP_marshal_private_key - - webcrypto_EVP_marshal_public_key - - webcrypto_EVP_MD_CTX_free - - webcrypto_EVP_MD_CTX_new - - webcrypto_EVP_MD_CTX_size - - webcrypto_EVP_parse_private_key - - webcrypto_EVP_parse_public_key - - webcrypto_EVP_PKEY_CTX_free - - webcrypto_EVP_PKEY_CTX_new - - webcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label - - webcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md - - webcrypto_EVP_PKEY_CTX_set_rsa_oaep_md - - webcrypto_EVP_PKEY_CTX_set_rsa_padding - - webcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen - - webcrypto_EVP_PKEY_decrypt - - webcrypto_EVP_PKEY_decrypt_init - - webcrypto_EVP_PKEY_encrypt - - webcrypto_EVP_PKEY_encrypt_init - - webcrypto_EVP_PKEY_free - - webcrypto_EVP_PKEY_get1_EC_KEY - - webcrypto_EVP_PKEY_get1_RSA - - webcrypto_EVP_PKEY_id - - webcrypto_EVP_PKEY_new - - webcrypto_EVP_PKEY_set1_EC_KEY - - webcrypto_EVP_PKEY_set1_RSA - - webcrypto_EVP_sha1 - - webcrypto_EVP_sha256 - - webcrypto_EVP_sha384 - - webcrypto_EVP_sha512 - - webcrypto_HKDF - - webcrypto_HMAC_CTX_free - - webcrypto_HMAC_CTX_new - - webcrypto_HMAC_Final - - webcrypto_HMAC_Init_ex - - webcrypto_HMAC_size - - webcrypto_HMAC_Update - - webcrypto_OPENSSL_malloc - - webcrypto_PKCS5_PBKDF2_HMAC - - webcrypto_RAND_bytes - - webcrypto_RSA_check_key - - webcrypto_RSA_free - - webcrypto_RSA_generate_key_ex - - webcrypto_RSA_get0_crt_params - - webcrypto_RSA_get0_factors - - webcrypto_RSA_get0_key - - webcrypto_RSA_new - - webcrypto_RSAPublicKey_dup - - webcrypto_RSA_set0_crt_params - - webcrypto_RSA_set0_factors - - webcrypto_RSA_set0_key - # These are referenced, just need to be sorted right. - - webcrypto_OPENSSL_free - - webcrypto_OPENSSL_memdup - - webcrypto_EVP_MD_size - # Not used but maybe they should be: - - webcrypto_EVP_AEAD_nonce_length - - webcrypto_EVP_AEAD_max_tag_len - # Not used by nice to have, maybe, or maybe we remove / comment them out - - webcrypto_EVP_AEAD_key_length - - webcrypto_BN_value_one - - webcrypto_BN_add - - webcrypto_BN_sub - - webcrypto_BN_cmp - - webcrypto_BN_lshift - - webcrypto_EVP_CIPHER_block_size - - webcrypto_EC_GROUP_new_by_curve_name - - webcrypto_EC_GROUP_free - - webcrypto_EVP_PKEY_set_type - # Self testing only.. - - webcrypto_BORINGSSL_self_test -preamble: | - /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). */ - // ignore_for_file: camel_case_types - // ignore_for_file: constant_identifier_names - // ignore_for_file: non_constant_identifier_names - // ignore_for_file: unused_element - // ignore_for_file: unused_field diff --git a/lib/src/third_party/boringssl/generated_bindings.dart b/lib/src/third_party/boringssl/generated_bindings.dart index cc237037b..4c94d6010 100644 --- a/lib/src/third_party/boringssl/generated_bindings.dart +++ b/lib/src/third_party/boringssl/generated_bindings.dart @@ -58,7 +58,10 @@ // AUTO GENERATED FILE, DO NOT EDIT. // // Generated by `package:ffigen`. -// ignore_for_file: type=lint +// ignore_for_file: type=lint, unused_import +@ffi.DefaultAsset('package:webcrypto/webcrypto.dart') +library; + import 'dart:ffi' as ffi; /// BN_add sets |r| = |a| + |b|, where |r| may be the same pointer as either |a| @@ -69,7 +72,7 @@ import 'dart:ffi' as ffi; ffi.Pointer, ffi.Pointer, ) ->(symbol: 'webcrypto_BN_add', assetId: 'package:webcrypto/webcrypto.dart') +>(symbol: 'webcrypto_BN_add') external int BN_add( ffi.Pointer r, ffi.Pointer a, @@ -86,9 +89,9 @@ external int BN_add( ffi.Size, ffi.Pointer, ) ->(symbol: 'webcrypto_BN_bin2bn', assetId: 'package:webcrypto/webcrypto.dart') +>(symbol: 'webcrypto_BN_bin2bn') external ffi.Pointer BN_bin2bn( - ffi.Pointer in1, + ffi.Pointer in$, int len, ffi.Pointer ret, ); @@ -99,44 +102,34 @@ external ffi.Pointer BN_bin2bn( /// returns 0. Otherwise, it returns 1. @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Size, ffi.Pointer) ->( - symbol: 'webcrypto_BN_bn2bin_padded', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_BN_bn2bin_padded') external int BN_bn2bin_padded( ffi.Pointer out, int len, - ffi.Pointer in1, + ffi.Pointer in$, ); /// BN_cmp returns a value less than, equal to or greater than zero if |a| is /// less than, equal to or greater than |b|, respectively. @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_BN_cmp', - assetId: 'package:webcrypto/webcrypto.dart', ) external int BN_cmp(ffi.Pointer a, ffi.Pointer b); /// BN_free frees the data referenced by |bn| and, if |bn| was originally /// allocated on the heap, frees |bn| also. -@ffi.Native)>( - symbol: 'webcrypto_BN_free', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native)>(symbol: 'webcrypto_BN_free') external void BN_free(ffi.Pointer bn); /// BN_lshift sets |r| equal to |a| << n. The |a| and |r| arguments may be the /// same |BIGNUM|. It returns one on success and zero on allocation failure. @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Int) ->(symbol: 'webcrypto_BN_lshift', assetId: 'package:webcrypto/webcrypto.dart') +>(symbol: 'webcrypto_BN_lshift') external int BN_lshift(ffi.Pointer r, ffi.Pointer a, int n); /// BN_new creates a new, allocated BIGNUM and initialises it. -@ffi.Native Function()>( - symbol: 'webcrypto_BN_new', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native Function()>(symbol: 'webcrypto_BN_new') external ffi.Pointer BN_new(); /// BN_num_bytes returns the minimum number of bytes needed to represent the @@ -147,7 +140,6 @@ external ffi.Pointer BN_new(); /// will always fit in |int|. @ffi.Native)>( symbol: 'webcrypto_BN_num_bytes', - assetId: 'package:webcrypto/webcrypto.dart', ) external int BN_num_bytes(ffi.Pointer bn); @@ -155,7 +147,6 @@ external int BN_num_bytes(ffi.Pointer bn); /// allocation failure. @ffi.Native, BN_ULONG)>( symbol: 'webcrypto_BN_set_word', - assetId: 'package:webcrypto/webcrypto.dart', ) external int BN_set_word(ffi.Pointer bn, int value); @@ -167,7 +158,7 @@ external int BN_set_word(ffi.Pointer bn, int value); ffi.Pointer, ffi.Pointer, ) ->(symbol: 'webcrypto_BN_sub', assetId: 'package:webcrypto/webcrypto.dart') +>(symbol: 'webcrypto_BN_sub') external int BN_sub( ffi.Pointer r, ffi.Pointer a, @@ -175,19 +166,13 @@ external int BN_sub( ); /// BN_value_one returns a static BIGNUM with value 1. -@ffi.Native Function()>( - symbol: 'webcrypto_BN_value_one', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native Function()>(symbol: 'webcrypto_BN_value_one') external ffi.Pointer BN_value_one(); /// BORINGSSL_self_test triggers most of the FIPS KAT-based self tests. It /// returns one on success and zero on error. It currently skips the SLH-DSA /// tests, which take a really long time to run. -@ffi.Native( - symbol: 'webcrypto_BORINGSSL_self_test', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native(symbol: 'webcrypto_BORINGSSL_self_test') external int BORINGSSL_self_test(); /// CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects @@ -199,7 +184,6 @@ external int BORINGSSL_self_test(); /// |CBB_zero|. @ffi.Native)>( symbol: 'webcrypto_CBB_cleanup', - assetId: 'package:webcrypto/webcrypto.dart', ) external void CBB_cleanup(ffi.Pointer cbb); @@ -210,7 +194,6 @@ external void CBB_cleanup(ffi.Pointer cbb); /// CBB with any active children. @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_CBB_data', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer CBB_data(ffi.Pointer cbb); @@ -219,10 +202,7 @@ external ffi.Pointer CBB_data(ffi.Pointer cbb); /// used after the children go out of scope, e.g. when local |CBB| objects are /// added as children to a |CBB| that persists after a function returns. This /// function returns one on success or zero on error. -@ffi.Native)>( - symbol: 'webcrypto_CBB_flush', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native)>(symbol: 'webcrypto_CBB_flush') external int CBB_flush(ffi.Pointer cbb); /// CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as @@ -230,7 +210,6 @@ external int CBB_flush(ffi.Pointer cbb); /// zero on allocation failure. @ffi.Native, ffi.Size)>( symbol: 'webcrypto_CBB_init', - assetId: 'package:webcrypto/webcrypto.dart', ) external int CBB_init(ffi.Pointer cbb, int initial_capacity); @@ -239,20 +218,14 @@ external int CBB_init(ffi.Pointer cbb, int initial_capacity); /// /// To avoid unfinalized length prefixes, it is a fatal error to call this on a /// CBB with any active children. -@ffi.Native)>( - symbol: 'webcrypto_CBB_len', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native)>(symbol: 'webcrypto_CBB_len') external int CBB_len(ffi.Pointer cbb); /// CBB_zero sets an uninitialised |cbb| to the zero state. It must be /// initialised with |CBB_init| or |CBB_init_fixed| before use, but it is safe to /// call |CBB_cleanup| without a successful |CBB_init|. This may be used for more /// uniform cleanup of a |CBB|. -@ffi.Native)>( - symbol: 'webcrypto_CBB_zero', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native)>(symbol: 'webcrypto_CBB_zero') external void CBB_zero(ffi.Pointer cbb); /// CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It @@ -262,10 +235,7 @@ external void CBB_zero(ffi.Pointer cbb); /// non-zero. @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) ->( - symbol: 'webcrypto_CRYPTO_memcmp', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_CRYPTO_memcmp') external int CRYPTO_memcmp( ffi.Pointer a, ffi.Pointer b, @@ -287,7 +257,7 @@ external int CRYPTO_memcmp( ffi.Pointer< ffi.NativeFunction< ffi.Pointer Function( - ffi.Pointer in1, + ffi.Pointer in$, ffi.Size inlen, ffi.Pointer out, ffi.Pointer outlen, @@ -295,10 +265,7 @@ external int CRYPTO_memcmp( > >, ) ->( - symbol: 'webcrypto_ECDH_compute_key', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_ECDH_compute_key') external int ECDH_compute_key( ffi.Pointer out, int outlen, @@ -307,7 +274,7 @@ external int ECDH_compute_key( ffi.Pointer< ffi.NativeFunction< ffi.Pointer Function( - ffi.Pointer in1, + ffi.Pointer in$, ffi.Size inlen, ffi.Pointer out, ffi.Pointer outlen, @@ -320,7 +287,6 @@ external int ECDH_compute_key( /// ECDSA_SIG_free frees |sig| its member |BIGNUM|s. @ffi.Native)>( symbol: 'webcrypto_ECDSA_SIG_free', - assetId: 'package:webcrypto/webcrypto.dart', ) external void ECDSA_SIG_free(ffi.Pointer sig); @@ -332,10 +298,7 @@ external void ECDSA_SIG_free(ffi.Pointer sig); ffi.Pointer>, ffi.Pointer>, ) ->( - symbol: 'webcrypto_ECDSA_SIG_get0', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_ECDSA_SIG_get0') external void ECDSA_SIG_get0( ffi.Pointer sig, ffi.Pointer> out_r, @@ -346,7 +309,6 @@ external void ECDSA_SIG_get0( /// the result to |cbb|. It returns one on success and zero on error. @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_ECDSA_SIG_marshal', - assetId: 'package:webcrypto/webcrypto.dart', ) external int ECDSA_SIG_marshal( ffi.Pointer cbb, @@ -356,7 +318,6 @@ external int ECDSA_SIG_marshal( /// ECDSA_SIG_new returns a fresh |ECDSA_SIG| structure or NULL on error. @ffi.Native Function()>( symbol: 'webcrypto_ECDSA_SIG_new', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer ECDSA_SIG_new(); @@ -364,7 +325,6 @@ external ffi.Pointer ECDSA_SIG_new(); /// advances |cbs|. It returns a newly-allocated |ECDSA_SIG| or NULL on error. @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_ECDSA_SIG_parse', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer ECDSA_SIG_parse(ffi.Pointer cbs); @@ -376,7 +336,6 @@ external ffi.Pointer ECDSA_SIG_parse(ffi.Pointer cbs); /// either may ignore this function. @ffi.Native)>( symbol: 'webcrypto_EC_GROUP_free', - assetId: 'package:webcrypto/webcrypto.dart', ) external void EC_GROUP_free(ffi.Pointer group); @@ -384,14 +343,12 @@ external void EC_GROUP_free(ffi.Pointer group); /// |group| that specifies the order of the group. @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EC_GROUP_get0_order', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EC_GROUP_get0_order(ffi.Pointer group); /// EC_GROUP_get_curve_name returns a NID that identifies |group|. @ffi.Native)>( symbol: 'webcrypto_EC_GROUP_get_curve_name', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EC_GROUP_get_curve_name(ffi.Pointer group); @@ -399,7 +356,6 @@ external int EC_GROUP_get_curve_name(ffi.Pointer group); /// element of the field underlying |group|. @ffi.Native)>( symbol: 'webcrypto_EC_GROUP_get_degree', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EC_GROUP_get_degree(ffi.Pointer group); @@ -422,7 +378,6 @@ external int EC_GROUP_get_degree(ffi.Pointer group); /// more modern primitives. @ffi.Native Function(ffi.Int)>( symbol: 'webcrypto_EC_GROUP_new_by_curve_name', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EC_GROUP_new_by_curve_name(int nid); @@ -432,14 +387,12 @@ external ffi.Pointer EC_GROUP_new_by_curve_name(int nid); /// about the problem can be found on the error stack. @ffi.Native)>( symbol: 'webcrypto_EC_KEY_check_key', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EC_KEY_check_key(ffi.Pointer key); /// EC_KEY_free frees all the data owned by |key| and |key| itself. @ffi.Native)>( symbol: 'webcrypto_EC_KEY_free', - assetId: 'package:webcrypto/webcrypto.dart', ) external void EC_KEY_free(ffi.Pointer key); @@ -448,21 +401,18 @@ external void EC_KEY_free(ffi.Pointer key); /// or zero otherwise. @ffi.Native)>( symbol: 'webcrypto_EC_KEY_generate_key', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EC_KEY_generate_key(ffi.Pointer key); /// EC_KEY_get0_group returns a pointer to the |EC_GROUP| object inside |key|. @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EC_KEY_get0_group', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EC_KEY_get0_group(ffi.Pointer key); /// EC_KEY_get0_private_key returns a pointer to the private key inside |key|. @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EC_KEY_get0_private_key', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EC_KEY_get0_private_key(ffi.Pointer key); @@ -470,7 +420,6 @@ external ffi.Pointer EC_KEY_get0_private_key(ffi.Pointer key); /// |key|. @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EC_KEY_get0_public_key', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EC_KEY_get0_public_key(ffi.Pointer key); @@ -478,7 +427,6 @@ external ffi.Pointer EC_KEY_get0_public_key(ffi.Pointer key); /// bitwise-OR of |EC_PKEY_*| values. @ffi.Native)>( symbol: 'webcrypto_EC_KEY_get_enc_flags', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EC_KEY_get_enc_flags(ffi.Pointer key); @@ -486,7 +434,6 @@ external int EC_KEY_get_enc_flags(ffi.Pointer key); /// or NULL on error. @ffi.Native Function(ffi.Int)>( symbol: 'webcrypto_EC_KEY_new_by_curve_name', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EC_KEY_new_by_curve_name(int nid); @@ -494,7 +441,6 @@ external ffi.Pointer EC_KEY_new_by_curve_name(int nid); /// bitwise-OR of |EC_PKEY_*| values. @ffi.Native, ffi.UnsignedInt)>( symbol: 'webcrypto_EC_KEY_set_enc_flags', - assetId: 'package:webcrypto/webcrypto.dart', ) external void EC_KEY_set_enc_flags(ffi.Pointer key, int flags); @@ -503,7 +449,6 @@ external void EC_KEY_set_enc_flags(ffi.Pointer key, int flags); /// configured (see |EC_KEY_set_group| and |EC_KEY_new_by_curve_name|). @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EC_KEY_set_private_key', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EC_KEY_set_private_key( ffi.Pointer key, @@ -516,7 +461,6 @@ external int EC_KEY_set_private_key( /// |pub| must also belong to that group, and must not be the point at infinity. @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EC_KEY_set_public_key', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EC_KEY_set_public_key( ffi.Pointer key, @@ -532,10 +476,7 @@ external int EC_KEY_set_public_key( ffi.Pointer, ffi.Pointer, ) ->( - symbol: 'webcrypto_EC_KEY_set_public_key_affine_coordinates', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EC_KEY_set_public_key_affine_coordinates') external int EC_KEY_set_public_key_affine_coordinates( ffi.Pointer key, ffi.Pointer x, @@ -545,7 +486,6 @@ external int EC_KEY_set_public_key_affine_coordinates( /// EC_POINT_free frees |point| and the data that it points to. @ffi.Native)>( symbol: 'webcrypto_EC_POINT_free', - assetId: 'package:webcrypto/webcrypto.dart', ) external void EC_POINT_free(ffi.Pointer point); @@ -563,10 +503,7 @@ external void EC_POINT_free(ffi.Pointer point); ffi.Pointer, ffi.Pointer, ) ->( - symbol: 'webcrypto_EC_POINT_get_affine_coordinates_GFp', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EC_POINT_get_affine_coordinates_GFp') external int EC_POINT_get_affine_coordinates_GFp( ffi.Pointer group, ffi.Pointer point, @@ -579,7 +516,6 @@ external int EC_POINT_get_affine_coordinates_GFp( /// on error. @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EC_POINT_new', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EC_POINT_new(ffi.Pointer group); @@ -595,10 +531,7 @@ external ffi.Pointer EC_POINT_new(ffi.Pointer group); ffi.Size, ffi.Pointer, ) ->( - symbol: 'webcrypto_EC_POINT_oct2point', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EC_POINT_oct2point') external int EC_POINT_oct2point( ffi.Pointer group, ffi.Pointer point, @@ -615,13 +548,10 @@ external int EC_POINT_oct2point( ffi.Pointer, ffi.Pointer, ffi.Pointer, - ffi.Int32, + ffi.UnsignedInt, ffi.Pointer, ) ->( - symbol: 'webcrypto_EC_POINT_point2cbb', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EC_POINT_point2cbb') external int EC_POINT_point2cbb( ffi.Pointer out, ffi.Pointer group, @@ -631,10 +561,7 @@ external int EC_POINT_point2cbb( ); /// ERR_clear_error clears the error queue for the current thread. -@ffi.Native( - symbol: 'webcrypto_ERR_clear_error', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native(symbol: 'webcrypto_ERR_clear_error') external void ERR_clear_error(); /// ERR_error_string_n generates a human-readable string representing @@ -650,10 +577,7 @@ external void ERR_clear_error(); /// are ASCII text. @ffi.Native< ffi.Pointer Function(ffi.Uint32, ffi.Pointer, ffi.Size) ->( - symbol: 'webcrypto_ERR_error_string_n', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_ERR_error_string_n') external ffi.Pointer ERR_error_string_n( int packed_error, ffi.Pointer buf, @@ -663,25 +587,18 @@ external ffi.Pointer ERR_error_string_n( /// ERR_get_error gets the packed error code for the least recent error and /// removes that error from the queue. If there are no errors in the queue then /// it returns zero. -@ffi.Native( - symbol: 'webcrypto_ERR_get_error', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native(symbol: 'webcrypto_ERR_get_error') external int ERR_get_error(); /// The "peek" functions act like the |ERR_get_error| functions, above, but they /// do not remove the error from the queue. -@ffi.Native( - symbol: 'webcrypto_ERR_peek_error', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native(symbol: 'webcrypto_ERR_peek_error') external int ERR_peek_error(); /// EVP_AEAD_CTX_free calls |EVP_AEAD_CTX_cleanup| and |OPENSSL_free| on /// |ctx|. @ffi.Native)>( symbol: 'webcrypto_EVP_AEAD_CTX_free', - assetId: 'package:webcrypto/webcrypto.dart', ) external void EVP_AEAD_CTX_free(ffi.Pointer ctx); @@ -694,10 +611,7 @@ external void EVP_AEAD_CTX_free(ffi.Pointer ctx); ffi.Size, ffi.Size, ) ->( - symbol: 'webcrypto_EVP_AEAD_CTX_new', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_AEAD_CTX_new') external ffi.Pointer EVP_AEAD_CTX_new( ffi.Pointer aead, ffi.Pointer key, @@ -737,10 +651,7 @@ external ffi.Pointer EVP_AEAD_CTX_new( ffi.Pointer, ffi.Size, ) ->( - symbol: 'webcrypto_EVP_AEAD_CTX_open', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_AEAD_CTX_open') external int EVP_AEAD_CTX_open( ffi.Pointer ctx, ffi.Pointer out, @@ -748,7 +659,7 @@ external int EVP_AEAD_CTX_open( int max_out_len, ffi.Pointer nonce, int nonce_len, - ffi.Pointer in1, + ffi.Pointer in$, int in_len, ffi.Pointer ad, int ad_len, @@ -787,10 +698,7 @@ external int EVP_AEAD_CTX_open( ffi.Pointer, ffi.Size, ) ->( - symbol: 'webcrypto_EVP_AEAD_CTX_seal', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_AEAD_CTX_seal') external int EVP_AEAD_CTX_seal( ffi.Pointer ctx, ffi.Pointer out, @@ -798,7 +706,7 @@ external int EVP_AEAD_CTX_seal( int max_out_len, ffi.Pointer nonce, int nonce_len, - ffi.Pointer in1, + ffi.Pointer in$, int in_len, ffi.Pointer ad, int ad_len, @@ -808,7 +716,6 @@ external int EVP_AEAD_CTX_seal( /// |aead|. @ffi.Native)>( symbol: 'webcrypto_EVP_AEAD_key_length', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_AEAD_key_length(ffi.Pointer aead); @@ -816,7 +723,6 @@ external int EVP_AEAD_key_length(ffi.Pointer aead); /// by the act of sealing data with |aead|. @ffi.Native)>( symbol: 'webcrypto_EVP_AEAD_max_overhead', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_AEAD_max_overhead(ffi.Pointer aead); @@ -825,7 +731,6 @@ external int EVP_AEAD_max_overhead(ffi.Pointer aead); /// |EVP_AEAD_CTX_init|. @ffi.Native)>( symbol: 'webcrypto_EVP_AEAD_max_tag_len', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_AEAD_max_tag_len(ffi.Pointer aead); @@ -833,7 +738,6 @@ external int EVP_AEAD_max_tag_len(ffi.Pointer aead); /// for |aead|. @ffi.Native)>( symbol: 'webcrypto_EVP_AEAD_nonce_length', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_AEAD_nonce_length(ffi.Pointer aead); @@ -841,7 +745,6 @@ external int EVP_AEAD_nonce_length(ffi.Pointer aead); /// |ctx| itself. @ffi.Native)>( symbol: 'webcrypto_EVP_CIPHER_CTX_free', - assetId: 'package:webcrypto/webcrypto.dart', ) external void EVP_CIPHER_CTX_free(ffi.Pointer ctx); @@ -849,7 +752,6 @@ external void EVP_CIPHER_CTX_free(ffi.Pointer ctx); /// |EVP_CIPHER_CTX_init| and returns it, or NULL on allocation failure. @ffi.Native Function()>( symbol: 'webcrypto_EVP_CIPHER_CTX_new', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_CIPHER_CTX_new(); @@ -857,7 +759,6 @@ external ffi.Pointer EVP_CIPHER_CTX_new(); /// if |cipher| is a stream cipher. @ffi.Native)>( symbol: 'webcrypto_EVP_CIPHER_block_size', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_CIPHER_block_size(ffi.Pointer cipher); @@ -865,7 +766,6 @@ external int EVP_CIPHER_block_size(ffi.Pointer cipher); /// |cipher| doesn't take an IV. @ffi.Native)>( symbol: 'webcrypto_EVP_CIPHER_iv_length', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_CIPHER_iv_length(ffi.Pointer cipher); @@ -880,10 +780,7 @@ external int EVP_CIPHER_iv_length(ffi.Pointer cipher); ffi.Pointer, ffi.Pointer, ) ->( - symbol: 'webcrypto_EVP_CipherFinal_ex', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_CipherFinal_ex') external int EVP_CipherFinal_ex( ffi.Pointer ctx, ffi.Pointer out, @@ -906,10 +803,7 @@ external int EVP_CipherFinal_ex( ffi.Pointer, ffi.Int, ) ->( - symbol: 'webcrypto_EVP_CipherInit_ex', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_CipherInit_ex') external int EVP_CipherInit_ex( ffi.Pointer ctx, ffi.Pointer cipher, @@ -936,15 +830,12 @@ external int EVP_CipherInit_ex( ffi.Pointer, ffi.Int, ) ->( - symbol: 'webcrypto_EVP_CipherUpdate', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_CipherUpdate') external int EVP_CipherUpdate( ffi.Pointer ctx, ffi.Pointer out, ffi.Pointer out_len, - ffi.Pointer in1, + ffi.Pointer in$, int in_len, ); @@ -956,10 +847,7 @@ external int EVP_CipherUpdate( ffi.Pointer, ffi.Pointer, ) ->( - symbol: 'webcrypto_EVP_DigestFinal', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_DigestFinal') external int EVP_DigestFinal( ffi.Pointer ctx, ffi.Pointer md_out, @@ -970,7 +858,6 @@ external int EVP_DigestFinal( /// initialised before use. @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_DigestInit', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_DigestInit( ffi.Pointer ctx, @@ -995,10 +882,7 @@ external int EVP_DigestInit( ffi.Pointer, ffi.Pointer, ) ->( - symbol: 'webcrypto_EVP_DigestSignFinal', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_DigestSignFinal') external int EVP_DigestSignFinal( ffi.Pointer ctx, ffi.Pointer out_sig, @@ -1027,10 +911,7 @@ external int EVP_DigestSignFinal( ffi.Pointer, ffi.Pointer, ) ->( - symbol: 'webcrypto_EVP_DigestSignInit', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_DigestSignInit') external int EVP_DigestSignInit( ffi.Pointer ctx, ffi.Pointer> pctx, @@ -1047,10 +928,7 @@ external int EVP_DigestSignInit( /// single-shot operation. @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) ->( - symbol: 'webcrypto_EVP_DigestSignUpdate', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_DigestSignUpdate') external int EVP_DigestSignUpdate( ffi.Pointer ctx, ffi.Pointer data, @@ -1061,10 +939,7 @@ external int EVP_DigestSignUpdate( /// in |ctx|. It returns one. @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) ->( - symbol: 'webcrypto_EVP_DigestUpdate', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_DigestUpdate') external int EVP_DigestUpdate( ffi.Pointer ctx, ffi.Pointer data, @@ -1080,10 +955,7 @@ external int EVP_DigestUpdate( /// single-shot verification. @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) ->( - symbol: 'webcrypto_EVP_DigestVerifyFinal', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_DigestVerifyFinal') external int EVP_DigestVerifyFinal( ffi.Pointer ctx, ffi.Pointer sig, @@ -1112,10 +984,7 @@ external int EVP_DigestVerifyFinal( ffi.Pointer, ffi.Pointer, ) ->( - symbol: 'webcrypto_EVP_DigestVerifyInit', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_DigestVerifyInit') external int EVP_DigestVerifyInit( ffi.Pointer ctx, ffi.Pointer> pctx, @@ -1132,10 +1001,7 @@ external int EVP_DigestVerifyInit( /// single-shot verification. @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) ->( - symbol: 'webcrypto_EVP_DigestVerifyUpdate', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_DigestVerifyUpdate') external int EVP_DigestVerifyUpdate( ffi.Pointer ctx, ffi.Pointer data, @@ -1145,7 +1011,6 @@ external int EVP_DigestVerifyUpdate( /// EVP_MD_CTX_free calls |EVP_MD_CTX_cleanup| and then frees |ctx| itself. @ffi.Native)>( symbol: 'webcrypto_EVP_MD_CTX_free', - assetId: 'package:webcrypto/webcrypto.dart', ) external void EVP_MD_CTX_free(ffi.Pointer ctx); @@ -1154,7 +1019,6 @@ external void EVP_MD_CTX_free(ffi.Pointer ctx); /// release the resulting object. @ffi.Native Function()>( symbol: 'webcrypto_EVP_MD_CTX_new', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_MD_CTX_new(); @@ -1162,21 +1026,18 @@ external ffi.Pointer EVP_MD_CTX_new(); /// will crash if a digest hasn't been set on |ctx|. @ffi.Native)>( symbol: 'webcrypto_EVP_MD_CTX_size', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_MD_CTX_size(ffi.Pointer ctx); /// EVP_MD_size returns the digest size of |md|, in bytes. @ffi.Native)>( symbol: 'webcrypto_EVP_MD_size', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_MD_size(ffi.Pointer md); /// EVP_PKEY_CTX_free frees |ctx| and the data it owns. @ffi.Native)>( symbol: 'webcrypto_EVP_PKEY_CTX_free', - assetId: 'package:webcrypto/webcrypto.dart', ) external void EVP_PKEY_CTX_free(ffi.Pointer ctx); @@ -1184,10 +1045,7 @@ external void EVP_PKEY_CTX_free(ffi.Pointer ctx); /// returns the context or NULL on error. @ffi.Native< ffi.Pointer Function(ffi.Pointer, ffi.Pointer) ->( - symbol: 'webcrypto_EVP_PKEY_CTX_new', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_PKEY_CTX_new') external ffi.Pointer EVP_PKEY_CTX_new( ffi.Pointer pkey, ffi.Pointer e, @@ -1200,10 +1058,7 @@ external ffi.Pointer EVP_PKEY_CTX_new( /// Returns one on success or zero on error. @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) ->( - symbol: 'webcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label') external int EVP_PKEY_CTX_set0_rsa_oaep_label( ffi.Pointer ctx, ffi.Pointer label, @@ -1218,7 +1073,6 @@ external int EVP_PKEY_CTX_set0_rsa_oaep_label( /// default and not call this function. @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_PKEY_CTX_set_rsa_mgf1_md( ffi.Pointer ctx, @@ -1232,7 +1086,6 @@ external int EVP_PKEY_CTX_set_rsa_mgf1_md( /// TODO(davidben): Remove the default and require callers specify this. @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_CTX_set_rsa_oaep_md', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_PKEY_CTX_set_rsa_oaep_md( ffi.Pointer ctx, @@ -1244,7 +1097,6 @@ external int EVP_PKEY_CTX_set_rsa_oaep_md( /// default, the padding is |RSA_PKCS1_PADDING|. @ffi.Native, ffi.Int)>( symbol: 'webcrypto_EVP_PKEY_CTX_set_rsa_padding', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_PKEY_CTX_set_rsa_padding( ffi.Pointer ctx, @@ -1264,7 +1116,6 @@ external int EVP_PKEY_CTX_set_rsa_padding( /// Returns one on success or zero on error. @ffi.Native, ffi.Int)>( symbol: 'webcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_PKEY_CTX_set_rsa_pss_saltlen( ffi.Pointer ctx, @@ -1289,15 +1140,12 @@ external int EVP_PKEY_CTX_set_rsa_pss_saltlen( ffi.Pointer, ffi.Size, ) ->( - symbol: 'webcrypto_EVP_PKEY_decrypt', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_PKEY_decrypt') external int EVP_PKEY_decrypt( ffi.Pointer ctx, ffi.Pointer out, ffi.Pointer out_len, - ffi.Pointer in1, + ffi.Pointer in$, int in_len, ); @@ -1307,7 +1155,6 @@ external int EVP_PKEY_decrypt( /// It returns one on success or zero on error. @ffi.Native)>( symbol: 'webcrypto_EVP_PKEY_decrypt_init', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_PKEY_decrypt_init(ffi.Pointer ctx); @@ -1329,15 +1176,12 @@ external int EVP_PKEY_decrypt_init(ffi.Pointer ctx); ffi.Pointer, ffi.Size, ) ->( - symbol: 'webcrypto_EVP_PKEY_encrypt', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_EVP_PKEY_encrypt') external int EVP_PKEY_encrypt( ffi.Pointer ctx, ffi.Pointer out, ffi.Pointer out_len, - ffi.Pointer in1, + ffi.Pointer in$, int in_len, ); @@ -1347,7 +1191,6 @@ external int EVP_PKEY_encrypt( /// It returns one on success or zero on error. @ffi.Native)>( symbol: 'webcrypto_EVP_PKEY_encrypt_init', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_PKEY_encrypt_init(ffi.Pointer ctx); @@ -1355,19 +1198,16 @@ external int EVP_PKEY_encrypt_init(ffi.Pointer ctx); /// reference count drops to zero. @ffi.Native)>( symbol: 'webcrypto_EVP_PKEY_free', - assetId: 'package:webcrypto/webcrypto.dart', ) external void EVP_PKEY_free(ffi.Pointer pkey); @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_get1_EC_KEY', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_PKEY_get1_EC_KEY(ffi.Pointer pkey); @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_get1_RSA', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_PKEY_get1_RSA(ffi.Pointer pkey); @@ -1379,21 +1219,16 @@ external ffi.Pointer EVP_PKEY_get1_RSA(ffi.Pointer pkey); /// |EVP_PKEY_get_ec_curve_nid|. @ffi.Native)>( symbol: 'webcrypto_EVP_PKEY_id', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_PKEY_id(ffi.Pointer pkey); /// EVP_PKEY_new creates a new, empty public-key object and returns it or NULL /// on allocation failure. -@ffi.Native Function()>( - symbol: 'webcrypto_EVP_PKEY_new', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native Function()>(symbol: 'webcrypto_EVP_PKEY_new') external ffi.Pointer EVP_PKEY_new(); @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_set1_EC_KEY', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_PKEY_set1_EC_KEY( ffi.Pointer pkey, @@ -1428,7 +1263,6 @@ external int EVP_PKEY_set1_EC_KEY( /// callers are exposed to |EVP_PKEY_RSA_PSS| by default. @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_set1_RSA', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_PKEY_set1_RSA( ffi.Pointer pkey, @@ -1454,7 +1288,6 @@ external int EVP_PKEY_set1_RSA( /// other values of |type| will result in an error. @ffi.Native, ffi.Int)>( symbol: 'webcrypto_EVP_PKEY_set_type', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_PKEY_set_type(ffi.Pointer pkey, int type); @@ -1467,7 +1300,6 @@ external int EVP_PKEY_set_type(ffi.Pointer pkey, int type); /// parameters, only use 12-byte nonces. @ffi.Native Function()>( symbol: 'webcrypto_EVP_aead_aes_128_gcm', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_aead_aes_128_gcm(); @@ -1480,31 +1312,26 @@ external ffi.Pointer EVP_aead_aes_128_gcm(); /// parameters, only use 12-byte nonces. @ffi.Native Function()>( symbol: 'webcrypto_EVP_aead_aes_256_gcm', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_aead_aes_256_gcm(); @ffi.Native Function()>( symbol: 'webcrypto_EVP_aes_128_cbc', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_aes_128_cbc(); @ffi.Native Function()>( symbol: 'webcrypto_EVP_aes_128_ctr', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_aes_128_ctr(); @ffi.Native Function()>( symbol: 'webcrypto_EVP_aes_256_cbc', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_aes_256_cbc(); @ffi.Native Function()>( symbol: 'webcrypto_EVP_aes_256_ctr', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_aes_256_ctr(); @@ -1513,7 +1340,6 @@ external ffi.Pointer EVP_aes_256_ctr(); /// success and zero on error. @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_marshal_private_key', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_marshal_private_key( ffi.Pointer cbb, @@ -1525,7 +1351,6 @@ external int EVP_marshal_private_key( /// success and zero on error. @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_marshal_public_key', - assetId: 'package:webcrypto/webcrypto.dart', ) external int EVP_marshal_public_key( ffi.Pointer cbb, @@ -1558,7 +1383,6 @@ external int EVP_marshal_public_key( /// ignored. @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EVP_parse_private_key', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_parse_private_key(ffi.Pointer cbs); @@ -1583,32 +1407,19 @@ external ffi.Pointer EVP_parse_private_key(ffi.Pointer cbs); /// size or EC curve. @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EVP_parse_public_key', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer EVP_parse_public_key(ffi.Pointer cbs); -@ffi.Native Function()>( - symbol: 'webcrypto_EVP_sha1', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native Function()>(symbol: 'webcrypto_EVP_sha1') external ffi.Pointer EVP_sha1(); -@ffi.Native Function()>( - symbol: 'webcrypto_EVP_sha256', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native Function()>(symbol: 'webcrypto_EVP_sha256') external ffi.Pointer EVP_sha256(); -@ffi.Native Function()>( - symbol: 'webcrypto_EVP_sha384', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native Function()>(symbol: 'webcrypto_EVP_sha384') external ffi.Pointer EVP_sha384(); -@ffi.Native Function()>( - symbol: 'webcrypto_EVP_sha512', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native Function()>(symbol: 'webcrypto_EVP_sha512') external ffi.Pointer EVP_sha512(); /// HKDF computes HKDF (as specified by RFC 5869) of initial keying material @@ -1630,7 +1441,7 @@ external ffi.Pointer EVP_sha512(); ffi.Pointer, ffi.Size, ) ->(symbol: 'webcrypto_HKDF', assetId: 'package:webcrypto/webcrypto.dart') +>(symbol: 'webcrypto_HKDF') external int HKDF( ffi.Pointer out_key, int out_len, @@ -1646,17 +1457,13 @@ external int HKDF( /// HMAC_CTX_free calls |HMAC_CTX_cleanup| and then frees |ctx| itself. @ffi.Native)>( symbol: 'webcrypto_HMAC_CTX_free', - assetId: 'package:webcrypto/webcrypto.dart', ) external void HMAC_CTX_free(ffi.Pointer ctx); /// HMAC_CTX_new allocates and initialises a new |HMAC_CTX| and returns it, or /// NULL on allocation failure. The caller must use |HMAC_CTX_free| to release /// the resulting object. -@ffi.Native Function()>( - symbol: 'webcrypto_HMAC_CTX_new', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native Function()>(symbol: 'webcrypto_HMAC_CTX_new') external ffi.Pointer HMAC_CTX_new(); /// HMAC_Final completes the HMAC operation in |ctx| and writes the result to @@ -1670,7 +1477,7 @@ external ffi.Pointer HMAC_CTX_new(); ffi.Pointer, ffi.Pointer, ) ->(symbol: 'webcrypto_HMAC_Final', assetId: 'package:webcrypto/webcrypto.dart') +>(symbol: 'webcrypto_HMAC_Final') external int HMAC_Final( ffi.Pointer ctx, ffi.Pointer out, @@ -1694,7 +1501,7 @@ external int HMAC_Final( ffi.Pointer, ffi.Pointer, ) ->(symbol: 'webcrypto_HMAC_Init_ex', assetId: 'package:webcrypto/webcrypto.dart') +>(symbol: 'webcrypto_HMAC_Init_ex') external int HMAC_Init_ex( ffi.Pointer ctx, ffi.Pointer key, @@ -1707,7 +1514,7 @@ external int HMAC_Init_ex( /// operation in |ctx|. It returns one. @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) ->(symbol: 'webcrypto_HMAC_Update', assetId: 'package:webcrypto/webcrypto.dart') +>(symbol: 'webcrypto_HMAC_Update') external int HMAC_Update( ffi.Pointer ctx, ffi.Pointer data, @@ -1718,7 +1525,6 @@ external int HMAC_Update( /// |ctx|. On entry, |ctx| must have been setup with |HMAC_Init_ex|. @ffi.Native)>( symbol: 'webcrypto_HMAC_size', - assetId: 'package:webcrypto/webcrypto.dart', ) external int HMAC_size(ffi.Pointer ctx); @@ -1727,7 +1533,6 @@ external int HMAC_size(ffi.Pointer ctx); /// It must only be used on on |ptr| values obtained from |OPENSSL_malloc| @ffi.Native)>( symbol: 'webcrypto_OPENSSL_free', - assetId: 'package:webcrypto/webcrypto.dart', ) external void OPENSSL_free(ffi.Pointer ptr); @@ -1737,7 +1542,6 @@ external void OPENSSL_free(ffi.Pointer ptr); /// push |ERR_R_MALLOC_FAILURE| onto the openssl error stack. @ffi.Native Function(ffi.Size)>( symbol: 'webcrypto_OPENSSL_malloc', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer OPENSSL_malloc(int size); @@ -1746,7 +1550,6 @@ external ffi.Pointer OPENSSL_malloc(int size); /// |OPENSSL_free|. @ffi.Native Function(ffi.Pointer, ffi.Size)>( symbol: 'webcrypto_OPENSSL_memdup', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer OPENSSL_memdup( ffi.Pointer data, @@ -1767,10 +1570,7 @@ external ffi.Pointer OPENSSL_memdup( ffi.Size, ffi.Pointer, ) ->( - symbol: 'webcrypto_PKCS5_PBKDF2_HMAC', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_PKCS5_PBKDF2_HMAC') external int PKCS5_PBKDF2_HMAC( ffi.Pointer password, int password_len, @@ -1786,7 +1586,6 @@ external int PKCS5_PBKDF2_HMAC( /// event that sufficient random data can not be obtained, |abort| is called. @ffi.Native, ffi.Size)>( symbol: 'webcrypto_RAND_bytes', - assetId: 'package:webcrypto/webcrypto.dart', ) external int RAND_bytes(ffi.Pointer buf, int len); @@ -1794,7 +1593,6 @@ external int RAND_bytes(ffi.Pointer buf, int len); /// |rsa| into it. It returns the fresh |RSA| object, or NULL on error. @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_RSAPublicKey_dup', - assetId: 'package:webcrypto/webcrypto.dart', ) external ffi.Pointer RSAPublicKey_dup(ffi.Pointer rsa); @@ -1803,16 +1601,12 @@ external ffi.Pointer RSAPublicKey_dup(ffi.Pointer rsa); /// returns zero then a more detailed error is available on the error queue. @ffi.Native)>( symbol: 'webcrypto_RSA_check_key', - assetId: 'package:webcrypto/webcrypto.dart', ) external int RSA_check_key(ffi.Pointer rsa); /// RSA_free decrements the reference count of |rsa| and frees it if the /// reference count drops to zero. -@ffi.Native)>( - symbol: 'webcrypto_RSA_free', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native)>(symbol: 'webcrypto_RSA_free') external void RSA_free(ffi.Pointer rsa); /// RSA_generate_key_ex generates a new RSA key where the modulus has size @@ -1830,10 +1624,7 @@ external void RSA_free(ffi.Pointer rsa); ffi.Pointer, ffi.Pointer, ) ->( - symbol: 'webcrypto_RSA_generate_key_ex', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_RSA_generate_key_ex') external int RSA_generate_key_ex( ffi.Pointer rsa, int bits, @@ -1852,10 +1643,7 @@ external int RSA_generate_key_ex( ffi.Pointer>, ffi.Pointer>, ) ->( - symbol: 'webcrypto_RSA_get0_crt_params', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_RSA_get0_crt_params') external void RSA_get0_crt_params( ffi.Pointer rsa, ffi.Pointer> out_dmp1, @@ -1871,10 +1659,7 @@ external void RSA_get0_crt_params( ffi.Pointer>, ffi.Pointer>, ) ->( - symbol: 'webcrypto_RSA_get0_factors', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_RSA_get0_factors') external void RSA_get0_factors( ffi.Pointer rsa, ffi.Pointer> out_p, @@ -1891,7 +1676,7 @@ external void RSA_get0_factors( ffi.Pointer>, ffi.Pointer>, ) ->(symbol: 'webcrypto_RSA_get0_key', assetId: 'package:webcrypto/webcrypto.dart') +>(symbol: 'webcrypto_RSA_get0_key') external void RSA_get0_key( ffi.Pointer rsa, ffi.Pointer> out_n, @@ -1901,10 +1686,7 @@ external void RSA_get0_key( /// RSA_new returns a new, empty |RSA| object or NULL on error. Prefer using /// |RSA_new_public_key| or |RSA_new_private_key| to import an RSA key. -@ffi.Native Function()>( - symbol: 'webcrypto_RSA_new', - assetId: 'package:webcrypto/webcrypto.dart', -) +@ffi.Native Function()>(symbol: 'webcrypto_RSA_new') external ffi.Pointer RSA_new(); /// RSA_set0_crt_params sets |rsa|'s CRT parameters to |dmp1|, |dmq1|, and @@ -1922,10 +1704,7 @@ external ffi.Pointer RSA_new(); ffi.Pointer, ffi.Pointer, ) ->( - symbol: 'webcrypto_RSA_set0_crt_params', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_RSA_set0_crt_params') external int RSA_set0_crt_params( ffi.Pointer rsa, ffi.Pointer dmp1, @@ -1943,10 +1722,7 @@ external int RSA_set0_crt_params( /// cryptographic operation. Construct a new |RSA| object instead. @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Pointer) ->( - symbol: 'webcrypto_RSA_set0_factors', - assetId: 'package:webcrypto/webcrypto.dart', -) +>(symbol: 'webcrypto_RSA_set0_factors') external int RSA_set0_factors( ffi.Pointer rsa, ffi.Pointer p, @@ -1969,7 +1745,7 @@ external int RSA_set0_factors( ffi.Pointer, ffi.Pointer, ) ->(symbol: 'webcrypto_RSA_set0_key', assetId: 'package:webcrypto/webcrypto.dart') +>(symbol: 'webcrypto_RSA_set0_key') external int RSA_set0_key( ffi.Pointer rsa, ffi.Pointer n, @@ -1979,40 +1755,218 @@ external int RSA_set0_key( const int AES_BLOCK_SIZE = 16; +typedef AES_KEY = aes_key_st; +typedef ASN1_BIT_STRING = asn1_string_st; +typedef ASN1_BMPSTRING = asn1_string_st; +typedef ASN1_BOOLEAN = ffi.Int; +typedef DartASN1_BOOLEAN = int; +typedef ASN1_ENUMERATED = asn1_string_st; +typedef ASN1_GENERALIZEDTIME = asn1_string_st; +typedef ASN1_GENERALSTRING = asn1_string_st; +typedef ASN1_IA5STRING = asn1_string_st; +typedef ASN1_INTEGER = asn1_string_st; +typedef ASN1_ITEM = ASN1_ITEM_st; + +final class ASN1_ITEM_st extends ffi.Opaque {} + +/// An |ASN1_NULL| is an opaque type. asn1.h represents the ASN.1 NULL value as +/// an opaque, non-NULL |ASN1_NULL*| pointer. +typedef ASN1_NULL = asn1_null_st; +typedef ASN1_OBJECT = asn1_object_st; +typedef ASN1_OCTET_STRING = asn1_string_st; +typedef ASN1_PCTX = asn1_pctx_st; +typedef ASN1_PRINTABLESTRING = asn1_string_st; +typedef ASN1_STRING = asn1_string_st; +typedef ASN1_T61STRING = asn1_string_st; +typedef ASN1_TIME = asn1_string_st; +typedef ASN1_TYPE = asn1_type_st; +typedef ASN1_UNIVERSALSTRING = asn1_string_st; +typedef ASN1_UTCTIME = asn1_string_st; +typedef ASN1_UTF8STRING = asn1_string_st; +typedef ASN1_VISIBLESTRING = asn1_string_st; +typedef AUTHORITY_KEYID = AUTHORITY_KEYID_st; + +final class AUTHORITY_KEYID_st extends ffi.Opaque {} + +typedef BASIC_CONSTRAINTS = BASIC_CONSTRAINTS_st; + +final class BASIC_CONSTRAINTS_st extends ffi.Opaque {} + typedef BIGNUM = bignum_st; +typedef BIO = bio_st; +typedef BIO_METHOD = bio_method_st; +typedef BLAKE2B_CTX = blake2b_state_st; typedef BN_CTX = bignum_ctx; typedef BN_GENCB = bn_gencb_st; +typedef BN_MONT_CTX = bn_mont_ctx_st; typedef BN_ULONG = ffi.Uint64; typedef DartBN_ULONG = int; +typedef BUF_MEM = buf_mem_st; typedef CBB = cbb_st; typedef CBS = cbs_st; + +/// CBS_ASN1_TAG is the type used by |CBS| and |CBB| for ASN.1 tags. See that +/// header for details. This type is defined in base.h as a forward declaration. +typedef CBS_ASN1_TAG = ffi.Uint32; +typedef DartCBS_ASN1_TAG = int; +typedef CMAC_CTX = cmac_ctx_st; +typedef CMS_ContentInfo = CMS_ContentInfo_st; + +final class CMS_ContentInfo_st extends ffi.Opaque {} + +typedef CMS_SignerInfo = CMS_SignerInfo_st; + +final class CMS_SignerInfo_st extends ffi.Opaque {} + +typedef CONF = conf_st; +typedef CONF_VALUE = conf_value_st; +typedef CRYPTO_BUFFER = crypto_buffer_st; +typedef CRYPTO_BUFFER_POOL = crypto_buffer_pool_st; + +/// CRYPTO_EX_DATA, in the public API, is an opaque struct that is never returned +/// from the library. +typedef CRYPTO_EX_DATA = crypto_ex_data_st; + +/// CRYPTO_EX_dup is a legacy callback function type which is ignored. +typedef CRYPTO_EX_dup = + ffi.NativeFunction< + ffi.Int Function( + ffi.Pointer to, + ffi.Pointer from, + ffi.Pointer> from_d, + ffi.Int index, + ffi.Long argl, + ffi.Pointer argp, + ) + >; + +/// CRYPTO_EX_free is a callback function that is called when an object of the +/// class with extra data pointers is being destroyed. For example, if this +/// callback has been passed to |SSL_get_ex_new_index| then it may be called each +/// time an |SSL*| is destroyed. +/// +/// |parent| and |ad| will be NULL. Historically, the parent object was passed in +/// |parent|, but accessing the pointer was not safe because |parent| was in the +/// process of being destroyed. If the callback has access to some other pointer +/// to the parent object, it must not pass the pointer to any BoringSSL APIs. +/// Mid-destruction, invariants on the parent object no longer hold. +/// +/// The arguments |argl| and |argp| contain opaque values that were given to +/// |CRYPTO_get_ex_new_index_ex|. +/// +/// This callback may be called with a NULL value for |ptr| if the object has no +/// value set for this index. However, the callbacks may also be skipped entirely +/// if no extra data pointers are set on the object at all. +typedef CRYPTO_EX_free = + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer parent, + ffi.Pointer ptr, + ffi.Pointer ad, + ffi.Int index, + ffi.Long argl, + ffi.Pointer argp, + ) + >; + +/// CRYPTO_EX_unused is a placeholder for an unused callback. It is aliased to +/// int to ensure non-NULL callers fail to compile rather than fail silently. +typedef CRYPTO_EX_unused = ffi.Int; +typedef DartCRYPTO_EX_unused = int; +typedef CRYPTO_IOVEC = crypto_iovec_st; +typedef CRYPTO_IVEC = crypto_ivec_st; + +/// CRYPTO_MUST_BE_NULL is an opaque type that is never returned from BoringSSL. +/// It is used in function parameters that must be NULL. +typedef CRYPTO_MUST_BE_NULL = crypto_must_be_null_st; + +/// CRYPTO_THREADID is a dummy value. +typedef CRYPTO_THREADID = ffi.Int; +typedef DartCRYPTO_THREADID = int; +typedef CTR_DRBG_STATE = ctr_drbg_state_st; +typedef DH = dh_st; +typedef DIST_POINT = DIST_POINT_st; + +final class DIST_POINT_st extends ffi.Opaque {} + +typedef DSA = dsa_st; +typedef DSA_SIG = DSA_SIG_st; + +final class DSA_SIG_st extends ffi.Opaque {} + +typedef ECDSA_METHOD = ecdsa_method_st; typedef ECDSA_SIG = ecdsa_sig_st; typedef EC_GROUP = ec_group_st; typedef EC_KEY = ec_key_st; +typedef EC_METHOD = ec_method_st; const int EC_PKEY_NO_PUBKEY = 2; typedef EC_POINT = ec_point_st; typedef ENGINE = engine_st; +typedef ERR_FNS = st_ERR_FNS; const int ERR_LIB_HKDF = 31; +/// ERR_print_errors_callback_t is the type of a function used by +/// |ERR_print_errors_cb|. It takes a pointer to a human readable string (and +/// its length) that describes an entry in the error queue. The |ctx| argument +/// is an opaque pointer given to |ERR_print_errors_cb|. +/// +/// It should return one on success or zero on error, which will stop the +/// iteration over the error queue. +typedef ERR_print_errors_callback_t = + ffi.Pointer>; +typedef ERR_print_errors_callback_tFunction = + ffi.Int Function( + ffi.Pointer str, + ffi.Size len, + ffi.Pointer ctx, + ); +typedef DartERR_print_errors_callback_tFunction = + int Function(ffi.Pointer str, int len, ffi.Pointer ctx); typedef EVP_AEAD = evp_aead_st; typedef EVP_AEAD_CTX = evp_aead_ctx_st; typedef EVP_CIPHER = evp_cipher_st; typedef EVP_CIPHER_CTX = evp_cipher_ctx_st; +typedef EVP_CIPHER_INFO = evp_cipher_info_st; +typedef EVP_ENCODE_CTX = evp_encode_ctx_st; +typedef EVP_HPKE_AEAD = evp_hpke_aead_st; +typedef EVP_HPKE_CTX = evp_hpke_ctx_st; +typedef EVP_HPKE_KDF = evp_hpke_kdf_st; +typedef EVP_HPKE_KEM = evp_hpke_kem_st; +typedef EVP_HPKE_KEY = evp_hpke_key_st; +typedef EVP_KEM = evp_kem_st; typedef EVP_MD = env_md_st; typedef EVP_MD_CTX = env_md_ctx_st; typedef EVP_PKEY = evp_pkey_st; +typedef EVP_PKEY_ALG = evp_pkey_alg_st; typedef EVP_PKEY_CTX = evp_pkey_ctx_st; const int EVP_PKEY_EC = 408; const int EVP_PKEY_RSA = 6; +typedef FILE = _IO_FILE; +typedef GENERAL_NAME = GENERAL_NAME_st; + +final class GENERAL_NAME_st extends ffi.Opaque {} + const int HKDF_R_OUTPUT_TOO_LARGE = 100; typedef HMAC_CTX = hmac_ctx_st; +typedef ISSUING_DIST_POINT = ISSUING_DIST_POINT_st; + +final class ISSUING_DIST_POINT_st extends ffi.Opaque {} + +typedef MD4_CTX = md4_state_st; +typedef MD5_CTX = md5_state_st; +typedef NAME_CONSTRAINTS = NAME_CONSTRAINTS_st; + +final class NAME_CONSTRAINTS_st extends ffi.Opaque {} + +typedef NETSCAPE_SPKAC = Netscape_spkac_st; +typedef NETSCAPE_SPKI = Netscape_spki_st; const int NID_X9_62_prime256v1 = 415; @@ -2020,7 +1974,24 @@ const int NID_secp384r1 = 715; const int NID_secp521r1 = 716; +final class Netscape_spkac_st extends ffi.Opaque {} + +final class Netscape_spki_st extends ffi.Opaque {} + +typedef OPENSSL_BLOCK = ffi.Pointer; +typedef OPENSSL_INIT_SETTINGS = ossl_init_settings_st; +typedef OSSL_LIB_CTX = ossl_lib_ctx_st; +typedef OSSL_PARAM = ossl_param_st; +typedef PKCS12 = pkcs12_st; +typedef PKCS8_PRIV_KEY_INFO = pkcs8_priv_key_info_st; +typedef RAND_METHOD = rand_meth_st; +typedef RC4_KEY = rc4_key_st; +typedef RIPEMD160_CTX = RIPEMD160state_st; + +final class RIPEMD160state_st extends ffi.Opaque {} + typedef RSA = rsa_st; +typedef RSA_METHOD = rsa_meth_st; const int RSA_PKCS1_OAEP_PADDING = 4; @@ -2028,52 +1999,261 @@ const int RSA_PKCS1_PADDING = 1; const int RSA_PKCS1_PSS_PADDING = 6; -/// md_data contains the hash-specific context. -final class UnnamedUnion2 extends ffi.Union { - @ffi.Array.multi([208]) - external ffi.Array md_data; - - @ffi.Uint64() - external int alignment; -} +typedef RSA_PSS_PARAMS = rsa_pss_params_st; +typedef SHA256_CTX = sha256_state_st; +typedef SHA512_CTX = sha512_state_st; +typedef SHA_CTX = sha_state_st; +typedef SPAKE2_CTX = spake2_ctx_st; +typedef SRTP_PROTECTION_PROFILE = srtp_protection_profile_st; +typedef SSL = ssl_st; +typedef SSL_CIPHER = ssl_cipher_st; +typedef SSL_CLIENT_HELLO = ssl_early_callback_ctx; +typedef SSL_CREDENTIAL = ssl_credential_st; +typedef SSL_CTX = ssl_ctx_st; +typedef SSL_ECH_KEYS = ssl_ech_keys_st; +typedef SSL_METHOD = ssl_method_st; +typedef SSL_PRIVATE_KEY_METHOD = ssl_private_key_method_st; +typedef SSL_QUIC_METHOD = ssl_quic_method_st; +typedef SSL_SESSION = ssl_session_st; +typedef SSL_TICKET_AEAD_METHOD = ssl_ticket_aead_method_st; +typedef TRUST_TOKEN = trust_token_st; +typedef TRUST_TOKEN_CLIENT = trust_token_client_st; +typedef TRUST_TOKEN_ISSUER = trust_token_issuer_st; +typedef TRUST_TOKEN_METHOD = trust_token_method_st; +typedef X509 = x509_st; +typedef X509V3_CTX = v3_ext_ctx; +typedef X509V3_EXT_METHOD = v3_ext_method; +typedef X509_ALGOR = X509_algor_st; +typedef X509_ATTRIBUTE = x509_attributes_st; +typedef X509_CRL = X509_crl_st; +typedef X509_EXTENSION = X509_extension_st; +typedef X509_INFO = X509_info_st; +typedef X509_LOOKUP = x509_lookup_st; +typedef X509_LOOKUP_METHOD = x509_lookup_method_st; +typedef X509_NAME = X509_name_st; +typedef X509_NAME_ENTRY = X509_name_entry_st; +typedef X509_OBJECT = x509_object_st; +typedef X509_PKEY = private_key_st; +typedef X509_PUBKEY = X509_pubkey_st; +typedef X509_PURPOSE = x509_purpose_st; +typedef X509_REQ = X509_req_st; +typedef X509_REVOKED = x509_revoked_st; +typedef X509_SIG = X509_sig_st; +typedef X509_STORE = x509_store_st; +typedef X509_STORE_CTX = x509_store_ctx_st; +typedef X509_VERIFY_PARAM = X509_VERIFY_PARAM_st; + +final class X509_VERIFY_PARAM_st extends ffi.Opaque {} + +final class X509_algor_st extends ffi.Opaque {} + +final class X509_crl_st extends ffi.Opaque {} + +final class X509_extension_st extends ffi.Opaque {} + +final class X509_info_st extends ffi.Opaque {} + +final class X509_name_entry_st extends ffi.Opaque {} + +final class X509_name_st extends ffi.Opaque {} + +final class X509_pubkey_st extends ffi.Opaque {} + +final class X509_req_st extends ffi.Opaque {} + +final class X509_sig_st extends ffi.Opaque {} + +typedef _Float32 = ffi.Float; +typedef Dart_Float32 = double; +typedef _Float32x = ffi.Double; +typedef Dart_Float32x = double; +typedef _Float64 = ffi.Double; +typedef Dart_Float64 = double; + +final class _G_fpos64_t extends ffi.Opaque {} + +final class _G_fpos_t extends ffi.Opaque {} + +final class _IO_FILE extends ffi.Opaque {} + +final class _IO_cookie_io_functions_t extends ffi.Opaque {} + +typedef _IO_lock_t = ffi.Void; +typedef Dart_IO_lock_t = void; +typedef __FILE = _IO_FILE; +typedef __blkcnt64_t = ffi.Long; +typedef Dart__blkcnt64_t = int; +typedef __blkcnt_t = ffi.Long; +typedef Dart__blkcnt_t = int; +typedef __blksize_t = ffi.Long; +typedef Dart__blksize_t = int; +typedef __caddr_t = ffi.Pointer; +typedef __clock_t = ffi.Long; +typedef Dart__clock_t = int; +typedef __clockid_t = ffi.Int; +typedef Dart__clockid_t = int; +typedef __compar_fn_t = ffi.Pointer>; +typedef __compar_fn_tFunction = + ffi.Int Function(ffi.Pointer, ffi.Pointer); +typedef Dart__compar_fn_tFunction = + int Function(ffi.Pointer, ffi.Pointer); +typedef __daddr_t = ffi.Int; +typedef Dart__daddr_t = int; +typedef __dev_t = ffi.UnsignedLong; +typedef Dart__dev_t = int; +typedef __fd_mask = ffi.Long; +typedef Dart__fd_mask = int; +typedef __fpos64_t = _G_fpos64_t; +typedef __fpos_t = _G_fpos_t; +typedef __fsblkcnt64_t = ffi.UnsignedLong; +typedef Dart__fsblkcnt64_t = int; +typedef __fsblkcnt_t = ffi.UnsignedLong; +typedef Dart__fsblkcnt_t = int; +typedef __fsfilcnt64_t = ffi.UnsignedLong; +typedef Dart__fsfilcnt64_t = int; +typedef __fsfilcnt_t = ffi.UnsignedLong; +typedef Dart__fsfilcnt_t = int; + +final class __fsid_t extends ffi.Opaque {} + +typedef __fsword_t = ffi.Long; +typedef Dart__fsword_t = int; +typedef __gid_t = ffi.UnsignedInt; +typedef Dart__gid_t = int; +typedef __gwchar_t = ffi.Int; +typedef Dart__gwchar_t = int; +typedef __id_t = ffi.UnsignedInt; +typedef Dart__id_t = int; +typedef __ino64_t = ffi.UnsignedLong; +typedef Dart__ino64_t = int; +typedef __ino_t = ffi.UnsignedLong; +typedef Dart__ino_t = int; +typedef __int16_t = ffi.Short; +typedef Dart__int16_t = int; +typedef __int32_t = ffi.Int; +typedef Dart__int32_t = int; +typedef __int64_t = ffi.Long; +typedef Dart__int64_t = int; +typedef __int8_t = ffi.SignedChar; +typedef Dart__int8_t = int; +typedef __int_least16_t = __int16_t; +typedef __int_least32_t = __int32_t; +typedef __int_least64_t = __int64_t; +typedef __int_least8_t = __int8_t; +typedef __intmax_t = ffi.Long; +typedef Dart__intmax_t = int; +typedef __intptr_t = ffi.Long; +typedef Dart__intptr_t = int; +typedef __key_t = ffi.Int; +typedef Dart__key_t = int; + +final class __locale_struct extends ffi.Opaque {} + +typedef __locale_t = ffi.Pointer<__locale_struct>; +typedef __loff_t = __off64_t; +typedef __mode_t = ffi.UnsignedInt; +typedef Dart__mode_t = int; +typedef __nlink_t = ffi.UnsignedLong; +typedef Dart__nlink_t = int; +typedef __off64_t = ffi.Long; +typedef Dart__off64_t = int; +typedef __off_t = ffi.Long; +typedef Dart__off_t = int; +typedef __pid_t = ffi.Int; +typedef Dart__pid_t = int; + +final class __pthread_internal_list extends ffi.Opaque {} + +final class __pthread_internal_slist extends ffi.Opaque {} + +typedef __pthread_list_t = __pthread_internal_list; +typedef __pthread_slist_t = __pthread_internal_slist; +typedef __quad_t = ffi.Long; +typedef Dart__quad_t = int; +typedef __rlim64_t = ffi.UnsignedLong; +typedef Dart__rlim64_t = int; +typedef __rlim_t = ffi.UnsignedLong; +typedef Dart__rlim_t = int; +typedef __sig_atomic_t = ffi.Int; +typedef Dart__sig_atomic_t = int; + +final class __sigset_t extends ffi.Opaque {} + +typedef __socklen_t = ffi.UnsignedInt; +typedef Dart__socklen_t = int; +typedef __ssize_t = ffi.Long; +typedef Dart__ssize_t = int; +typedef __suseconds64_t = ffi.Long; +typedef Dart__suseconds64_t = int; +typedef __suseconds_t = ffi.Long; +typedef Dart__suseconds_t = int; +typedef __syscall_slong_t = ffi.Long; +typedef Dart__syscall_slong_t = int; +typedef __syscall_ulong_t = ffi.UnsignedLong; +typedef Dart__syscall_ulong_t = int; +typedef __thrd_t = ffi.UnsignedLong; +typedef Dart__thrd_t = int; +typedef __time_t = ffi.Long; +typedef Dart__time_t = int; +typedef __timer_t = ffi.Pointer; +typedef __tss_t = ffi.UnsignedInt; +typedef Dart__tss_t = int; +typedef __u_char = ffi.UnsignedChar; +typedef Dart__u_char = int; +typedef __u_int = ffi.UnsignedInt; +typedef Dart__u_int = int; +typedef __u_long = ffi.UnsignedLong; +typedef Dart__u_long = int; +typedef __u_quad_t = ffi.UnsignedLong; +typedef Dart__u_quad_t = int; +typedef __u_short = ffi.UnsignedShort; +typedef Dart__u_short = int; +typedef __uid_t = ffi.UnsignedInt; +typedef Dart__uid_t = int; +typedef __uint16_t = ffi.UnsignedShort; +typedef Dart__uint16_t = int; +typedef __uint32_t = ffi.UnsignedInt; +typedef Dart__uint32_t = int; +typedef __uint64_t = ffi.UnsignedLong; +typedef Dart__uint64_t = int; +typedef __uint8_t = ffi.UnsignedChar; +typedef Dart__uint8_t = int; +typedef __uint_least16_t = __uint16_t; +typedef __uint_least32_t = __uint32_t; +typedef __uint_least64_t = __uint64_t; +typedef __uint_least8_t = __uint8_t; +typedef __uintmax_t = ffi.UnsignedLong; +typedef Dart__uintmax_t = int; +typedef __useconds_t = ffi.UnsignedInt; +typedef Dart__useconds_t = int; + +/// aes_key_st should be an opaque type, but EVP requires that the size be +/// known. +final class aes_key_st extends ffi.Opaque {} + +final class asn1_null_st extends ffi.Opaque {} + +final class asn1_object_st extends ffi.Opaque {} + +final class asn1_pctx_st extends ffi.Opaque {} + +final class asn1_string_st extends ffi.Opaque {} + +final class asn1_type_st extends ffi.Opaque {} final class bignum_ctx extends ffi.Opaque {} /// Private functions -final class bignum_st extends ffi.Struct { - /// d is a pointer to an array of |width| |BN_BITS2|-bit chunks in - /// little-endian order. This stores the absolute value of the number. - external ffi.Pointer d; - - /// width is the number of elements of |d| which are valid. This value is not - /// necessarily minimal; the most-significant words of |d| may be zero. - /// |width| determines a potentially loose upper-bound on the absolute value - /// of the |BIGNUM|. - /// - /// Functions taking |BIGNUM| inputs must compute the same answer for all - /// possible widths. |bn_minimal_width|, |bn_set_minimal_width|, and other - /// helpers may be used to recover the minimal width, provided it is not - /// secret. If it is secret, use a different algorithm. Functions may output - /// minimal or non-minimal |BIGNUM|s depending on secrecy requirements, but - /// those which cause widths to unboundedly grow beyond the minimal value - /// should be documented such. - /// - /// Note this is different from historical |BIGNUM| semantics. - @ffi.Int() - external int width; +final class bignum_st extends ffi.Opaque {} - /// dmax is number of elements of |d| which are allocated. - @ffi.Int() - external int dmax; +final class bio_method_st extends ffi.Opaque {} - /// neg is one if the number if negative and zero otherwise. - @ffi.Int() - external int neg; +final class bio_st extends ffi.Opaque {} - /// flags is a bitmask of |BN_FLG_*| values - @ffi.Int() - external int flags; -} +final class blake2b_state_st extends ffi.Opaque {} + +typedef blkcnt_t = __blkcnt_t; +typedef blksize_t = __blksize_t; /// bn_gencb_st, or |BN_GENCB|, holds a callback function that is used by /// generation functions that can take a very long time to complete. Use @@ -2095,23 +2275,11 @@ final class bignum_st extends ffi.Struct { /// BN_GENCB argument and may call the function with other argument values. final class bn_gencb_st extends ffi.Opaque {} -/// CRYPTO ByteBuilder. -/// -/// |CBB| objects allow one to build length-prefixed serialisations. A |CBB| -/// object is associated with a buffer and new buffers are created with -/// |CBB_init|. Several |CBB| objects can point at the same buffer when a -/// length-prefix is pending, however only a single |CBB| can be 'current' at -/// any one time. For example, if one calls |CBB_add_u8_length_prefixed| then -/// the new |CBB| points at the same buffer as the original. But if the original -/// |CBB| is used then the length prefix is written out and the new |CBB| must -/// not be used again. -/// -/// If one needs to force a length prefix to be written out because a |CBB| is -/// going out of scope, use |CBB_flush|. If an operation on a |CBB| fails, it is -/// in an undefined state and must not be used except to call |CBB_cleanup|. -final class cbb_buffer_st extends ffi.Opaque {} +final class bn_mont_ctx_st extends ffi.Opaque {} -final class cbb_child_st extends ffi.Opaque {} +final class buf_mem_st extends ffi.Opaque {} + +typedef caddr_t = __caddr_t; final class cbb_st extends ffi.Opaque {} @@ -2123,166 +2291,332 @@ final class cbs_st extends ffi.Struct { external int len; } +typedef clock_t = __clock_t; +typedef clockid_t = __clockid_t; + +final class cmac_ctx_st extends ffi.Opaque {} + +final class conf_st extends ffi.Opaque {} + +final class conf_value_st extends ffi.Opaque {} + +typedef cookie_close_function_t = + ffi.NativeFunction __cookie)>; +typedef cookie_io_functions_t = _IO_cookie_io_functions_t; +typedef cookie_read_function_t = + ffi.NativeFunction< + __ssize_t Function( + ffi.Pointer __cookie, + ffi.Pointer __buf, + ffi.Size __nbytes, + ) + >; +typedef cookie_seek_function_t = + ffi.NativeFunction< + ffi.Int Function( + ffi.Pointer __cookie, + ffi.Pointer<__off64_t> __pos, + ffi.Int __w, + ) + >; +typedef cookie_write_function_t = + ffi.NativeFunction< + __ssize_t Function( + ffi.Pointer __cookie, + ffi.Pointer __buf, + ffi.Size __nbytes, + ) + >; + +final class crypto_buffer_pool_st extends ffi.Opaque {} + +final class crypto_buffer_st extends ffi.Opaque {} + +final class crypto_ex_data_st extends ffi.Opaque {} + +/// crypto_iovec_st (aka |CRYPTO_IOVEC| combines a pointer to input data and a +/// pointer to an output buffer with their common length. It is usually passed +/// as an array of length of at most |CRYPTO_IOVEC_MAX|. +final class crypto_iovec_st extends ffi.Opaque {} + +/// crypto_ivec_st (aka |CRYPTO_IVEC|) combines a pointer to input data with its +/// length. It is usually passed as an array of length of at most +/// |CRYPTO_IOVEC_MAX|. +final class crypto_ivec_st extends ffi.Opaque {} + +final class crypto_must_be_null_st extends ffi.Opaque {} + +final class ctr_drbg_state_st extends ffi.Opaque {} + +typedef daddr_t = __daddr_t; +typedef dev_t = __dev_t; + +final class dh_st extends ffi.Opaque {} + +final class dsa_st extends ffi.Opaque {} + final class ec_group_st extends ffi.Opaque {} final class ec_key_st extends ffi.Opaque {} +final class ec_method_st extends ffi.Opaque {} + final class ec_point_st extends ffi.Opaque {} +/// ecdsa_method_st is a structure of function pointers for implementing ECDSA. +/// See engine.h. +final class ecdsa_method_st extends ffi.Opaque {} + /// Low-level signing and verification. /// /// Low-level functions handle signatures as |ECDSA_SIG| structures which allow /// the two values in an ECDSA signature to be handled separately. -final class ecdsa_sig_st extends ffi.Struct { - external ffi.Pointer r; - - external ffi.Pointer s; -} +final class ecdsa_sig_st extends ffi.Opaque {} final class engine_st extends ffi.Opaque {} /// env_md_ctx_st is typoed ("evp" -> "env"), but the typo comes from OpenSSL /// and some consumers forward-declare these structures so we're leaving it /// alone. -final class env_md_ctx_st extends ffi.Struct { - /// md_data contains the hash-specific context. - external UnnamedUnion2 unnamed; - - /// digest is the underlying digest function, or NULL if not set. - external ffi.Pointer digest; - - /// pctx is an opaque (at this layer) pointer to additional context that - /// EVP_PKEY functions may store in this object. - external ffi.Pointer pctx; - - /// pctx_ops, if not NULL, points to a vtable that contains functions to - /// manipulate |pctx|. - external ffi.Pointer pctx_ops; -} +final class env_md_ctx_st extends ffi.Opaque {} final class env_md_st extends ffi.Opaque {} /// An evp_aead_ctx_st (typedefed as |EVP_AEAD_CTX| in base.h) represents an AEAD /// algorithm configured with a specific key and message-independent IV. -final class evp_aead_ctx_st extends ffi.Struct { - external ffi.Pointer aead; +final class evp_aead_ctx_st extends ffi.Opaque {} - external evp_aead_ctx_st_state state; +final class evp_aead_st extends ffi.Opaque {} - /// tag_len may contain the actual length of the authentication tag if it is - /// known at initialization time. - @ffi.Uint8() - external int tag_len; -} +final class evp_cipher_ctx_st extends ffi.Opaque {} -/// AEAD operations. -final class evp_aead_ctx_st_state extends ffi.Union { - @ffi.Array.multi([560]) - external ffi.Array opaque; +final class evp_cipher_info_st extends ffi.Opaque {} - @ffi.Uint64() - external int alignment; -} +final class evp_cipher_st extends ffi.Opaque {} -final class evp_aead_st extends ffi.Opaque {} +final class evp_encode_ctx_st extends ffi.Opaque {} -final class evp_cipher_ctx_st extends ffi.Struct { - /// cipher contains the underlying cipher for this context. - external ffi.Pointer cipher; +final class evp_hpke_aead_st extends ffi.Opaque {} - /// application stuff - external ffi.Pointer app_data; +final class evp_hpke_ctx_st extends ffi.Opaque {} - /// cipher_data points to the |cipher| specific state. - external ffi.Pointer cipher_data; +final class evp_hpke_kdf_st extends ffi.Opaque {} - /// key_len contains the length of the key, which may differ from - /// |cipher->key_len| if the cipher can take a variable key length. - @ffi.UnsignedInt() - external int key_len; +final class evp_hpke_kem_st extends ffi.Opaque {} - /// encrypt is one if encrypting and zero if decrypting. - @ffi.Int() - external int encrypt; +final class evp_hpke_key_st extends ffi.Opaque {} - /// flags contains the OR of zero or more |EVP_CIPH_*| flags, above. - @ffi.Uint32() - external int flags; +final class evp_kem_st extends ffi.Opaque {} - /// oiv contains the original IV value. - @ffi.Array.multi([16]) - external ffi.Array oiv; +final class evp_pkey_alg_st extends ffi.Opaque {} - /// iv contains the current IV value, which may have been updated. - @ffi.Array.multi([16]) - external ffi.Array iv; +final class evp_pkey_ctx_st extends ffi.Opaque {} - /// buf contains a partial block which is used by, for example, CTR mode to - /// store unused keystream bytes. - @ffi.Array.multi([32]) - external ffi.Array buf; +final class evp_pkey_st extends ffi.Opaque {} - /// buf_len contains the number of bytes of a partial block contained in - /// |buf|. - @ffi.Int() - external int buf_len; +typedef fd_mask = __fd_mask; +typedef fpos_t = __fpos_t; +typedef fsblkcnt_t = __fsblkcnt_t; +typedef fsfilcnt_t = __fsfilcnt_t; +typedef fsid_t = __fsid_t; +typedef gid_t = __gid_t; - /// num contains the number of bytes of |iv| which are valid for modes that - /// manage partial blocks themselves. - @ffi.UnsignedInt() - external int num; +/// Private functions +final class hmac_ctx_st extends ffi.Opaque {} - /// final_used is non-zero if the |final| buffer contains plaintext. - @ffi.Int() - external int final_used; +typedef id_t = __id_t; +typedef ino_t = __ino_t; +typedef int_fast16_t = ffi.Long; +typedef Dartint_fast16_t = int; +typedef int_fast32_t = ffi.Long; +typedef Dartint_fast32_t = int; +typedef int_fast64_t = ffi.Long; +typedef Dartint_fast64_t = int; +typedef int_fast8_t = ffi.SignedChar; +typedef Dartint_fast8_t = int; +typedef int_least16_t = __int_least16_t; +typedef int_least32_t = __int_least32_t; +typedef int_least64_t = __int_least64_t; +typedef int_least8_t = __int_least8_t; +typedef intmax_t = __intmax_t; +typedef key_t = __key_t; +typedef locale_t = __locale_t; +typedef loff_t = __loff_t; - /// possible final block - @ffi.Array.multi([32]) - external ffi.Array final1; +final class md4_state_st extends ffi.Opaque {} - /// Has this structure been rendered unusable by a failure. - @ffi.Int() - external int poisoned; -} +final class md5_state_st extends ffi.Opaque {} -final class evp_cipher_st extends ffi.Opaque {} +typedef mode_t = __mode_t; +typedef nlink_t = __nlink_t; +typedef off_t = __off_t; -/// Internal constants and structures (hidden). -final class evp_md_pctx_ops extends ffi.Opaque {} +final class ossl_init_settings_st extends ffi.Opaque {} -final class evp_pkey_ctx_st extends ffi.Opaque {} +final class ossl_lib_ctx_st extends ffi.Opaque {} -final class evp_pkey_st extends ffi.Opaque {} +final class ossl_param_st extends ffi.Opaque {} -/// Private functions -final class hmac_ctx_st extends ffi.Struct { - external ffi.Pointer md; +/// ossl_ssize_t is a signed type which is large enough to fit the size of any +/// valid memory allocation. We prefer using |size_t|, but sometimes we need a +/// signed type for OpenSSL API compatibility. This type can be used in such +/// cases to avoid overflow. +/// +/// Not all |size_t| values fit in |ossl_ssize_t|, but all |size_t| values that +/// are sizes of or indices into C objects, can be converted without overflow. +typedef ossl_ssize_t = ptrdiff_t; +typedef pid_t = __pid_t; - external EVP_MD_CTX md_ctx; +final class pkcs12_st extends ffi.Opaque {} - external EVP_MD_CTX i_ctx; - - external EVP_MD_CTX o_ctx; -} +final class pkcs8_priv_key_info_st extends ffi.Opaque {} /// point_conversion_form_t enumerates forms, as defined in X9.62 (ECDSA), for /// the encoding of a elliptic curve point (x,y) -abstract class point_conversion_form_t { +sealed class point_conversion_form_t { /// POINT_CONVERSION_COMPRESSED indicates that the point is encoded as z||x, /// where the octet z specifies which solution of the quadratic equation y /// is. - static const int POINT_CONVERSION_COMPRESSED = 2; + static const POINT_CONVERSION_COMPRESSED = 2; /// POINT_CONVERSION_UNCOMPRESSED indicates that the point is encoded as /// z||x||y, where z is the octet 0x04. - static const int POINT_CONVERSION_UNCOMPRESSED = 4; + static const POINT_CONVERSION_UNCOMPRESSED = 4; /// POINT_CONVERSION_HYBRID indicates that the point is encoded as z||x||y, /// where z specifies which solution of the quadratic equation y is. This is /// not supported by the code and has never been observed in use. /// /// TODO(agl): remove once node.js no longer references this. - static const int POINT_CONVERSION_HYBRID = 6; + static const POINT_CONVERSION_HYBRID = 6; } +final class private_key_st extends ffi.Opaque {} + +typedef pthread_key_t = ffi.UnsignedInt; +typedef Dartpthread_key_t = int; +typedef pthread_once_t = ffi.Int; +typedef Dartpthread_once_t = int; +typedef pthread_t = ffi.UnsignedLong; +typedef Dartpthread_t = int; +typedef ptrdiff_t = ffi.Long; +typedef Dartptrdiff_t = int; +typedef quad_t = __quad_t; + +/// rand_meth_st is typedefed to |RAND_METHOD| in base.h. It isn't used; it +/// exists only to be the return type of |RAND_SSLeay|. It's +/// external so that variables of this type can be initialized. +final class rand_meth_st extends ffi.Opaque {} + +final class rc4_key_st extends ffi.Opaque {} + +typedef register_t = ffi.Long; +typedef Dartregister_t = int; + +final class rsa_meth_st extends ffi.Opaque {} + +final class rsa_pss_params_st extends ffi.Opaque {} + final class rsa_st extends ffi.Opaque {} + +final class sha256_state_st extends ffi.Opaque {} + +final class sha512_state_st extends ffi.Opaque {} + +final class sha_state_st extends ffi.Opaque {} + +typedef sigset_t = __sigset_t; + +final class spake2_ctx_st extends ffi.Opaque {} + +final class srtp_protection_profile_st extends ffi.Opaque {} + +typedef ssize_t = __ssize_t; + +final class ssl_cipher_st extends ffi.Opaque {} + +final class ssl_credential_st extends ffi.Opaque {} + +final class ssl_ctx_st extends ffi.Opaque {} + +final class ssl_early_callback_ctx extends ffi.Opaque {} + +final class ssl_ech_keys_st extends ffi.Opaque {} + +final class ssl_method_st extends ffi.Opaque {} + +final class ssl_private_key_method_st extends ffi.Opaque {} + +final class ssl_quic_method_st extends ffi.Opaque {} + +final class ssl_session_st extends ffi.Opaque {} + +final class ssl_st extends ffi.Opaque {} + +final class ssl_ticket_aead_method_st extends ffi.Opaque {} + +final class st_ERR_FNS extends ffi.Opaque {} + +typedef suseconds_t = __suseconds_t; +typedef time_t = __time_t; +typedef timer_t = __timer_t; + +final class trust_token_client_st extends ffi.Opaque {} + +final class trust_token_issuer_st extends ffi.Opaque {} + +final class trust_token_method_st extends ffi.Opaque {} + +final class trust_token_st extends ffi.Opaque {} + +typedef u_char = __u_char; +typedef u_int = __u_int; +typedef u_int16_t = __uint16_t; +typedef u_int32_t = __uint32_t; +typedef u_int64_t = __uint64_t; +typedef u_int8_t = __uint8_t; +typedef u_long = __u_long; +typedef u_quad_t = __u_quad_t; +typedef u_short = __u_short; +typedef uid_t = __uid_t; +typedef uint = ffi.UnsignedInt; +typedef Dartuint = int; +typedef uint_fast16_t = ffi.UnsignedLong; +typedef Dartuint_fast16_t = int; +typedef uint_fast32_t = ffi.UnsignedLong; +typedef Dartuint_fast32_t = int; +typedef uint_fast64_t = ffi.UnsignedLong; +typedef Dartuint_fast64_t = int; +typedef uint_fast8_t = ffi.UnsignedChar; +typedef Dartuint_fast8_t = int; +typedef uint_least16_t = __uint_least16_t; +typedef uint_least32_t = __uint_least32_t; +typedef uint_least64_t = __uint_least64_t; +typedef uint_least8_t = __uint_least8_t; +typedef uintmax_t = __uintmax_t; +typedef ulong = ffi.UnsignedLong; +typedef Dartulong = int; +typedef ushort = ffi.UnsignedShort; +typedef Dartushort = int; + +final class v3_ext_ctx extends ffi.Opaque {} + +final class v3_ext_method extends ffi.Opaque {} + +final class x509_attributes_st extends ffi.Opaque {} + +final class x509_lookup_method_st extends ffi.Opaque {} + +final class x509_lookup_st extends ffi.Opaque {} + +final class x509_object_st extends ffi.Opaque {} + +final class x509_purpose_st extends ffi.Opaque {} + +final class x509_revoked_st extends ffi.Opaque {} + +final class x509_st extends ffi.Opaque {} + +final class x509_store_ctx_st extends ffi.Opaque {} + +final class x509_store_st extends ffi.Opaque {} diff --git a/pubspec.yaml b/pubspec.yaml index 3baa6d58c..7d5771630 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -28,7 +28,7 @@ dependencies: meta: ^1.3.0 dev_dependencies: - ffigen: ^11.0.0 + ffigen: ^20.0.0 test: ^1.30.0 yaml: ^3.0.0 flutter_lints: ^6.0.0 diff --git a/tool/ffigen.dart b/tool/ffigen.dart new file mode 100644 index 000000000..89c5525b5 --- /dev/null +++ b/tool/ffigen.dart @@ -0,0 +1,357 @@ +// Copyright 2021 Google LLC +// +// 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. + +import 'dart:io'; + +import 'package:ffigen/ffigen.dart'; + +void main() { + final packageRoot = Platform.script.resolve('../'); + + generateWebCryptoBindings(packageRoot); + generateBoringSslBindings(packageRoot); +} + +void generateWebCryptoBindings(Uri packageRoot) { + FfiGenerator( + output: Output( + dartFile: packageRoot + .resolve('lib/src/boringssl/bindings/generated_bindings.dart'), + style: const NativeExternalBindings( + assetId: 'package:webcrypto/webcrypto.dart', + ), + sort: true, + commentType: const CommentType(CommentStyle.any, CommentLength.full), + preamble: ''' +// Copyright 2021 Google LLC +// +// 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. +// +// ignore_for_file: unused_element +// ignore_for_file: non_constant_identifier_names +''', + ), + headers: Headers( + entryPoints: [ + packageRoot.resolve('src/webcrypto.h'), + ], + ), + functions: Functions( + include: Declarations.includeSet({'webcrypto_get_CBB_size'}), + ), + structs: const Structs( + dependencies: CompoundDependencies.opaque, + ), + typedefs: const Typedefs( + include: Declarations.includeAll, + ), + ).generate(); +} + +void generateBoringSslBindings(Uri packageRoot) { + FfiGenerator( + output: Output( + dartFile: packageRoot.resolve( + 'lib/src/third_party/boringssl/generated_bindings.dart', + ), + style: const NativeExternalBindings( + assetId: 'package:webcrypto/webcrypto.dart', + ), + sort: true, + commentType: const CommentType(CommentStyle.any, CommentLength.full), + preamble: ''' +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ +// ignore_for_file: camel_case_types +// ignore_for_file: constant_identifier_names +// ignore_for_file: non_constant_identifier_names +// ignore_for_file: unused_element +// ignore_for_file: unused_field +''', + ), + headers: Headers( + entryPoints: [ + packageRoot.resolve('third_party/boringssl/src/include/openssl/aead.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/aes.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/bn.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/bytestring.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/cipher.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/crypto.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/digest.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/ec.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/ecdh.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/ec_key.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/ecdsa.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/err.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/evp.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/hkdf.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/hmac.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/mem.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/rand.h'), + packageRoot.resolve('third_party/boringssl/src/include/openssl/rsa.h'), + ], + compilerOptions: [ + '-Ithird_party/boringssl/src/include', + '-DBORINGSSL_PREFIX=webcrypto', + '-U__PRAGMA_REDEFINE_EXTNAME', + ], + ), + macros: Macros( + include: Declarations.includeSet({ + 'AES_BLOCK_SIZE', + 'EC_PKEY_NO_PUBKEY', + 'EVP_PKEY_EC', + 'EVP_PKEY_RSA', + 'HKDF_R_OUTPUT_TOO_LARGE', + 'NID_secp384r1', + 'NID_secp521r1', + 'NID_X9_62_prime256v1', + 'RSA_PKCS1_OAEP_PADDING', + 'RSA_PKCS1_PADDING', + 'RSA_PKCS1_PSS_PADDING', + }), + ), + enums: Enums( + include: Declarations.includeSet({ + 'point_conversion_form_t', + }), + style: (decl, suggestedStyle) => EnumStyle.intConstants, + ), + unnamedEnums: UnnamedEnums( + include: Declarations.includeSet({ + 'ERR_LIB_HKDF', + }), + ), + structs: Structs( + include: Declarations.includeSet({ + 'cbs_st', + 'cbb_st', + }), + dependencies: CompoundDependencies.opaque, + ), + typedefs: const Typedefs( + include: Declarations.includeAll, + ), + functions: Functions( + include: Declarations.includeSet({ + // Source of truth for BoringSSL entry points bound from Dart. + 'webcrypto_BN_bin2bn', + 'webcrypto_BN_bn2bin_padded', + 'webcrypto_BN_free', + 'webcrypto_BN_new', + 'webcrypto_BN_num_bytes', + 'webcrypto_BN_set_word', + 'webcrypto_CBB_cleanup', + 'webcrypto_CBB_data', + 'webcrypto_CBB_flush', + 'webcrypto_CBB_init', + 'webcrypto_CBB_len', + 'webcrypto_CBB_zero', + 'webcrypto_CRYPTO_memcmp', + 'webcrypto_ECDH_compute_key', + 'webcrypto_ECDSA_SIG_free', + 'webcrypto_ECDSA_SIG_get0', + 'webcrypto_ECDSA_SIG_marshal', + 'webcrypto_ECDSA_SIG_new', + 'webcrypto_ECDSA_SIG_parse', + 'webcrypto_EC_GROUP_get0_order', + 'webcrypto_EC_GROUP_get_curve_name', + 'webcrypto_EC_GROUP_get_degree', + 'webcrypto_EC_KEY_check_key', + 'webcrypto_EC_KEY_free', + 'webcrypto_EC_KEY_generate_key', + 'webcrypto_EC_KEY_get0_group', + 'webcrypto_EC_KEY_get0_private_key', + 'webcrypto_EC_KEY_get0_public_key', + 'webcrypto_EC_KEY_get_enc_flags', + 'webcrypto_EC_KEY_new_by_curve_name', + 'webcrypto_EC_KEY_set_enc_flags', + 'webcrypto_EC_KEY_set_private_key', + 'webcrypto_EC_KEY_set_public_key', + 'webcrypto_EC_KEY_set_public_key_affine_coordinates', + 'webcrypto_EC_POINT_free', + 'webcrypto_EC_POINT_get_affine_coordinates_GFp', + 'webcrypto_EC_POINT_new', + 'webcrypto_EC_POINT_oct2point', + 'webcrypto_EC_POINT_point2cbb', + 'webcrypto_ERR_clear_error', + 'webcrypto_ERR_error_string_n', + 'webcrypto_ERR_get_error', + 'webcrypto_ERR_peek_error', + 'webcrypto_EVP_aead_aes_128_gcm', + 'webcrypto_EVP_aead_aes_256_gcm', + 'webcrypto_EVP_AEAD_CTX_free', + 'webcrypto_EVP_AEAD_CTX_new', + 'webcrypto_EVP_AEAD_CTX_open', + 'webcrypto_EVP_AEAD_CTX_seal', + 'webcrypto_EVP_AEAD_max_overhead', + 'webcrypto_EVP_aes_128_cbc', + 'webcrypto_EVP_aes_128_ctr', + 'webcrypto_EVP_aes_256_cbc', + 'webcrypto_EVP_aes_256_ctr', + 'webcrypto_EVP_CIPHER_CTX_free', + 'webcrypto_EVP_CIPHER_CTX_new', + 'webcrypto_EVP_CipherFinal_ex', + 'webcrypto_EVP_CipherInit_ex', + 'webcrypto_EVP_CIPHER_iv_length', + 'webcrypto_EVP_CipherUpdate', + 'webcrypto_EVP_DigestFinal', + 'webcrypto_EVP_DigestInit', + 'webcrypto_EVP_DigestSignFinal', + 'webcrypto_EVP_DigestSignInit', + 'webcrypto_EVP_DigestSignUpdate', + 'webcrypto_EVP_DigestUpdate', + 'webcrypto_EVP_DigestVerifyFinal', + 'webcrypto_EVP_DigestVerifyInit', + 'webcrypto_EVP_DigestVerifyUpdate', + 'webcrypto_EVP_marshal_private_key', + 'webcrypto_EVP_marshal_public_key', + 'webcrypto_EVP_MD_CTX_free', + 'webcrypto_EVP_MD_CTX_new', + 'webcrypto_EVP_MD_CTX_size', + 'webcrypto_EVP_parse_private_key', + 'webcrypto_EVP_parse_public_key', + 'webcrypto_EVP_PKEY_CTX_free', + 'webcrypto_EVP_PKEY_CTX_new', + 'webcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label', + 'webcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md', + 'webcrypto_EVP_PKEY_CTX_set_rsa_oaep_md', + 'webcrypto_EVP_PKEY_CTX_set_rsa_padding', + 'webcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen', + 'webcrypto_EVP_PKEY_decrypt', + 'webcrypto_EVP_PKEY_decrypt_init', + 'webcrypto_EVP_PKEY_encrypt', + 'webcrypto_EVP_PKEY_encrypt_init', + 'webcrypto_EVP_PKEY_free', + 'webcrypto_EVP_PKEY_get1_EC_KEY', + 'webcrypto_EVP_PKEY_get1_RSA', + 'webcrypto_EVP_PKEY_id', + 'webcrypto_EVP_PKEY_new', + 'webcrypto_EVP_PKEY_set1_EC_KEY', + 'webcrypto_EVP_PKEY_set1_RSA', + 'webcrypto_EVP_sha1', + 'webcrypto_EVP_sha256', + 'webcrypto_EVP_sha384', + 'webcrypto_EVP_sha512', + 'webcrypto_HKDF', + 'webcrypto_HMAC_CTX_free', + 'webcrypto_HMAC_CTX_new', + 'webcrypto_HMAC_Final', + 'webcrypto_HMAC_Init_ex', + 'webcrypto_HMAC_size', + 'webcrypto_HMAC_Update', + 'webcrypto_OPENSSL_malloc', + 'webcrypto_PKCS5_PBKDF2_HMAC', + 'webcrypto_RAND_bytes', + 'webcrypto_RSA_check_key', + 'webcrypto_RSA_free', + 'webcrypto_RSA_generate_key_ex', + 'webcrypto_RSA_get0_crt_params', + 'webcrypto_RSA_get0_factors', + 'webcrypto_RSA_get0_key', + 'webcrypto_RSA_new', + 'webcrypto_RSAPublicKey_dup', + 'webcrypto_RSA_set0_crt_params', + 'webcrypto_RSA_set0_factors', + 'webcrypto_RSA_set0_key', + // These are referenced, just need to be sorted right. + 'webcrypto_OPENSSL_free', + 'webcrypto_OPENSSL_memdup', + 'webcrypto_EVP_MD_size', + // Not used but maybe they should be: + 'webcrypto_EVP_AEAD_nonce_length', + 'webcrypto_EVP_AEAD_max_tag_len', + // Not used by nice to have, maybe, or maybe we remove / comment them out + 'webcrypto_EVP_AEAD_key_length', + 'webcrypto_BN_value_one', + 'webcrypto_BN_add', + 'webcrypto_BN_sub', + 'webcrypto_BN_cmp', + 'webcrypto_BN_lshift', + 'webcrypto_EVP_CIPHER_block_size', + 'webcrypto_EC_GROUP_new_by_curve_name', + 'webcrypto_EC_GROUP_free', + 'webcrypto_EVP_PKEY_set_type', + // Self testing only.. + 'webcrypto_BORINGSSL_self_test', + }), + rename: (decl) { + final name = decl.originalName; + if (name.startsWith('webcrypto_')) { + return name.substring('webcrypto_'.length); + } + return name; + }, + ), + ).generate(); +} diff --git a/tool/update-bindings.sh b/tool/update-bindings.sh index 9ff4da9ec..be7901552 100755 --- a/tool/update-bindings.sh +++ b/tool/update-bindings.sh @@ -22,5 +22,4 @@ cd "$DIR/.." dart pub get --no-example -dart run ffigen --config=lib/src/boringssl/bindings/ffigen.yaml -dart run ffigen --config=lib/src/third_party/boringssl/ffigen.yaml +dart run tool/ffigen.dart From afb736c1cca29b6549696497a28f9ed835cbf8cf Mon Sep 17 00:00:00 2001 From: mosuem Date: Wed, 15 Jul 2026 13:19:19 +0000 Subject: [PATCH 2/9] upgrade --- CHANGELOG.md | 1 + pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 660b3c05f..88f838af6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # 0.6.2-wip * Fixed JS interop to enable WebAssembly. +* Upgrade `ffigen` and `hooks` versions. # 0.6.1 * Added Dart native build hooks and native asset lookup for the bundled diff --git a/pubspec.yaml b/pubspec.yaml index 7d5771630..2af2b8dba 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,7 +22,7 @@ environment: dependencies: ffi: ^2.0.0 - hooks: ^1.0.0 + hooks: ^2.1.0 code_assets: ^1.0.0 native_toolchain_cmake: ^0.2.4 meta: ^1.3.0 From 00877aeaacbbaddd6bab305d00102c5bd24e9263 Mon Sep 17 00:00:00 2001 From: mosuem Date: Wed, 15 Jul 2026 13:42:40 +0000 Subject: [PATCH 3/9] feat: add native artifact fetching and build workflow - Add hooks.user_defines.webcrypto.buildMode: fetch to pubspec.yaml - Support fetch, build, and local build modes in hook/build.dart - Add lib/src/hook_helpers/hashes.dart and tool/regenerate_hashes.dart for SHA256 integrity checks - Add .github/workflows/release-artifacts.yml matrix workflow supporting Linux, macOS, Windows, Android, and iOS - Pin workflow actions to full commit SHA hashes --- .github/workflows/release-artifacts.yml | 132 +++++++++++++++ hook/build.dart | 204 ++++++++++++++++++++---- lib/src/hook_helpers/hashes.dart | 28 ++++ pubspec.yaml | 6 + tool/regenerate_hashes.dart | 77 +++++++++ 5 files changed, 420 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/release-artifacts.yml create mode 100644 lib/src/hook_helpers/hashes.dart create mode 100644 tool/regenerate_hashes.dart diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml new file mode 100644 index 000000000..d371d373d --- /dev/null +++ b/.github/workflows/release-artifacts.yml @@ -0,0 +1,132 @@ +name: Build & Upload Release Artifacts + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+*' + workflow_dispatch: + +jobs: + build-artifacts: + name: Build Native Artifact (${{ matrix.target.os }}-${{ matrix.target.arch }}) + runs-on: ${{ matrix.target.runner }} + strategy: + fail-fast: false + matrix: + target: + - os: linux + arch: x64 + runner: ubuntu-latest + artifact: libwebcrypto.so + asset_name: webcrypto-linux-x64-libwebcrypto.so + - os: macos + arch: x64 + runner: macos-13 + artifact: libwebcrypto.dylib + asset_name: webcrypto-macOS-x64-libwebcrypto.dylib + - os: macos + arch: arm64 + runner: macos-14 + artifact: libwebcrypto.dylib + asset_name: webcrypto-macOS-arm64-libwebcrypto.dylib + - os: windows + arch: x64 + runner: windows-latest + artifact: webcrypto.dll + asset_name: webcrypto-windows-x64-webcrypto.dll + - os: android + arch: arm64 + abi: arm64-v8a + runner: ubuntu-latest + artifact: libwebcrypto.so + asset_name: webcrypto-android-arm64-libwebcrypto.so + - os: android + arch: arm + abi: armeabi-v7a + runner: ubuntu-latest + artifact: libwebcrypto.so + asset_name: webcrypto-android-arm-libwebcrypto.so + - os: android + arch: x64 + abi: x86_64 + runner: ubuntu-latest + artifact: libwebcrypto.so + asset_name: webcrypto-android-x64-libwebcrypto.so + - os: iOS + arch: arm64 + runner: macos-14 + artifact: libwebcrypto.dylib + asset_name: webcrypto-iOS-arm64-libwebcrypto.dylib + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: subosito/flutter-action@f37a2a73da312e3e63f5c0b9634526d2b0e7fe88 + with: + channel: 'stable' + cache: true + + - name: Configure Linux Dependencies + if: matrix.target.os == 'linux' + run: | + sudo apt-get update -y + sudo apt-get install -y cmake ninja-build libgtk-3-dev + + - name: Build Native Library for Android (CMake NDK) + if: matrix.target.os == 'android' + run: | + mkdir -p build_native + cd build_native + cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake \ + -DANDROID_ABI=${{ matrix.target.abi }} \ + -DANDROID_PLATFORM=android-21 \ + -DCMAKE_BUILD_TYPE=Release ../src + cmake --build . --config Release + + - name: Build Native Library for iOS (CMake) + if: matrix.target.os == 'iOS' + run: | + mkdir -p build_native + cd build_native + cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES="arm64" -DCMAKE_BUILD_TYPE=Release ../src + cmake --build . --config Release --target webcrypto + + - name: Build Desktop Native Library (CMake) + if: matrix.target.os != 'android' && matrix.target.os != 'iOS' + run: | + mkdir -p build_native + cd build_native + cmake -DCMAKE_BUILD_TYPE=Release ../src + cmake --build . --config Release + + - name: Locate, Rename, and Hash Artifact + shell: bash + run: | + LIBRARY_PATH=$(find build_native -name "${{ matrix.target.artifact }}" | head -n 1) + if [ -z "$LIBRARY_PATH" ]; then + echo "Error: Could not find ${{ matrix.target.artifact }}" + exit 1 + fi + cp "$LIBRARY_PATH" "./${{ matrix.target.asset_name }}" + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "./${{ matrix.target.asset_name }}" > "./${{ matrix.target.asset_name }}.sha256" + else + shasum -a 256 "./${{ matrix.target.asset_name }}" > "./${{ matrix.target.asset_name }}.sha256" + fi + + - name: Upload Build Artifacts (Workflow Debugging) + uses: actions/upload-artifact@b4b15b348d6a79ff96702e61a5847e68810fe949 + with: + name: ${{ matrix.target.asset_name }} + path: | + ./${{ matrix.target.asset_name }} + ./${{ matrix.target.asset_name }}.sha256 + + - name: Upload Release Asset (Release Tags Only) + if: startsWith(github.ref, 'refs/tags/') + uses: softprops/action-gh-release@c95fe0c20b7ea1f2c1494446929e7f3e254c693a + with: + files: | + ./${{ matrix.target.asset_name }} + ./${{ matrix.target.asset_name }}.sha256 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/hook/build.dart b/hook/build.dart index fcbf862bb..ddc09369e 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -15,11 +15,37 @@ import 'dart:io'; import 'package:code_assets/code_assets.dart'; +import 'package:crypto/crypto.dart' show sha256; import 'package:hooks/hooks.dart'; import 'package:native_toolchain_cmake/native_toolchain_cmake.dart'; +import 'package:webcrypto/src/hook_helpers/hashes.dart' + show fileHashes, releaseVersion; const _assetName = 'webcrypto.dart'; +enum BuildModeEnum { fetch, build, local } + +class BuildOptions { + final BuildModeEnum buildMode; + final Uri? localPath; + + BuildOptions({required this.buildMode, this.localPath}); + + factory BuildOptions.fromDefines(HookInputUserDefines defines) { + return BuildOptions( + buildMode: BuildModeEnum.values.firstWhere( + (element) => element.name == defines['buildMode'], + orElse: () => BuildModeEnum.fetch, + ), + localPath: defines.path('localPath'), + ); + } + + @override + String toString() => + 'BuildOptions(buildMode: $buildMode, localPath: $localPath)'; +} + Future main(List args) async { await build(args, (input, output) async { // Skip build for non-code targets (e.g. web builds via flutter drive). @@ -30,43 +56,167 @@ Future main(List args) async { return; } - final packageRoot = input.packageRoot; - final installDir = input.outputDirectory.resolve('install/'); - final sourceDir = packageRoot.resolve('src/'); + final buildOptions = BuildOptions.fromDefines(input.userDefines); + stdout.writeln('webcrypto: build options: $buildOptions'); - stdout.writeln( - 'webcrypto: building native asset for ' - '${input.config.code.targetOS}-${input.config.code.targetArchitecture}.', - ); + switch (buildOptions.buildMode) { + case BuildModeEnum.fetch: + await _fetchPrebuiltBinary(input, output); + case BuildModeEnum.build: + await _buildLocalCMake(input, output); + case BuildModeEnum.local: + await _useLocalBinary(input, output, buildOptions.localPath); + } + output.dependencies.add(input.packageRoot.resolve('pubspec.yaml')); + }); +} - final builder = CMakeBuilder.create( - name: 'webcrypto', - sourceDir: sourceDir, - defines: { - 'CMAKE_BUILD_TYPE': 'Release', - 'CMAKE_INSTALL_PREFIX': installDir.toFilePath(), - }, - targets: ['install'], - ); +Future _fetchPrebuiltBinary( + BuildInput input, + BuildOutputBuilder output, +) async { + final targetOS = input.config.code.targetOS; + final targetArch = input.config.code.targetArchitecture; + final dylibFileName = targetOS.dylibFileName('webcrypto'); - await builder.run(input: input, output: output); + final targetTriple = '${targetOS.name}-${targetArch.name}'; + final expectedHash = fileHashes[targetTriple]; - final assets = await output.findAndAddCodeAssets( - input, - outDir: installDir, - names: {r'(lib)?webcrypto\.(dll|dylib|so)': _assetName}, - regExp: true, + if (expectedHash == null || expectedHash.isEmpty) { + throw BuildError( + message: + 'No prebuilt binary hash registered for target $targetTriple in package:webcrypto.\n' + 'To build webcrypto locally from source instead, set `buildMode: build` in your pubspec.yaml under `hooks.user_defines.webcrypto`.', ); - if (assets.isEmpty) { + } + + final assetName = 'webcrypto-$targetTriple-$dylibFileName'; + final binaryUrl = Uri.parse( + 'https://github.com/google/webcrypto.dart/releases/download/v$releaseVersion/$assetName', + ); + + stdout.writeln( + 'webcrypto: fetching prebuilt binary from $binaryUrl...', + ); + + final client = HttpClient(); + try { + final request = await client.getUrl(binaryUrl); + final response = await request.close(); + if (response.statusCode != 200) { throw BuildError( message: - 'Failed to locate built webcrypto dynamic library in ' - '${installDir.toFilePath()}', + 'Failed to fetch prebuilt webcrypto binary from $binaryUrl (HTTP ${response.statusCode}).\n' + 'To build webcrypto locally from source instead, set `buildMode: build` in your pubspec.yaml under `hooks.user_defines.webcrypto`.', ); } - output.dependencies.addAll(_buildDependencies(packageRoot)); - }); + final bytes = await response.fold>([], (a, b) => a..addAll(b)); + final actualHash = sha256.convert(bytes).toString(); + + if (actualHash != expectedHash) { + throw BuildError( + message: + 'SHA256 hash mismatch for prebuilt binary $assetName.\n' + 'Expected: $expectedHash\n' + 'Actual: $actualHash\n' + 'To build webcrypto locally from source instead, set `buildMode: build` in your pubspec.yaml under `hooks.user_defines.webcrypto`.', + ); + } + + stdout.writeln('webcrypto: verified SHA256 checksum ($actualHash).'); + + final libraryFile = File.fromUri( + input.outputDirectory.resolve(dylibFileName), + ); + await libraryFile.writeAsBytes(bytes); + + output.assets.code.add( + CodeAsset( + package: input.packageName, + name: _assetName, + linkMode: DynamicLoadingBundled(), + file: libraryFile.uri, + ), + ); + } finally { + client.close(); + } +} + +Future _useLocalBinary( + BuildInput input, + BuildOutputBuilder output, + Uri? localPath, +) async { + if (localPath == null) { + throw BuildError( + message: + 'buildMode is set to `local`, but `localPath` was not specified under `hooks.user_defines.webcrypto`.', + ); + } + final file = File.fromUri(localPath); + if (!file.existsSync()) { + throw BuildError( + message: + 'Specified local binary does not exist at ${localPath.toFilePath()}', + ); + } + final dylibFileName = input.config.code.targetOS.dylibFileName('webcrypto'); + final destFile = File.fromUri(input.outputDirectory.resolve(dylibFileName)); + await file.copy(destFile.path); + + output.assets.code.add( + CodeAsset( + package: input.packageName, + name: _assetName, + linkMode: DynamicLoadingBundled(), + file: destFile.uri, + ), + ); + output.dependencies.add(localPath); +} + +Future _buildLocalCMake( + BuildInput input, + BuildOutputBuilder output, +) async { + final packageRoot = input.packageRoot; + final installDir = input.outputDirectory.resolve('install/'); + final sourceDir = packageRoot.resolve('src/'); + + stdout.writeln( + 'webcrypto: building native asset with CMake for ' + '${input.config.code.targetOS}-${input.config.code.targetArchitecture}.', + ); + + final builder = CMakeBuilder.create( + name: 'webcrypto', + sourceDir: sourceDir, + defines: { + 'CMAKE_BUILD_TYPE': 'Release', + 'CMAKE_INSTALL_PREFIX': installDir.toFilePath(), + }, + targets: ['install'], + ); + + await builder.run(input: input, output: output); + + final assets = await output.findAndAddCodeAssets( + input, + outDir: installDir, + names: {r'(lib)?webcrypto\.(dll|dylib|so)': _assetName}, + regExp: true, + ); + if (assets.isEmpty) { + throw BuildError( + message: + 'Failed to locate built webcrypto dynamic library in ' + '${installDir.toFilePath()}', + ); + } + + output.dependencies.addAll(_buildDependencies(packageRoot)); } final _buildDependencyExtensions = { diff --git a/lib/src/hook_helpers/hashes.dart b/lib/src/hook_helpers/hashes.dart new file mode 100644 index 000000000..cae5193e7 --- /dev/null +++ b/lib/src/hook_helpers/hashes.dart @@ -0,0 +1,28 @@ +// Copyright 2025 Google LLC +// +// 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. + +// THIS FILE IS AUTOGENERATED BY `tool/regenerate_hashes.dart`. + +const releaseVersion = '0.6.2-wip'; + +const fileHashes = { + 'linux-x64': '', + 'macOS-x64': '', + 'macOS-arm64': '', + 'windows-x64': '', + 'android-arm64': '', + 'android-arm': '', + 'android-x64': '', + 'iOS-arm64': '', +}; diff --git a/pubspec.yaml b/pubspec.yaml index 2af2b8dba..94d86b95f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,6 +26,7 @@ dependencies: code_assets: ^1.0.0 native_toolchain_cmake: ^0.2.4 meta: ^1.3.0 + crypto: ^3.0.0 dev_dependencies: ffigen: ^20.0.0 @@ -34,5 +35,10 @@ dev_dependencies: flutter_lints: ^6.0.0 coverage: any # we only need format_coverage, don't care what version +hooks: + user_defines: + webcrypto: + buildMode: fetch + topics: - crypto diff --git a/tool/regenerate_hashes.dart b/tool/regenerate_hashes.dart new file mode 100644 index 000000000..e5d5c338f --- /dev/null +++ b/tool/regenerate_hashes.dart @@ -0,0 +1,77 @@ +// Copyright 2025 Google LLC +// +// 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. + +import 'dart:io'; + +import 'package:crypto/crypto.dart' show sha256; + +Future main(List args) async { + final version = args.isNotEmpty ? args[0] : '0.6.2-wip'; + final httpClient = HttpClient(); + + stdout.writeln('Fetching binary hashes for release tag v$version...'); + final hashes = {}; + + final targets = [ + ('linux', 'x64', 'libwebcrypto.so'), + ('macOS', 'x64', 'libwebcrypto.dylib'), + ('macOS', 'arm64', 'libwebcrypto.dylib'), + ('windows', 'x64', 'webcrypto.dll'), + ('android', 'arm64', 'libwebcrypto.so'), + ('android', 'arm', 'libwebcrypto.so'), + ('android', 'x64', 'libwebcrypto.so'), + ('iOS', 'arm64', 'libwebcrypto.dylib'), + ]; + + for (final (os, arch, ext) in targets) { + final targetTriple = '$os-$arch'; + final assetName = 'webcrypto-$targetTriple-$ext'; + final uri = Uri.parse( + 'https://github.com/google/webcrypto.dart/releases/download/v$version/$assetName', + ); + + stdout.writeln('Fetching $assetName from $uri...'); + try { + final request = await httpClient.getUrl(uri); + final response = await request.close(); + if (response.statusCode != 200) { + stdout.writeln(' File not found (HTTP ${response.statusCode})'); + continue; + } + final bytes = await response.fold>([], (a, b) => a..addAll(b)); + final fileHash = sha256.convert(bytes).toString(); + hashes[targetTriple] = fileHash; + stdout.writeln(' Hash: $fileHash'); + } catch (e) { + stdout.writeln(' Error: $e'); + } + } + httpClient.close(force: true); + + final buffer = StringBuffer(); + buffer.writeln('// Copyright 2025 Google LLC'); + buffer.writeln('//'); + buffer.writeln('// THIS FILE IS AUTOGENERATED BY `tool/regenerate_hashes.dart`.'); + buffer.writeln(''); + buffer.writeln("const releaseVersion = '$version';"); + buffer.writeln(''); + buffer.writeln('const fileHashes = {'); + for (final entry in hashes.entries) { + buffer.writeln(" '${entry.key}': '${entry.value}',"); + } + buffer.writeln('};'); + + await File('lib/src/hook_helpers/hashes.dart').writeAsString(buffer.toString()); + stdout.writeln('Updated lib/src/hook_helpers/hashes.dart'); +} From 18b3f557c7fc3e951363b9a7d90b1cf108989312 Mon Sep 17 00:00:00 2001 From: mosuem Date: Thu, 16 Jul 2026 14:12:50 +0000 Subject: [PATCH 4/9] Use runStandalone --- .github/workflows/release-artifacts.yml | 28 +------- hook/build.dart | 12 ++-- pubspec.yaml | 2 + tool/build_native.dart | 87 +++++++++++++++++++++++++ tool/ffigen.dart | 60 ++++++++--------- tool/regenerate_hashes.dart | 8 ++- 6 files changed, 131 insertions(+), 66 deletions(-) create mode 100644 tool/build_native.dart diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml index d371d373d..1212d3a0b 100644 --- a/.github/workflows/release-artifacts.yml +++ b/.github/workflows/release-artifacts.yml @@ -71,32 +71,10 @@ jobs: sudo apt-get update -y sudo apt-get install -y cmake ninja-build libgtk-3-dev - - name: Build Native Library for Android (CMake NDK) - if: matrix.target.os == 'android' + - name: Build Native Library (native_toolchain_cmake) run: | - mkdir -p build_native - cd build_native - cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake \ - -DANDROID_ABI=${{ matrix.target.abi }} \ - -DANDROID_PLATFORM=android-21 \ - -DCMAKE_BUILD_TYPE=Release ../src - cmake --build . --config Release - - - name: Build Native Library for iOS (CMake) - if: matrix.target.os == 'iOS' - run: | - mkdir -p build_native - cd build_native - cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES="arm64" -DCMAKE_BUILD_TYPE=Release ../src - cmake --build . --config Release --target webcrypto - - - name: Build Desktop Native Library (CMake) - if: matrix.target.os != 'android' && matrix.target.os != 'iOS' - run: | - mkdir -p build_native - cd build_native - cmake -DCMAKE_BUILD_TYPE=Release ../src - cmake --build . --config Release + dart pub get + dart run tool/build_native.dart --target-os ${{ matrix.target.os }} --target-architecture ${{ matrix.target.arch }} --output-dir ./build_native - name: Locate, Rename, and Hash Artifact shell: bash diff --git a/hook/build.dart b/hook/build.dart index ddc09369e..10346b34a 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -83,11 +83,11 @@ Future _fetchPrebuiltBinary( final expectedHash = fileHashes[targetTriple]; if (expectedHash == null || expectedHash.isEmpty) { - throw BuildError( - message: - 'No prebuilt binary hash registered for target $targetTriple in package:webcrypto.\n' - 'To build webcrypto locally from source instead, set `buildMode: build` in your pubspec.yaml under `hooks.user_defines.webcrypto`.', + stdout.writeln( + 'webcrypto: no prebuilt binary hash registered for $targetTriple, falling back to building from source.', ); + await _buildLocalCMake(input, output); + return; } final assetName = 'webcrypto-$targetTriple-$dylibFileName'; @@ -95,9 +95,7 @@ Future _fetchPrebuiltBinary( 'https://github.com/google/webcrypto.dart/releases/download/v$releaseVersion/$assetName', ); - stdout.writeln( - 'webcrypto: fetching prebuilt binary from $binaryUrl...', - ); + stdout.writeln('webcrypto: fetching prebuilt binary from $binaryUrl...'); final client = HttpClient(); try { diff --git a/pubspec.yaml b/pubspec.yaml index 94d86b95f..ed8099df0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -29,6 +29,7 @@ dependencies: crypto: ^3.0.0 dev_dependencies: + args: ^2.5.0 ffigen: ^20.0.0 test: ^1.30.0 yaml: ^3.0.0 @@ -42,3 +43,4 @@ hooks: topics: - crypto + \ No newline at end of file diff --git a/tool/build_native.dart b/tool/build_native.dart new file mode 100644 index 000000000..c546d1ba2 --- /dev/null +++ b/tool/build_native.dart @@ -0,0 +1,87 @@ +// Copyright 2026 Google LLC +// +// 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. + +import 'dart:io'; + +import 'package:args/args.dart'; +import 'package:code_assets/code_assets.dart'; +import 'package:native_toolchain_cmake/native_toolchain_cmake.dart'; + +Future main(List args) async { + final parser = ArgParser() + ..addOption( + 'target-os', + help: + 'The target operating system (e.g. linux, macos, windows, android, ios).', + mandatory: true, + allowed: OS.values.map((os) => os.name).toList(), + ) + ..addOption( + 'target-architecture', + help: 'The target architecture (e.g. x64, arm64, arm, ia32, riscv64).', + mandatory: true, + allowed: Architecture.values.map((arch) => arch.name).toList(), + ) + ..addOption( + 'output-dir', + help: + 'The directory where build artifacts and installation will be output.', + mandatory: true, + ); + + ArgResults argResults; + try { + argResults = parser.parse(args); + } catch (e) { + stderr.writeln('Error: $e\n'); + stderr.writeln('Usage:\n${parser.usage}'); + exit(64); + } + + final targetOS = OS.fromString(argResults.option('target-os')!); + final targetArch = Architecture.fromString( + argResults.option('target-architecture')!, + ); + final outputDirectory = Directory( + argResults.option('output-dir')!, + ).absolute.uri; + + final packageRoot = Directory.current.uri; + final installDir = outputDirectory.resolve('install/'); + final sourceDir = packageRoot.resolve('src/'); + + if (!Directory.fromUri(sourceDir).existsSync()) { + stderr.writeln( + 'Error: Source directory does not exist at ${sourceDir.toFilePath()}', + ); + exit(66); + } + + final builder = CMakeBuilder.create( + name: 'webcrypto', + sourceDir: sourceDir, + defines: { + 'CMAKE_BUILD_TYPE': 'Release', + 'CMAKE_INSTALL_PREFIX': installDir.toFilePath(), + }, + targets: ['install'], + ); + + await builder.runStandalone( + outputDirectory: outputDirectory, + targetOS: targetOS, + targetArchitecture: targetArch, + packageRoot: packageRoot, + ); +} diff --git a/tool/ffigen.dart b/tool/ffigen.dart index 89c5525b5..4ed1fae45 100644 --- a/tool/ffigen.dart +++ b/tool/ffigen.dart @@ -26,8 +26,9 @@ void main() { void generateWebCryptoBindings(Uri packageRoot) { FfiGenerator( output: Output( - dartFile: packageRoot - .resolve('lib/src/boringssl/bindings/generated_bindings.dart'), + dartFile: packageRoot.resolve( + 'lib/src/boringssl/bindings/generated_bindings.dart', + ), style: const NativeExternalBindings( assetId: 'package:webcrypto/webcrypto.dart', ), @@ -52,20 +53,12 @@ void generateWebCryptoBindings(Uri packageRoot) { // ignore_for_file: non_constant_identifier_names ''', ), - headers: Headers( - entryPoints: [ - packageRoot.resolve('src/webcrypto.h'), - ], - ), + headers: Headers(entryPoints: [packageRoot.resolve('src/webcrypto.h')]), functions: Functions( include: Declarations.includeSet({'webcrypto_get_CBB_size'}), ), - structs: const Structs( - dependencies: CompoundDependencies.opaque, - ), - typedefs: const Typedefs( - include: Declarations.includeAll, - ), + structs: const Structs(dependencies: CompoundDependencies.opaque), + typedefs: const Typedefs(include: Declarations.includeAll), ).generate(); } @@ -144,14 +137,26 @@ void generateBoringSslBindings(Uri packageRoot) { packageRoot.resolve('third_party/boringssl/src/include/openssl/aead.h'), packageRoot.resolve('third_party/boringssl/src/include/openssl/aes.h'), packageRoot.resolve('third_party/boringssl/src/include/openssl/bn.h'), - packageRoot.resolve('third_party/boringssl/src/include/openssl/bytestring.h'), - packageRoot.resolve('third_party/boringssl/src/include/openssl/cipher.h'), - packageRoot.resolve('third_party/boringssl/src/include/openssl/crypto.h'), - packageRoot.resolve('third_party/boringssl/src/include/openssl/digest.h'), + packageRoot.resolve( + 'third_party/boringssl/src/include/openssl/bytestring.h', + ), + packageRoot.resolve( + 'third_party/boringssl/src/include/openssl/cipher.h', + ), + packageRoot.resolve( + 'third_party/boringssl/src/include/openssl/crypto.h', + ), + packageRoot.resolve( + 'third_party/boringssl/src/include/openssl/digest.h', + ), packageRoot.resolve('third_party/boringssl/src/include/openssl/ec.h'), packageRoot.resolve('third_party/boringssl/src/include/openssl/ecdh.h'), - packageRoot.resolve('third_party/boringssl/src/include/openssl/ec_key.h'), - packageRoot.resolve('third_party/boringssl/src/include/openssl/ecdsa.h'), + packageRoot.resolve( + 'third_party/boringssl/src/include/openssl/ec_key.h', + ), + packageRoot.resolve( + 'third_party/boringssl/src/include/openssl/ecdsa.h', + ), packageRoot.resolve('third_party/boringssl/src/include/openssl/err.h'), packageRoot.resolve('third_party/boringssl/src/include/openssl/evp.h'), packageRoot.resolve('third_party/boringssl/src/include/openssl/hkdf.h'), @@ -182,26 +187,17 @@ void generateBoringSslBindings(Uri packageRoot) { }), ), enums: Enums( - include: Declarations.includeSet({ - 'point_conversion_form_t', - }), + include: Declarations.includeSet({'point_conversion_form_t'}), style: (decl, suggestedStyle) => EnumStyle.intConstants, ), unnamedEnums: UnnamedEnums( - include: Declarations.includeSet({ - 'ERR_LIB_HKDF', - }), + include: Declarations.includeSet({'ERR_LIB_HKDF'}), ), structs: Structs( - include: Declarations.includeSet({ - 'cbs_st', - 'cbb_st', - }), + include: Declarations.includeSet({'cbs_st', 'cbb_st'}), dependencies: CompoundDependencies.opaque, ), - typedefs: const Typedefs( - include: Declarations.includeAll, - ), + typedefs: const Typedefs(include: Declarations.includeAll), functions: Functions( include: Declarations.includeSet({ // Source of truth for BoringSSL entry points bound from Dart. diff --git a/tool/regenerate_hashes.dart b/tool/regenerate_hashes.dart index e5d5c338f..0d5b5584c 100644 --- a/tool/regenerate_hashes.dart +++ b/tool/regenerate_hashes.dart @@ -62,7 +62,9 @@ Future main(List args) async { final buffer = StringBuffer(); buffer.writeln('// Copyright 2025 Google LLC'); buffer.writeln('//'); - buffer.writeln('// THIS FILE IS AUTOGENERATED BY `tool/regenerate_hashes.dart`.'); + buffer.writeln( + '// THIS FILE IS AUTOGENERATED BY `tool/regenerate_hashes.dart`.', + ); buffer.writeln(''); buffer.writeln("const releaseVersion = '$version';"); buffer.writeln(''); @@ -72,6 +74,8 @@ Future main(List args) async { } buffer.writeln('};'); - await File('lib/src/hook_helpers/hashes.dart').writeAsString(buffer.toString()); + await File( + 'lib/src/hook_helpers/hashes.dart', + ).writeAsString(buffer.toString()); stdout.writeln('Updated lib/src/hook_helpers/hashes.dart'); } From 67273232e3126696a1b9128a25f9b8e4aa24dd17 Mon Sep 17 00:00:00 2001 From: mosuem Date: Thu, 16 Jul 2026 14:53:38 +0000 Subject: [PATCH 5/9] fix readme --- README.md | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f63648e7a..47d2b0305 100644 --- a/README.md +++ b/README.md @@ -52,13 +52,29 @@ see `doc/design-rationale-md`. ## System dependencies -When you have a dependency on `package:webcrypto`, it will use -[hooks](https://dart.dev/tools/hooks) to build BoringSSL. Thus, your system -must have: +By default, `package:webcrypto` uses [hooks](https://dart.dev/tools/hooks) to fetch prebuilt native binaries, so no additional system dependencies are required for supported target platforms. + +### Build Configuration + +You can configure the build mode in `pubspec.yaml`: + +```yaml +hooks: + user_defines: + webcrypto: + buildMode: fetch # Options: 'fetch' (default), 'build', 'local' +``` + +* `fetch` (default): Downloads prebuilt binaries from release assets (falls back to building from source if prebuilt binaries are unavailable). +* `build`: Always builds BoringSSL locally from source using CMake. +* `local`: Uses a prebuilt binary from a specified local path (`localPath`). + +If you configure `package:webcrypto` to build from source, your system must have: * `cmake`, and, * a C compiler (like `gcc` or `clang`) + ## Limitations This package has a few limitations compared to the [Web Cryptography API][webcrypto-spec]. For a discussion of parity with From 387030a7f59405a1e44d2862a39d4aed4a994ef1 Mon Sep 17 00:00:00 2001 From: mosuem Date: Fri, 17 Jul 2026 08:47:25 +0000 Subject: [PATCH 6/9] use hooks 2.0 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index ed8099df0..df8418c17 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,7 +22,7 @@ environment: dependencies: ffi: ^2.0.0 - hooks: ^2.1.0 + hooks: ^2.0.0 code_assets: ^1.0.0 native_toolchain_cmake: ^0.2.4 meta: ^1.3.0 From 5138cf1384821eb160361ed7a9ed9825a86e5dcc Mon Sep 17 00:00:00 2001 From: mosuem Date: Fri, 17 Jul 2026 08:56:27 +0000 Subject: [PATCH 7/9] newline --- pubspec.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index df8418c17..6b14b66a1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -43,4 +43,3 @@ hooks: topics: - crypto - \ No newline at end of file From aa94577cdad3104f34777314ad09478ddf2712e2 Mon Sep 17 00:00:00 2001 From: mosuem Date: Wed, 15 Jul 2026 13:58:57 +0000 Subject: [PATCH 8/9] feat: add link hook for treeshaking native symbols via record_use - Add hook/link.dart using CLinker and record_use for native symbol treeshaking - Update hook/build.dart to support static library building and ToLinkHook routing - Add .github/workflows/treeshake-test.yml workflow for desktop treeshake testing - Update src/CMakeLists.txt to support BUILD_SHARED_LIBS --- .github/workflows/treeshake-test.yml | 47 +++++++++++++++ hook/build.dart | 50 ++++++++++++---- hook/link.dart | 90 ++++++++++++++++++++++++++++ pubspec.yaml | 5 +- src/CMakeLists.txt | 3 - 5 files changed, 181 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/treeshake-test.yml create mode 100644 hook/link.dart diff --git a/.github/workflows/treeshake-test.yml b/.github/workflows/treeshake-test.yml new file mode 100644 index 000000000..136190f58 --- /dev/null +++ b/.github/workflows/treeshake-test.yml @@ -0,0 +1,47 @@ +name: Link Hook Treeshake Test + +on: + push: + branches: [master] + pull_request: + branches: [master] + workflow_dispatch: + +jobs: + test-treeshake-desktop: + name: Link Hook Treeshake (${{ matrix.os }}) + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - os: linux + runner: ubuntu-latest + - os: macos + runner: macos-14 + - os: windows + runner: windows-latest + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + + - uses: subosito/flutter-action@f37a2a73da312e3e63f5c0b9634526d2b0e7fe88 + with: + channel: 'stable' + cache: true + + - name: Setup Windows NASM + if: matrix.os == 'windows' + uses: ilammy/setup-nasm@141b71216503c14c57c5f87b1c312781b012d093 + + - name: Configure Linux Dependencies + if: matrix.os == 'linux' + run: | + sudo apt-get update -y + sudo apt-get install -y cmake ninja-build libgtk-3-dev + + - name: Get Dependencies + run: flutter pub get + + - name: Run Tests with Link Hook & Record Use Treeshaking + run: dart test --enable-experiment=record-use diff --git a/hook/build.dart b/hook/build.dart index 10346b34a..0c0eb70bf 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -136,6 +136,9 @@ Future _fetchPrebuiltBinary( linkMode: DynamicLoadingBundled(), file: libraryFile.uri, ), + routing: input.config.linkingEnabled + ? ToLinkHook(input.packageName) + : const ToAppBundle(), ); } finally { client.close(); @@ -183,9 +186,12 @@ Future _buildLocalCMake( final installDir = input.outputDirectory.resolve('install/'); final sourceDir = packageRoot.resolve('src/'); + final buildStatic = input.config.buildStatic; + stdout.writeln( 'webcrypto: building native asset with CMake for ' - '${input.config.code.targetOS}-${input.config.code.targetArchitecture}.', + '${input.config.code.targetOS}-${input.config.code.targetArchitecture} ' + '(static: $buildStatic).', ); final builder = CMakeBuilder.create( @@ -194,29 +200,53 @@ Future _buildLocalCMake( defines: { 'CMAKE_BUILD_TYPE': 'Release', 'CMAKE_INSTALL_PREFIX': installDir.toFilePath(), + 'BUILD_SHARED_LIBS': buildStatic ? 'OFF' : 'ON', }, targets: ['install'], ); await builder.run(input: input, output: output); - final assets = await output.findAndAddCodeAssets( - input, - outDir: installDir, - names: {r'(lib)?webcrypto\.(dll|dylib|so)': _assetName}, - regExp: true, - ); - if (assets.isEmpty) { + final installDirPath = installDir.toFilePath(); + final installDirectory = Directory(installDirPath); + final matchingFiles = installDirectory.existsSync() + ? installDirectory + .listSync(recursive: true) + .whereType() + .where((f) => RegExp(r'(lib)?webcrypto\.(dll|dylib|so|a|lib)$').hasMatch(f.path)) + .toList() + : []; + + if (matchingFiles.isEmpty) { throw BuildError( message: - 'Failed to locate built webcrypto dynamic library in ' - '${installDir.toFilePath()}', + 'Failed to locate built webcrypto library in ' + '$installDirPath', ); } + final libraryFile = matchingFiles.first; + + output.assets.code.add( + CodeAsset( + package: input.packageName, + name: _assetName, + linkMode: buildStatic ? StaticLinking() : DynamicLoadingBundled(), + file: libraryFile.uri, + ), + routing: buildStatic && input.config.linkingEnabled + ? ToLinkHook(input.packageName) + : const ToAppBundle(), + ); + output.dependencies.addAll(_buildDependencies(packageRoot)); } +extension on BuildConfig { + bool get buildStatic => + code.linkModePreference == LinkModePreference.static || linkingEnabled; +} + final _buildDependencyExtensions = { '.S', '.asm', diff --git a/hook/link.dart b/hook/link.dart new file mode 100644 index 000000000..a2ab13539 --- /dev/null +++ b/hook/link.dart @@ -0,0 +1,90 @@ +// Copyright 2025 Google LLC +// +// 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. + +import 'dart:io'; + +import 'package:code_assets/code_assets.dart' + show CodeAsset, OS, HookConfigCodeConfig, LinkInputCodeAssets; +import 'package:hooks/hooks.dart' show link; +import 'package:logging/logging.dart' show Level, Logger; +import 'package:native_toolchain_c/native_toolchain_c.dart' + show CLinker, LinkerOptions; +import 'package:record_use/record_use.dart' as record_use; + +/// Run the linker to turn a static library into a treeshaken dynamic library. +Future main(List args) async { + await link(args, (input, output) async { + stdout.writeln('webcrypto: start link hook'); + + final CodeAsset staticLib; + try { + staticLib = input.assets.code.firstWhere( + (asset) => asset.id == 'package:webcrypto/webcrypto.dart', + ); + } catch (e) { + // No static library provided, assume a dynamic library was already bundled. + stdout.writeln('webcrypto: no static asset found for linking, skipping.'); + return; + } + + final recordedUses = input.recordedUses; + Iterable? usedSymbols; + + if (recordedUses == null) { + stdout.writeln( + 'webcrypto: --enable-experiment=record-use not active; linking all symbols.', + ); + } else { + usedSymbols = recordedUses.calls.keys + .where( + (id) => + id.library == + const record_use.Library( + 'package:webcrypto/src/boringssl/bindings/generated_bindings.dart', + ) || + id.library == + const record_use.Library( + 'package:webcrypto/src/third_party/boringssl/generated_bindings.dart', + ), + ) + .map((id) => id.name) + .where((methodName) => methodName.startsWith('_')) + .map((methodName) => methodName.substring(1)); + } + + stdout.writeln(''' +webcrypto treeshaking symbols: + ${usedSymbols?.join('\n') ?? 'All symbols preserved.'} +'''); + + await CLinker.library( + name: 'webcrypto', + packageName: input.packageName, + assetName: 'webcrypto.dart', + sources: [staticLib.file!.toFilePath()], + libraries: switch (input.config.code.targetOS) { + OS.windows => const ['MSVCRT', 'ws2_32', 'userenv', 'ntdll', 'bcrypt'], + OS.android => const ['m'], + _ => const [], + }, + linkerOptions: LinkerOptions.treeshake(symbolsToKeep: usedSymbols), + ).run( + input: input, + output: output, + logger: Logger('webcrypto_linker') + ..level = Level.ALL + ..onRecord.listen((record) => stdout.writeln(record.message)), + ); + }); +} diff --git a/pubspec.yaml b/pubspec.yaml index 6b14b66a1..de5cb6ebd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -25,6 +25,9 @@ dependencies: hooks: ^2.0.0 code_assets: ^1.0.0 native_toolchain_cmake: ^0.2.4 + native_toolchain_c: ^0.19.1 + record_use: ^1.0.0 + logging: ^1.3.0 meta: ^1.3.0 crypto: ^3.0.0 @@ -39,7 +42,7 @@ dev_dependencies: hooks: user_defines: webcrypto: - buildMode: fetch + buildMode: build topics: - crypto diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0d739186d..d83b1dbbf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -142,9 +142,6 @@ endif() add_library( webcrypto - # Build a shared library - SHARED - # Source files ../src/webcrypto.c ${crypto_sources} From 41ebdee31da4c6e85fd3ab413122edc74d286697 Mon Sep 17 00:00:00 2001 From: mosuem Date: Fri, 17 Jul 2026 15:15:07 +0000 Subject: [PATCH 9/9] add some more stuff --- .github/workflows/treeshake-test.yml | 4 +- hook/build.dart | 28 ++-- hook/link.dart | 37 +++-- .../bindings/generated_bindings.dart | 2 + .../boringssl/generated_bindings.dart | 136 +++++++++++++++ pubspec.yaml | 1 + src/CMakeLists.txt | 7 +- test/ffi/treeshake_target.dart | 21 +++ test/ffi/treeshake_test.dart | 155 ++++++++++++++++++ tool/ffigen.dart | 44 +++-- 10 files changed, 397 insertions(+), 38 deletions(-) create mode 100644 test/ffi/treeshake_target.dart create mode 100644 test/ffi/treeshake_test.dart diff --git a/.github/workflows/treeshake-test.yml b/.github/workflows/treeshake-test.yml index 136190f58..6dc43a7d4 100644 --- a/.github/workflows/treeshake-test.yml +++ b/.github/workflows/treeshake-test.yml @@ -43,5 +43,5 @@ jobs: - name: Get Dependencies run: flutter pub get - - name: Run Tests with Link Hook & Record Use Treeshaking - run: dart test --enable-experiment=record-use + - name: Run Treeshake Test with dart build & Size Limit Verification + run: dart test test/ffi/treeshake_test.dart diff --git a/hook/build.dart b/hook/build.dart index 0c0eb70bf..154463614 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -186,12 +186,10 @@ Future _buildLocalCMake( final installDir = input.outputDirectory.resolve('install/'); final sourceDir = packageRoot.resolve('src/'); - final buildStatic = input.config.buildStatic; - stdout.writeln( 'webcrypto: building native asset with CMake for ' '${input.config.code.targetOS}-${input.config.code.targetArchitecture} ' - '(static: $buildStatic).', + '(static: ${input.config.linkingEnabled}).', ); final builder = CMakeBuilder.create( @@ -200,7 +198,8 @@ Future _buildLocalCMake( defines: { 'CMAKE_BUILD_TYPE': 'Release', 'CMAKE_INSTALL_PREFIX': installDir.toFilePath(), - 'BUILD_SHARED_LIBS': buildStatic ? 'OFF' : 'ON', + 'CMAKE_POSITION_INDEPENDENT_CODE': 'ON', + 'BUILD_SHARED_LIBS': input.config.linkingEnabled ? 'OFF' : 'ON', }, targets: ['install'], ); @@ -211,10 +210,14 @@ Future _buildLocalCMake( final installDirectory = Directory(installDirPath); final matchingFiles = installDirectory.existsSync() ? installDirectory - .listSync(recursive: true) - .whereType() - .where((f) => RegExp(r'(lib)?webcrypto\.(dll|dylib|so|a|lib)$').hasMatch(f.path)) - .toList() + .listSync(recursive: true) + .whereType() + .where( + (f) => RegExp( + r'(lib)?webcrypto\.(dll|dylib|so|a|lib)$', + ).hasMatch(f.path), + ) + .toList() : []; if (matchingFiles.isEmpty) { @@ -231,10 +234,10 @@ Future _buildLocalCMake( CodeAsset( package: input.packageName, name: _assetName, - linkMode: buildStatic ? StaticLinking() : DynamicLoadingBundled(), + linkMode: DynamicLoadingBundled(), file: libraryFile.uri, ), - routing: buildStatic && input.config.linkingEnabled + routing: input.config.linkingEnabled ? ToLinkHook(input.packageName) : const ToAppBundle(), ); @@ -242,11 +245,6 @@ Future _buildLocalCMake( output.dependencies.addAll(_buildDependencies(packageRoot)); } -extension on BuildConfig { - bool get buildStatic => - code.linkModePreference == LinkModePreference.static || linkingEnabled; -} - final _buildDependencyExtensions = { '.S', '.asm', diff --git a/hook/link.dart b/hook/link.dart index a2ab13539..2d7544637 100644 --- a/hook/link.dart +++ b/hook/link.dart @@ -17,7 +17,7 @@ import 'dart:io'; import 'package:code_assets/code_assets.dart' show CodeAsset, OS, HookConfigCodeConfig, LinkInputCodeAssets; import 'package:hooks/hooks.dart' show link; -import 'package:logging/logging.dart' show Level, Logger; +import 'package:logging/logging.dart' show Logger; import 'package:native_toolchain_c/native_toolchain_c.dart' show CLinker, LinkerOptions; import 'package:record_use/record_use.dart' as record_use; @@ -38,10 +38,20 @@ Future main(List args) async { return; } + final disableTreeshakingUserDefine = input.userDefines['disable_treeshaking']; + final disableTreeshaking = + disableTreeshakingUserDefine == true || + disableTreeshakingUserDefine == 'true' || + Platform.environment['WEBCRYPTO_DISABLE_TREESHAKING'] == 'true'; + final recordedUses = input.recordedUses; - Iterable? usedSymbols; + Set? usedSymbols; - if (recordedUses == null) { + if (disableTreeshaking) { + stdout.writeln( + 'webcrypto: Treeshaking is disabled via user define (disable_treeshaking). All symbols will be preserved.', + ); + } else if (recordedUses == null) { stdout.writeln( 'webcrypto: --enable-experiment=record-use not active; linking all symbols.', ); @@ -59,14 +69,22 @@ Future main(List args) async { ), ) .map((id) => id.name) - .where((methodName) => methodName.startsWith('_')) - .map((methodName) => methodName.substring(1)); - } + .map((name) { + final nameWithoutLeadingUnderscore = name.startsWith('_') + ? name.substring(1) + : name; + return nameWithoutLeadingUnderscore.startsWith('webcrypto_') + ? nameWithoutLeadingUnderscore + : 'webcrypto_$nameWithoutLeadingUnderscore'; + }) + .toSet(); - stdout.writeln(''' -webcrypto treeshaking symbols: - ${usedSymbols?.join('\n') ?? 'All symbols preserved.'} + final sortedSymbols = usedSymbols.toList()..sort(); + stdout.writeln(''' +webcrypto treeshaking enabled (${sortedSymbols.length} symbols preserved): + ${sortedSymbols.join('\n ')} '''); + } await CLinker.library( name: 'webcrypto', @@ -83,7 +101,6 @@ webcrypto treeshaking symbols: input: input, output: output, logger: Logger('webcrypto_linker') - ..level = Level.ALL ..onRecord.listen((record) => stdout.writeln(record.message)), ); }); diff --git a/lib/src/boringssl/bindings/generated_bindings.dart b/lib/src/boringssl/bindings/generated_bindings.dart index 7f5c7d513..8cc3aeb69 100644 --- a/lib/src/boringssl/bindings/generated_bindings.dart +++ b/lib/src/boringssl/bindings/generated_bindings.dart @@ -23,8 +23,10 @@ library; import 'dart:ffi' as ffi; +import 'package:meta/meta.dart' as meta; /// Helper function to get the size of CBB structure for FFI allocation. +@meta.RecordUse() @ffi.Native() external int webcrypto_get_CBB_size(); diff --git a/lib/src/third_party/boringssl/generated_bindings.dart b/lib/src/third_party/boringssl/generated_bindings.dart index 4c94d6010..379932a6f 100644 --- a/lib/src/third_party/boringssl/generated_bindings.dart +++ b/lib/src/third_party/boringssl/generated_bindings.dart @@ -63,9 +63,11 @@ library; import 'dart:ffi' as ffi; +import 'package:meta/meta.dart' as meta; /// BN_add sets |r| = |a| + |b|, where |r| may be the same pointer as either |a| /// or |b|. It returns one on success and zero on allocation failure. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -83,6 +85,7 @@ external int BN_add( /// a big-endian number, and returns |ret|. If |ret| is NULL then a fresh /// |BIGNUM| is allocated and returned. It returns NULL on allocation /// failure. +@meta.RecordUse() @ffi.Native< ffi.Pointer Function( ffi.Pointer, @@ -100,6 +103,7 @@ external ffi.Pointer BN_bin2bn( /// big-endian integer. The integer is padded with leading zeros up to size /// |len|. If |len| is smaller than |BN_num_bytes|, the function fails and /// returns 0. Otherwise, it returns 1. +@meta.RecordUse() @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Size, ffi.Pointer) >(symbol: 'webcrypto_BN_bn2bin_padded') @@ -111,6 +115,7 @@ external int BN_bn2bin_padded( /// BN_cmp returns a value less than, equal to or greater than zero if |a| is /// less than, equal to or greater than |b|, respectively. +@meta.RecordUse() @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_BN_cmp', ) @@ -118,17 +123,20 @@ external int BN_cmp(ffi.Pointer a, ffi.Pointer b); /// BN_free frees the data referenced by |bn| and, if |bn| was originally /// allocated on the heap, frees |bn| also. +@meta.RecordUse() @ffi.Native)>(symbol: 'webcrypto_BN_free') external void BN_free(ffi.Pointer bn); /// BN_lshift sets |r| equal to |a| << n. The |a| and |r| arguments may be the /// same |BIGNUM|. It returns one on success and zero on allocation failure. +@meta.RecordUse() @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Int) >(symbol: 'webcrypto_BN_lshift') external int BN_lshift(ffi.Pointer r, ffi.Pointer a, int n); /// BN_new creates a new, allocated BIGNUM and initialises it. +@meta.RecordUse() @ffi.Native Function()>(symbol: 'webcrypto_BN_new') external ffi.Pointer BN_new(); @@ -138,6 +146,7 @@ external ffi.Pointer BN_new(); /// While |size_t| is the preferred type for byte counts, callers can assume that /// |BIGNUM|s are bounded such that this value, and its corresponding bit count, /// will always fit in |int|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_BN_num_bytes', ) @@ -145,6 +154,7 @@ external int BN_num_bytes(ffi.Pointer bn); /// BN_set_word sets |bn| to |value|. It returns one on success or zero on /// allocation failure. +@meta.RecordUse() @ffi.Native, BN_ULONG)>( symbol: 'webcrypto_BN_set_word', ) @@ -152,6 +162,7 @@ external int BN_set_word(ffi.Pointer bn, int value); /// BN_sub sets |r| = |a| - |b|, where |r| may be the same pointer as either |a| /// or |b|. It returns one on success and zero on allocation failure. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -166,12 +177,14 @@ external int BN_sub( ); /// BN_value_one returns a static BIGNUM with value 1. +@meta.RecordUse() @ffi.Native Function()>(symbol: 'webcrypto_BN_value_one') external ffi.Pointer BN_value_one(); /// BORINGSSL_self_test triggers most of the FIPS KAT-based self tests. It /// returns one on success and zero on error. It currently skips the SLH-DSA /// tests, which take a really long time to run. +@meta.RecordUse() @ffi.Native(symbol: 'webcrypto_BORINGSSL_self_test') external int BORINGSSL_self_test(); @@ -182,6 +195,7 @@ external int BORINGSSL_self_test(); /// This function can only be called on a "top level" |CBB|, i.e. one initialised /// with |CBB_init| or |CBB_init_fixed|, or a |CBB| set to the zero state with /// |CBB_zero|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_CBB_cleanup', ) @@ -192,6 +206,7 @@ external void CBB_cleanup(ffi.Pointer cbb); /// /// To avoid unfinalized length prefixes, it is a fatal error to call this on a /// CBB with any active children. +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_CBB_data', ) @@ -202,12 +217,14 @@ external ffi.Pointer CBB_data(ffi.Pointer cbb); /// used after the children go out of scope, e.g. when local |CBB| objects are /// added as children to a |CBB| that persists after a function returns. This /// function returns one on success or zero on error. +@meta.RecordUse() @ffi.Native)>(symbol: 'webcrypto_CBB_flush') external int CBB_flush(ffi.Pointer cbb); /// CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as /// needed, the |initial_capacity| is just a hint. It returns one on success or /// zero on allocation failure. +@meta.RecordUse() @ffi.Native, ffi.Size)>( symbol: 'webcrypto_CBB_init', ) @@ -218,6 +235,7 @@ external int CBB_init(ffi.Pointer cbb, int initial_capacity); /// /// To avoid unfinalized length prefixes, it is a fatal error to call this on a /// CBB with any active children. +@meta.RecordUse() @ffi.Native)>(symbol: 'webcrypto_CBB_len') external int CBB_len(ffi.Pointer cbb); @@ -225,6 +243,7 @@ external int CBB_len(ffi.Pointer cbb); /// initialised with |CBB_init| or |CBB_init_fixed| before use, but it is safe to /// call |CBB_cleanup| without a successful |CBB_init|. This may be used for more /// uniform cleanup of a |CBB|. +@meta.RecordUse() @ffi.Native)>(symbol: 'webcrypto_CBB_zero') external void CBB_zero(ffi.Pointer cbb); @@ -233,6 +252,7 @@ external void CBB_zero(ffi.Pointer cbb); /// of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a /// defined order as the return value when a != b is undefined, other than to be /// non-zero. +@meta.RecordUse() @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) >(symbol: 'webcrypto_CRYPTO_memcmp') @@ -248,6 +268,7 @@ external int CRYPTO_memcmp( /// return value. Otherwise, as many bytes of the shared key as will fit are /// copied directly to, at most, |outlen| bytes at |out|. It returns the number /// of bytes written to |out|, or -1 on error. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -285,6 +306,7 @@ external int ECDH_compute_key( ); /// ECDSA_SIG_free frees |sig| its member |BIGNUM|s. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_ECDSA_SIG_free', ) @@ -292,6 +314,7 @@ external void ECDSA_SIG_free(ffi.Pointer sig); /// ECDSA_SIG_get0 sets |*out_r| and |*out_s|, if non-NULL, to the two /// components of |sig|. +@meta.RecordUse() @ffi.Native< ffi.Void Function( ffi.Pointer, @@ -307,6 +330,7 @@ external void ECDSA_SIG_get0( /// ECDSA_SIG_marshal marshals |sig| as a DER-encoded ECDSA-Sig-Value and appends /// the result to |cbb|. It returns one on success and zero on error. +@meta.RecordUse() @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_ECDSA_SIG_marshal', ) @@ -316,6 +340,7 @@ external int ECDSA_SIG_marshal( ); /// ECDSA_SIG_new returns a fresh |ECDSA_SIG| structure or NULL on error. +@meta.RecordUse() @ffi.Native Function()>( symbol: 'webcrypto_ECDSA_SIG_new', ) @@ -323,6 +348,7 @@ external ffi.Pointer ECDSA_SIG_new(); /// ECDSA_SIG_parse parses a DER-encoded ECDSA-Sig-Value structure from |cbs| and /// advances |cbs|. It returns a newly-allocated |ECDSA_SIG| or NULL on error. +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_ECDSA_SIG_parse', ) @@ -334,6 +360,7 @@ external ffi.Pointer ECDSA_SIG_parse(ffi.Pointer cbs); /// This function exists for OpenSSL compatibility, and to manage dynamic /// |EC_GROUP|s constructed by |EC_GROUP_new_curve_GFp|. Callers that do not need /// either may ignore this function. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EC_GROUP_free', ) @@ -341,12 +368,14 @@ external void EC_GROUP_free(ffi.Pointer group); /// EC_GROUP_get0_order returns a pointer to the internal |BIGNUM| object in /// |group| that specifies the order of the group. +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EC_GROUP_get0_order', ) external ffi.Pointer EC_GROUP_get0_order(ffi.Pointer group); /// EC_GROUP_get_curve_name returns a NID that identifies |group|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EC_GROUP_get_curve_name', ) @@ -354,6 +383,7 @@ external int EC_GROUP_get_curve_name(ffi.Pointer group); /// EC_GROUP_get_degree returns the number of bits needed to represent an /// element of the field underlying |group|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EC_GROUP_get_degree', ) @@ -376,6 +406,7 @@ external int EC_GROUP_get_degree(ffi.Pointer group); /// /// If in doubt, use |NID_X9_62_prime256v1|, or see the curve25519.h header for /// more modern primitives. +@meta.RecordUse() @ffi.Native Function(ffi.Int)>( symbol: 'webcrypto_EC_GROUP_new_by_curve_name', ) @@ -385,12 +416,14 @@ external ffi.Pointer EC_GROUP_new_by_curve_name(int nid); /// expensive check that the public key is in the primary subgroup). It returns /// one if all checks pass and zero otherwise. If it returns zero then detail /// about the problem can be found on the error stack. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EC_KEY_check_key', ) external int EC_KEY_check_key(ffi.Pointer key); /// EC_KEY_free frees all the data owned by |key| and |key| itself. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EC_KEY_free', ) @@ -399,18 +432,21 @@ external void EC_KEY_free(ffi.Pointer key); /// EC_KEY_generate_key generates a random, private key, calculates the /// corresponding public key and stores both in |key|. It returns one on success /// or zero otherwise. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EC_KEY_generate_key', ) external int EC_KEY_generate_key(ffi.Pointer key); /// EC_KEY_get0_group returns a pointer to the |EC_GROUP| object inside |key|. +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EC_KEY_get0_group', ) external ffi.Pointer EC_KEY_get0_group(ffi.Pointer key); /// EC_KEY_get0_private_key returns a pointer to the private key inside |key|. +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EC_KEY_get0_private_key', ) @@ -418,6 +454,7 @@ external ffi.Pointer EC_KEY_get0_private_key(ffi.Pointer key); /// EC_KEY_get0_public_key returns a pointer to the public key point inside /// |key|. +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EC_KEY_get0_public_key', ) @@ -425,6 +462,7 @@ external ffi.Pointer EC_KEY_get0_public_key(ffi.Pointer key); /// EC_KEY_get_enc_flags returns the encoding flags for |key|, which is a /// bitwise-OR of |EC_PKEY_*| values. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EC_KEY_get_enc_flags', ) @@ -432,6 +470,7 @@ external int EC_KEY_get_enc_flags(ffi.Pointer key); /// EC_KEY_new_by_curve_name returns a fresh EC_KEY for group specified by |nid| /// or NULL on error. +@meta.RecordUse() @ffi.Native Function(ffi.Int)>( symbol: 'webcrypto_EC_KEY_new_by_curve_name', ) @@ -439,6 +478,7 @@ external ffi.Pointer EC_KEY_new_by_curve_name(int nid); /// EC_KEY_set_enc_flags sets the encoding flags for |key|, which is a /// bitwise-OR of |EC_PKEY_*| values. +@meta.RecordUse() @ffi.Native, ffi.UnsignedInt)>( symbol: 'webcrypto_EC_KEY_set_enc_flags', ) @@ -447,6 +487,7 @@ external void EC_KEY_set_enc_flags(ffi.Pointer key, int flags); /// EC_KEY_set_private_key sets the private key of |key| to |priv|. It returns /// one on success and zero otherwise. |key| must already have had a group /// configured (see |EC_KEY_set_group| and |EC_KEY_new_by_curve_name|). +@meta.RecordUse() @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EC_KEY_set_private_key', ) @@ -459,6 +500,7 @@ external int EC_KEY_set_private_key( /// It returns one on success and zero otherwise. |key| must already have had a /// group configured (see |EC_KEY_set_group| and |EC_KEY_new_by_curve_name|), and /// |pub| must also belong to that group, and must not be the point at infinity. +@meta.RecordUse() @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EC_KEY_set_public_key', ) @@ -470,6 +512,7 @@ external int EC_KEY_set_public_key( /// EC_KEY_set_public_key_affine_coordinates sets the public key in |key| to /// (|x|, |y|). It returns one on success and zero on error. It's considered an /// error if |x| and |y| do not represent a point on |key|'s curve. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -484,6 +527,7 @@ external int EC_KEY_set_public_key_affine_coordinates( ); /// EC_POINT_free frees |point| and the data that it points to. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EC_POINT_free', ) @@ -495,6 +539,7 @@ external void EC_POINT_free(ffi.Pointer point); /// /// Either |x| or |y| may be NULL to skip computing that coordinate. This is /// slightly faster in the common case where only the x-coordinate is needed. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -514,6 +559,7 @@ external int EC_POINT_get_affine_coordinates_GFp( /// EC_POINT_new returns a fresh |EC_POINT| object in the given group, or NULL /// on error. +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EC_POINT_new', ) @@ -523,6 +569,7 @@ external ffi.Pointer EC_POINT_new(ffi.Pointer group); /// serialisation in |buf|. It returns one on success and zero on error. |ctx| /// may be NULL. It's considered an error if |buf| does not represent a point on /// the curve. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -543,6 +590,7 @@ external int EC_POINT_oct2point( /// EC_POINT_point2cbb behaves like |EC_POINT_point2oct| but appends the /// serialised point to |cbb|. It returns one on success and zero on error. |ctx| /// is ignored and may be NULL. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -561,6 +609,7 @@ external int EC_POINT_point2cbb( ); /// ERR_clear_error clears the error queue for the current thread. +@meta.RecordUse() @ffi.Native(symbol: 'webcrypto_ERR_clear_error') external void ERR_clear_error(); @@ -575,6 +624,7 @@ external void ERR_clear_error(); /// /// error code is an 8 digit hexadecimal number; library name and reason string /// are ASCII text. +@meta.RecordUse() @ffi.Native< ffi.Pointer Function(ffi.Uint32, ffi.Pointer, ffi.Size) >(symbol: 'webcrypto_ERR_error_string_n') @@ -587,16 +637,19 @@ external ffi.Pointer ERR_error_string_n( /// ERR_get_error gets the packed error code for the least recent error and /// removes that error from the queue. If there are no errors in the queue then /// it returns zero. +@meta.RecordUse() @ffi.Native(symbol: 'webcrypto_ERR_get_error') external int ERR_get_error(); /// The "peek" functions act like the |ERR_get_error| functions, above, but they /// do not remove the error from the queue. +@meta.RecordUse() @ffi.Native(symbol: 'webcrypto_ERR_peek_error') external int ERR_peek_error(); /// EVP_AEAD_CTX_free calls |EVP_AEAD_CTX_cleanup| and |OPENSSL_free| on /// |ctx|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_AEAD_CTX_free', ) @@ -604,6 +657,7 @@ external void EVP_AEAD_CTX_free(ffi.Pointer ctx); /// EVP_AEAD_CTX_new allocates an |EVP_AEAD_CTX|, calls |EVP_AEAD_CTX_init| and /// returns the |EVP_AEAD_CTX|, or NULL on error. +@meta.RecordUse() @ffi.Native< ffi.Pointer Function( ffi.Pointer, @@ -638,6 +692,7 @@ external ffi.Pointer EVP_AEAD_CTX_new( /// filled with zero bytes and |*out_len| set to zero. /// /// If |in| and |out| alias then |out| must be == |in|. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -685,6 +740,7 @@ external int EVP_AEAD_CTX_open( /// filled with zero bytes and |*out_len| set to zero. /// /// If |in| and |out| alias then |out| must be == |in|. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -714,6 +770,7 @@ external int EVP_AEAD_CTX_seal( /// EVP_AEAD_key_length returns the length, in bytes, of the keys used by /// |aead|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_AEAD_key_length', ) @@ -721,6 +778,7 @@ external int EVP_AEAD_key_length(ffi.Pointer aead); /// EVP_AEAD_max_overhead returns the maximum number of additional bytes added /// by the act of sealing data with |aead|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_AEAD_max_overhead', ) @@ -729,6 +787,7 @@ external int EVP_AEAD_max_overhead(ffi.Pointer aead); /// EVP_AEAD_max_tag_len returns the maximum tag length when using |aead|. This /// is the largest value that can be passed as |tag_len| to /// |EVP_AEAD_CTX_init|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_AEAD_max_tag_len', ) @@ -736,6 +795,7 @@ external int EVP_AEAD_max_tag_len(ffi.Pointer aead); /// EVP_AEAD_nonce_length returns the length, in bytes, of the per-message nonce /// for |aead|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_AEAD_nonce_length', ) @@ -743,6 +803,7 @@ external int EVP_AEAD_nonce_length(ffi.Pointer aead); /// EVP_CIPHER_CTX_free calls |EVP_CIPHER_CTX_cleanup| on |ctx| and then frees /// |ctx| itself. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_CIPHER_CTX_free', ) @@ -750,6 +811,7 @@ external void EVP_CIPHER_CTX_free(ffi.Pointer ctx); /// EVP_CIPHER_CTX_new allocates a fresh |EVP_CIPHER_CTX|, calls /// |EVP_CIPHER_CTX_init| and returns it, or NULL on allocation failure. +@meta.RecordUse() @ffi.Native Function()>( symbol: 'webcrypto_EVP_CIPHER_CTX_new', ) @@ -757,6 +819,7 @@ external ffi.Pointer EVP_CIPHER_CTX_new(); /// EVP_CIPHER_block_size returns the block size, in bytes, for |cipher|, or one /// if |cipher| is a stream cipher. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_CIPHER_block_size', ) @@ -764,6 +827,7 @@ external int EVP_CIPHER_block_size(ffi.Pointer cipher); /// EVP_CIPHER_iv_length returns the IV size, in bytes, of |cipher|, or zero if /// |cipher| doesn't take an IV. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_CIPHER_iv_length', ) @@ -774,6 +838,7 @@ external int EVP_CIPHER_iv_length(ffi.Pointer cipher); /// /// WARNING: This function does not check bounds on out, and correctly sizing /// the output buffer is difficult. Use |EVP_CipherFinal_ex2| instead. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -794,6 +859,7 @@ external int EVP_CipherFinal_ex( /// as the key and |iv| as the IV (if any). These should have the correct /// lengths given by |EVP_CIPHER_key_length| and |EVP_CIPHER_iv_length|. It /// returns one on success and zero on error. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -822,6 +888,7 @@ external int EVP_CipherInit_ex( /// WARNING: This function does not check bounds on |out|, and correctly sizing /// the output buffer is difficult. Use |EVP_CipherUpdate_ex| or /// |EVP_CipherUpdateAAD| instead. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -841,6 +908,7 @@ external int EVP_CipherUpdate( /// EVP_DigestFinal acts like |EVP_DigestFinal_ex| except that /// |EVP_MD_CTX_cleanup| is called on |ctx| before returning. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -856,6 +924,7 @@ external int EVP_DigestFinal( /// EVP_DigestInit acts like |EVP_DigestInit_ex| except that |ctx| is /// initialised before use. +@meta.RecordUse() @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_DigestInit', ) @@ -876,6 +945,7 @@ external int EVP_DigestInit( /// single-shot operation. /// /// It returns one on success, or zero on error. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -903,6 +973,7 @@ external int EVP_DigestSignFinal( /// used concurrently with other non-mutating functions on |pkey|. /// /// It returns one on success, or zero on error. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -926,6 +997,7 @@ external int EVP_DigestSignInit( /// This function performs a streaming signing operation and will fail for /// signature algorithms which do not support this. Use |EVP_DigestSign| for a /// single-shot operation. +@meta.RecordUse() @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) >(symbol: 'webcrypto_EVP_DigestSignUpdate') @@ -937,6 +1009,7 @@ external int EVP_DigestSignUpdate( /// EVP_DigestUpdate hashes |len| bytes from |data| into the hashing operation /// in |ctx|. It returns one. +@meta.RecordUse() @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) >(symbol: 'webcrypto_EVP_DigestUpdate') @@ -953,6 +1026,7 @@ external int EVP_DigestUpdate( /// This function performs streaming signature verification and will fail for /// signature algorithms which do not support this. Use |EVP_DigestVerify| for a /// single-shot verification. +@meta.RecordUse() @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) >(symbol: 'webcrypto_EVP_DigestVerifyFinal') @@ -976,6 +1050,7 @@ external int EVP_DigestVerifyFinal( /// used concurrently with other non-mutating functions on |pkey|. /// /// It returns one on success, or zero on error. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -999,6 +1074,7 @@ external int EVP_DigestVerifyInit( /// This function performs streaming signature verification and will fail for /// signature algorithms which do not support this. Use |EVP_DigestVerify| for a /// single-shot verification. +@meta.RecordUse() @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) >(symbol: 'webcrypto_EVP_DigestVerifyUpdate') @@ -1009,6 +1085,7 @@ external int EVP_DigestVerifyUpdate( ); /// EVP_MD_CTX_free calls |EVP_MD_CTX_cleanup| and then frees |ctx| itself. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_MD_CTX_free', ) @@ -1017,6 +1094,7 @@ external void EVP_MD_CTX_free(ffi.Pointer ctx); /// EVP_MD_CTX_new allocates and initialises a fresh |EVP_MD_CTX| and returns /// it, or NULL on allocation failure. The caller must use |EVP_MD_CTX_free| to /// release the resulting object. +@meta.RecordUse() @ffi.Native Function()>( symbol: 'webcrypto_EVP_MD_CTX_new', ) @@ -1024,18 +1102,21 @@ external ffi.Pointer EVP_MD_CTX_new(); /// EVP_MD_CTX_size returns the digest size of |ctx|, in bytes. It /// will crash if a digest hasn't been set on |ctx|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_MD_CTX_size', ) external int EVP_MD_CTX_size(ffi.Pointer ctx); /// EVP_MD_size returns the digest size of |md|, in bytes. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_MD_size', ) external int EVP_MD_size(ffi.Pointer md); /// EVP_PKEY_CTX_free frees |ctx| and the data it owns. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_PKEY_CTX_free', ) @@ -1043,6 +1124,7 @@ external void EVP_PKEY_CTX_free(ffi.Pointer ctx); /// EVP_PKEY_CTX_new allocates a fresh |EVP_PKEY_CTX| for use with |pkey|. It /// returns the context or NULL on error. +@meta.RecordUse() @ffi.Native< ffi.Pointer Function(ffi.Pointer, ffi.Pointer) >(symbol: 'webcrypto_EVP_PKEY_CTX_new') @@ -1056,6 +1138,7 @@ external ffi.Pointer EVP_PKEY_CTX_new( /// and will call |OPENSSL_free| on it when |ctx| is destroyed. /// /// Returns one on success or zero on error. +@meta.RecordUse() @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) >(symbol: 'webcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label') @@ -1071,6 +1154,7 @@ external int EVP_PKEY_CTX_set0_rsa_oaep_label( /// If unset, the default is the signing hash for |RSA_PKCS1_PSS_PADDING| and the /// OAEP hash for |RSA_PKCS1_OAEP_PADDING|. Callers are recommended to use this /// default and not call this function. +@meta.RecordUse() @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md', ) @@ -1084,6 +1168,7 @@ external int EVP_PKEY_CTX_set_rsa_mgf1_md( /// Callers are recommended to overwrite this default. /// /// TODO(davidben): Remove the default and require callers specify this. +@meta.RecordUse() @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_CTX_set_rsa_oaep_md', ) @@ -1095,6 +1180,7 @@ external int EVP_PKEY_CTX_set_rsa_oaep_md( /// EVP_PKEY_CTX_set_rsa_padding sets the padding type to use. It should be one /// of the |RSA_*_PADDING| values. Returns one on success or zero on error. By /// default, the padding is |RSA_PKCS1_PADDING|. +@meta.RecordUse() @ffi.Native, ffi.Int)>( symbol: 'webcrypto_EVP_PKEY_CTX_set_rsa_padding', ) @@ -1114,6 +1200,7 @@ external int EVP_PKEY_CTX_set_rsa_padding( /// differs from OpenSSL, which defaults to |RSA_PSS_SALTLEN_AUTO|. /// /// Returns one on success or zero on error. +@meta.RecordUse() @ffi.Native, ffi.Int)>( symbol: 'webcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen', ) @@ -1132,6 +1219,7 @@ external int EVP_PKEY_CTX_set_rsa_pss_saltlen( /// plaintext. The actual plaintext may be smaller. /// /// It returns one on success or zero on error. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -1153,6 +1241,7 @@ external int EVP_PKEY_decrypt( /// operation. It should be called before |EVP_PKEY_decrypt|. /// /// It returns one on success or zero on error. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_PKEY_decrypt_init', ) @@ -1168,6 +1257,7 @@ external int EVP_PKEY_decrypt_init(ffi.Pointer ctx); /// ciphertext. The actual ciphertext may be smaller. /// /// It returns one on success or zero on error. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -1189,6 +1279,7 @@ external int EVP_PKEY_encrypt( /// operation. It should be called before |EVP_PKEY_encrypt|. /// /// It returns one on success or zero on error. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_PKEY_encrypt_init', ) @@ -1196,16 +1287,19 @@ external int EVP_PKEY_encrypt_init(ffi.Pointer ctx); /// EVP_PKEY_free decrements the reference count of |pkey| and frees it if the /// reference count drops to zero. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_PKEY_free', ) external void EVP_PKEY_free(ffi.Pointer pkey); +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_get1_EC_KEY', ) external ffi.Pointer EVP_PKEY_get1_EC_KEY(ffi.Pointer pkey); +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_get1_RSA', ) @@ -1217,6 +1311,7 @@ external ffi.Pointer EVP_PKEY_get1_RSA(ffi.Pointer pkey); /// PrivateKeyInfo (RFC 5208) AlgorithmIdentifier. Algorithm parameters can be /// inspected with algorithm-specific accessors, e.g. /// |EVP_PKEY_get_ec_curve_nid|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_EVP_PKEY_id', ) @@ -1224,9 +1319,11 @@ external int EVP_PKEY_id(ffi.Pointer pkey); /// EVP_PKEY_new creates a new, empty public-key object and returns it or NULL /// on allocation failure. +@meta.RecordUse() @ffi.Native Function()>(symbol: 'webcrypto_EVP_PKEY_new') external ffi.Pointer EVP_PKEY_new(); +@meta.RecordUse() @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_set1_EC_KEY', ) @@ -1261,6 +1358,7 @@ external int EVP_PKEY_set1_EC_KEY( /// not make |EVP_PKEY_RSA_PSS| available by default, only when callers opt in /// via |EVP_pkey_rsa_pss_sha256|. This differs from upstream OpenSSL, where /// callers are exposed to |EVP_PKEY_RSA_PSS| by default. +@meta.RecordUse() @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_PKEY_set1_RSA', ) @@ -1286,6 +1384,7 @@ external int EVP_PKEY_set1_RSA( /// |EVP_PKEY_set1_tls_encodedpoint| with X25519, which requires a half-empty /// |EVP_PKEY| that was first configured with |EVP_PKEY_X25519|. Currently, all /// other values of |type| will result in an error. +@meta.RecordUse() @ffi.Native, ffi.Int)>( symbol: 'webcrypto_EVP_PKEY_set_type', ) @@ -1298,6 +1397,7 @@ external int EVP_PKEY_set_type(ffi.Pointer pkey, int type); /// effectively randomized, which means one must consider collisions. Unless /// implementing an existing protocol which has already specified incorrect /// parameters, only use 12-byte nonces. +@meta.RecordUse() @ffi.Native Function()>( symbol: 'webcrypto_EVP_aead_aes_128_gcm', ) @@ -1310,26 +1410,31 @@ external ffi.Pointer EVP_aead_aes_128_gcm(); /// effectively randomized, which means one must consider collisions. Unless /// implementing an existing protocol which has already specified incorrect /// parameters, only use 12-byte nonces. +@meta.RecordUse() @ffi.Native Function()>( symbol: 'webcrypto_EVP_aead_aes_256_gcm', ) external ffi.Pointer EVP_aead_aes_256_gcm(); +@meta.RecordUse() @ffi.Native Function()>( symbol: 'webcrypto_EVP_aes_128_cbc', ) external ffi.Pointer EVP_aes_128_cbc(); +@meta.RecordUse() @ffi.Native Function()>( symbol: 'webcrypto_EVP_aes_128_ctr', ) external ffi.Pointer EVP_aes_128_ctr(); +@meta.RecordUse() @ffi.Native Function()>( symbol: 'webcrypto_EVP_aes_256_cbc', ) external ffi.Pointer EVP_aes_256_cbc(); +@meta.RecordUse() @ffi.Native Function()>( symbol: 'webcrypto_EVP_aes_256_ctr', ) @@ -1338,6 +1443,7 @@ external ffi.Pointer EVP_aes_256_ctr(); /// EVP_marshal_private_key marshals |key| as a DER-encoded PrivateKeyInfo /// structure (RFC 5208) and appends the result to |cbb|. It returns one on /// success and zero on error. +@meta.RecordUse() @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_marshal_private_key', ) @@ -1349,6 +1455,7 @@ external int EVP_marshal_private_key( /// EVP_marshal_public_key marshals |key| as a DER-encoded SubjectPublicKeyInfo /// structure (RFC 5280) and appends the result to |cbb|. It returns one on /// success and zero on error. +@meta.RecordUse() @ffi.Native, ffi.Pointer)>( symbol: 'webcrypto_EVP_marshal_public_key', ) @@ -1381,6 +1488,7 @@ external int EVP_marshal_public_key( /// /// A PrivateKeyInfo ends with an optional set of attributes. These are silently /// ignored. +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EVP_parse_private_key', ) @@ -1405,20 +1513,25 @@ external ffi.Pointer EVP_parse_private_key(ffi.Pointer cbs); /// This means callers must check the type of the parsed public key to ensure it /// is suitable and validate other desired key properties such as RSA modulus /// size or EC curve. +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_EVP_parse_public_key', ) external ffi.Pointer EVP_parse_public_key(ffi.Pointer cbs); +@meta.RecordUse() @ffi.Native Function()>(symbol: 'webcrypto_EVP_sha1') external ffi.Pointer EVP_sha1(); +@meta.RecordUse() @ffi.Native Function()>(symbol: 'webcrypto_EVP_sha256') external ffi.Pointer EVP_sha256(); +@meta.RecordUse() @ffi.Native Function()>(symbol: 'webcrypto_EVP_sha384') external ffi.Pointer EVP_sha384(); +@meta.RecordUse() @ffi.Native Function()>(symbol: 'webcrypto_EVP_sha512') external ffi.Pointer EVP_sha512(); @@ -1429,6 +1542,7 @@ external ffi.Pointer EVP_sha512(); /// HKDF is an Extract-and-Expand algorithm. It does not do any key stretching, /// and as such, is not suited to be used alone to generate a key from a /// password. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -1455,6 +1569,7 @@ external int HKDF( ); /// HMAC_CTX_free calls |HMAC_CTX_cleanup| and then frees |ctx| itself. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_HMAC_CTX_free', ) @@ -1463,6 +1578,7 @@ external void HMAC_CTX_free(ffi.Pointer ctx); /// HMAC_CTX_new allocates and initialises a new |HMAC_CTX| and returns it, or /// NULL on allocation failure. The caller must use |HMAC_CTX_free| to release /// the resulting object. +@meta.RecordUse() @ffi.Native Function()>(symbol: 'webcrypto_HMAC_CTX_new') external ffi.Pointer HMAC_CTX_new(); @@ -1471,6 +1587,7 @@ external ffi.Pointer HMAC_CTX_new(); /// |*out_len|. On entry, |out| must contain at least |HMAC_size| bytes of /// space. An output size of |EVP_MAX_MD_SIZE| will always be large enough. It /// returns one on success or zero on allocation failure. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -1493,6 +1610,7 @@ external int HMAC_Final( /// WARNING: NULL and empty keys are ambiguous on non-initial calls. Passing NULL /// |key| but repeating the previous |md| reuses the previous key rather than the /// empty key. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -1512,6 +1630,7 @@ external int HMAC_Init_ex( /// HMAC_Update hashes |data_len| bytes from |data| into the current HMAC /// operation in |ctx|. It returns one. +@meta.RecordUse() @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Size) >(symbol: 'webcrypto_HMAC_Update') @@ -1523,6 +1642,7 @@ external int HMAC_Update( /// HMAC_size returns the size, in bytes, of the HMAC that will be produced by /// |ctx|. On entry, |ctx| must have been setup with |HMAC_Init_ex|. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_HMAC_size', ) @@ -1531,6 +1651,7 @@ external int HMAC_size(ffi.Pointer ctx); /// OPENSSL_free does nothing if |ptr| is NULL. Otherwise it zeros out the /// memory allocated at |ptr| and frees it along with the private data. /// It must only be used on on |ptr| values obtained from |OPENSSL_malloc| +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_OPENSSL_free', ) @@ -1540,6 +1661,7 @@ external void OPENSSL_free(ffi.Pointer ptr); /// private data. The resulting pointer must be freed with |OPENSSL_free|. In /// the case of a malloc failure, prior to returning NULL |OPENSSL_malloc| will /// push |ERR_R_MALLOC_FAILURE| onto the openssl error stack. +@meta.RecordUse() @ffi.Native Function(ffi.Size)>( symbol: 'webcrypto_OPENSSL_malloc', ) @@ -1548,6 +1670,7 @@ external ffi.Pointer OPENSSL_malloc(int size); /// OPENSSL_memdup returns an allocated, duplicate of |size| bytes from |data| or /// NULL on allocation failure. The memory allocated must be freed with /// |OPENSSL_free|. +@meta.RecordUse() @ffi.Native Function(ffi.Pointer, ffi.Size)>( symbol: 'webcrypto_OPENSSL_memdup', ) @@ -1559,6 +1682,7 @@ external ffi.Pointer OPENSSL_memdup( /// PKCS5_PBKDF2_HMAC computes |iterations| iterations of PBKDF2 of |password| /// and |salt|, using |digest|, and outputs |key_len| bytes to |out_key|. It /// returns one on success and zero on allocation failure or if iterations is 0. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -1584,6 +1708,7 @@ external int PKCS5_PBKDF2_HMAC( /// RAND_bytes writes |len| bytes of random data to |buf| and returns one. In the /// event that sufficient random data can not be obtained, |abort| is called. +@meta.RecordUse() @ffi.Native, ffi.Size)>( symbol: 'webcrypto_RAND_bytes', ) @@ -1591,6 +1716,7 @@ external int RAND_bytes(ffi.Pointer buf, int len); /// RSAPublicKey_dup allocates a fresh |RSA| and copies the public key from /// |rsa| into it. It returns the fresh |RSA| object, or NULL on error. +@meta.RecordUse() @ffi.Native Function(ffi.Pointer)>( symbol: 'webcrypto_RSAPublicKey_dup', ) @@ -1599,6 +1725,7 @@ external ffi.Pointer RSAPublicKey_dup(ffi.Pointer rsa); /// RSA_check_key performs basic validity tests on |rsa|. It returns one if /// they pass and zero otherwise. Opaque keys and public keys always pass. If it /// returns zero then a more detailed error is available on the error queue. +@meta.RecordUse() @ffi.Native)>( symbol: 'webcrypto_RSA_check_key', ) @@ -1606,6 +1733,7 @@ external int RSA_check_key(ffi.Pointer rsa); /// RSA_free decrements the reference count of |rsa| and frees it if the /// reference count drops to zero. +@meta.RecordUse() @ffi.Native)>(symbol: 'webcrypto_RSA_free') external void RSA_free(ffi.Pointer rsa); @@ -1617,6 +1745,7 @@ external void RSA_free(ffi.Pointer rsa); /// with event=3 when a suitable value for |p| is found. /// /// It returns one on success or zero on error. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -1636,6 +1765,7 @@ external int RSA_generate_key_ex( /// non-NULL, to |rsa|'s CRT parameters. These are d (mod p-1), d (mod q-1) and /// q^-1 (mod p), respectively. If |rsa| is a public key, each parameter will be /// set to NULL. +@meta.RecordUse() @ffi.Native< ffi.Void Function( ffi.Pointer, @@ -1653,6 +1783,7 @@ external void RSA_get0_crt_params( /// RSA_get0_factors sets |*out_p| and |*out_q|, if non-NULL, to |rsa|'s prime /// factors. If |rsa| is a public key, they will be set to NULL. +@meta.RecordUse() @ffi.Native< ffi.Void Function( ffi.Pointer, @@ -1669,6 +1800,7 @@ external void RSA_get0_factors( /// RSA_get0_key sets |*out_n|, |*out_e|, and |*out_d|, if non-NULL, to |rsa|'s /// modulus, public exponent, and private exponent, respectively. If |rsa| is a /// public key, the private exponent will be set to NULL. +@meta.RecordUse() @ffi.Native< ffi.Void Function( ffi.Pointer, @@ -1686,6 +1818,7 @@ external void RSA_get0_key( /// RSA_new returns a new, empty |RSA| object or NULL on error. Prefer using /// |RSA_new_public_key| or |RSA_new_private_key| to import an RSA key. +@meta.RecordUse() @ffi.Native Function()>(symbol: 'webcrypto_RSA_new') external ffi.Pointer RSA_new(); @@ -1697,6 +1830,7 @@ external ffi.Pointer RSA_new(); /// /// It is an error to call this function after |rsa| has been used for a /// cryptographic operation. Construct a new |RSA| object instead. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, @@ -1720,6 +1854,7 @@ external int RSA_set0_crt_params( /// /// It is an error to call this function after |rsa| has been used for a /// cryptographic operation. Construct a new |RSA| object instead. +@meta.RecordUse() @ffi.Native< ffi.Int Function(ffi.Pointer, ffi.Pointer, ffi.Pointer) >(symbol: 'webcrypto_RSA_set0_factors') @@ -1738,6 +1873,7 @@ external int RSA_set0_factors( /// /// It is an error to call this function after |rsa| has been used for a /// cryptographic operation. Construct a new |RSA| object instead. +@meta.RecordUse() @ffi.Native< ffi.Int Function( ffi.Pointer, diff --git a/pubspec.yaml b/pubspec.yaml index de5cb6ebd..a7a057870 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -43,6 +43,7 @@ hooks: user_defines: webcrypto: buildMode: build + disable_treeshaking: false topics: - crypto diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d83b1dbbf..1aa4e6d7d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -120,7 +120,11 @@ if(MSVC) # Hack because Windows compilers will put .dll files in # $CMAKE_BINARY_DIR/Debug/ folder. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${CMAKE_BINARY_DIR}>) +else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections") endif() + if(WIN32) # Windows/MSVC option from CMakeLists.txt in BoringSSL # Use NASM on Windows. @@ -161,7 +165,8 @@ set_target_properties( webcrypto PROPERTIES - + + POSITION_INDEPENDENT_CODE ON C_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1 WINDOWS_EXPORT_ALL_SYMBOLS TRUE diff --git a/test/ffi/treeshake_target.dart b/test/ffi/treeshake_target.dart new file mode 100644 index 000000000..828ee49bd --- /dev/null +++ b/test/ffi/treeshake_target.dart @@ -0,0 +1,21 @@ +// Copyright 2026 Google LLC +// +// 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. + +import 'dart:typed_data'; +import 'package:webcrypto/webcrypto.dart'; + +Future main() async { + final hash = await Hash.sha256.digestBytes(Uint8List.fromList([1, 2, 3])); + print('SHA256 hash length: ${hash.length}'); +} diff --git a/test/ffi/treeshake_test.dart b/test/ffi/treeshake_test.dart new file mode 100644 index 000000000..c03514c0a --- /dev/null +++ b/test/ffi/treeshake_test.dart @@ -0,0 +1,155 @@ +// Copyright 2026 Google LLC +// +// 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. + +@TestOn('vm') +@Timeout(Duration(minutes: 10)) +library; + +import 'dart:io'; + +import 'package:test/test.dart'; + +void main() { + test('dart build verifies link hook treeshaking and disable_treeshaking user define', () async { + final tempDirTreeshaken = + Directory.systemTemp.createTempSync('webcrypto_treeshaken_'); + final tempDirDisabled = + Directory.systemTemp.createTempSync('webcrypto_disabled_'); + + try { + final baseEnv = Map.from(Platform.environment); + const llvmPath = '/usr/lib/llvm-19/bin'; + if (Directory(llvmPath).existsSync()) { + final currentPath = baseEnv['PATH'] ?? ''; + baseEnv['PATH'] = '$llvmPath:$currentPath'; + } + + // 1. Build WITH treeshaking (default) + final resultTreeshaken = await Process.run( + Platform.resolvedExecutable, + [ + 'build', + 'cli', + '-t', + 'test/ffi/treeshake_target.dart', + '-o', + tempDirTreeshaken.path, + ], + environment: baseEnv, + workingDirectory: Directory.current.path, + ); + + expect( + resultTreeshaken.exitCode, + 0, + reason: + 'dart build cli (treeshaken) failed.\nstdout:\n${resultTreeshaken.stdout}\nstderr:\n${resultTreeshaken.stderr}', + ); + + // Verify link hook treeshaking output log + expect( + resultTreeshaken.stdout.toString(), + contains('webcrypto treeshaking enabled'), + reason: 'Link hook did not output treeshaking log.', + ); + + final dylibTreeshaken = _findDynamicLibrary([ + tempDirTreeshaken, + Directory('.dart_tool/lib'), + ]); + expect( + dylibTreeshaken, + isNotNull, + reason: 'No dynamic library found after treeshaken build.', + ); + + final sizeTreeshaken = dylibTreeshaken!.lengthSync(); + final sizeTreeshakenMB = sizeTreeshaken / (1024 * 1024); + + stdout.writeln( + 'Treeshaken library size: ${sizeTreeshakenMB.toStringAsFixed(2)} MB (${sizeTreeshaken} bytes)', + ); + + // Verify treeshaken size is below 5 MB limit + expect( + sizeTreeshakenMB, + lessThan(5.0), + reason: 'Treeshaken binary size exceeded 5.0 MB limit.', + ); + + // 2. Build WITHOUT treeshaking (disable_treeshaking = true) + // Invalidate shared link cache to re-execute link hook + final sharedLinkDir = + Directory('.dart_tool/hooks_runner/shared/webcrypto/link'); + if (sharedLinkDir.existsSync()) { + sharedLinkDir.deleteSync(recursive: true); + } + + final envDisabled = Map.from(baseEnv) + ..['WEBCRYPTO_DISABLE_TREESHAKING'] = 'true'; + + final resultDisabled = await Process.run( + Platform.resolvedExecutable, + [ + 'build', + 'cli', + '-t', + 'test/ffi/treeshake_target.dart', + '-o', + tempDirDisabled.path, + ], + environment: envDisabled, + workingDirectory: Directory.current.path, + ); + + expect( + resultDisabled.exitCode, + 0, + reason: + 'dart build cli (disabled treeshaking) failed.\nstdout:\n${resultDisabled.stdout}\nstderr:\n${resultDisabled.stderr}', + ); + + // Verify link hook logged that treeshaking was disabled via user define + expect( + resultDisabled.stdout.toString(), + contains('webcrypto: Treeshaking is disabled via user define'), + reason: 'Link hook did not recognize disable_treeshaking flag.', + ); + } finally { + if (tempDirTreeshaken.existsSync()) { + tempDirTreeshaken.deleteSync(recursive: true); + } + if (tempDirDisabled.existsSync()) { + tempDirDisabled.deleteSync(recursive: true); + } + } + }); +} + +File? _findDynamicLibrary(List searchDirs) { + for (final dir in searchDirs) { + if (dir.existsSync()) { + final files = dir + .listSync(recursive: true) + .whereType() + .where( + (f) => RegExp(r'(lib)?webcrypto\.(dll|dylib|so)$').hasMatch(f.path), + ); + if (files.isNotEmpty) { + return files.first; + } + } + } + return null; +} diff --git a/tool/ffigen.dart b/tool/ffigen.dart index 4ed1fae45..da0b86576 100644 --- a/tool/ffigen.dart +++ b/tool/ffigen.dart @@ -19,16 +19,42 @@ import 'package:ffigen/ffigen.dart'; void main() { final packageRoot = Platform.script.resolve('../'); - generateWebCryptoBindings(packageRoot); - generateBoringSslBindings(packageRoot); + final webCryptoFile = packageRoot.resolve( + 'lib/src/boringssl/bindings/generated_bindings.dart', + ); + final boringSslFile = packageRoot.resolve( + 'lib/src/third_party/boringssl/generated_bindings.dart', + ); + + generateWebCryptoBindings(packageRoot, webCryptoFile); + generateBoringSslBindings(packageRoot, boringSslFile); + + _addRecordUseAnnotations(webCryptoFile); + _addRecordUseAnnotations(boringSslFile); } -void generateWebCryptoBindings(Uri packageRoot) { +void _addRecordUseAnnotations(Uri fileUri) { + final file = File.fromUri(fileUri); + if (!file.existsSync()) return; + var content = file.readAsStringSync(); + + if (!content.contains("import 'package:meta/meta.dart' as meta;")) { + content = content.replaceFirst( + "import 'dart:ffi' as ffi;\n", + "import 'dart:ffi' as ffi;\nimport 'package:meta/meta.dart' as meta;\n", + ); + } + + content = content.replaceAll('@meta.RecordUse()\n', ''); + content = content.replaceAll('@ffi.Native', '@meta.RecordUse()\n@ffi.Native'); + + file.writeAsStringSync(content); +} + +void generateWebCryptoBindings(Uri packageRoot, Uri outputFile) { FfiGenerator( output: Output( - dartFile: packageRoot.resolve( - 'lib/src/boringssl/bindings/generated_bindings.dart', - ), + dartFile: outputFile, style: const NativeExternalBindings( assetId: 'package:webcrypto/webcrypto.dart', ), @@ -62,12 +88,10 @@ void generateWebCryptoBindings(Uri packageRoot) { ).generate(); } -void generateBoringSslBindings(Uri packageRoot) { +void generateBoringSslBindings(Uri packageRoot, Uri outputFile) { FfiGenerator( output: Output( - dartFile: packageRoot.resolve( - 'lib/src/third_party/boringssl/generated_bindings.dart', - ), + dartFile: outputFile, style: const NativeExternalBindings( assetId: 'package:webcrypto/webcrypto.dart', ),