### Installation: Bundle Directory and Cleanup Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Sets up the installation prefix to create a relocatable bundle and ensures the build bundle directory is clean before installation. This prepares the environment for installing the application. ```cmake # === Installation === # By default, "installing" just makes a relocatable bundle in the build # directory. set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() # Start with a clean build bundle directory every time. install(CODE " file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") " COMPONENT Runtime) ``` -------------------------------- ### Install Application Executable Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Installs the main application executable to the root of the installation bundle. This makes the application runnable after installation. ```cmake install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) ``` -------------------------------- ### WebCrypto Installation Rules Source: https://github.com/google/webcrypto.dart/blob/master/src/CMakeLists.txt Installs the 'webcrypto' library, runtime components, and archives to the root destination directory. This defines how the built library is deployed. ```cmake install( TARGETS webcrypto RUNTIME DESTINATION . LIBRARY DESTINATION . ARCHIVE DESTINATION . ) ``` -------------------------------- ### Installation: Bundle Data and Library Directories Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Defines the destination directories for data and libraries within the installation bundle. This structures the application bundle for correct operation. ```cmake set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") ``` -------------------------------- ### Install Bundled Plugin Libraries Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Iterates through a list of bundled libraries (likely from plugins) and installs them into the bundle's library directory. This ensures all necessary plugin code is included. ```cmake foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) install(FILES "${bundled_library}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endforeach(bundled_library) ``` -------------------------------- ### Install ICU Data and Flutter Library Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Installs the ICU data file and the main Flutter library into the bundle's data and library directories, respectively. These are essential runtime components. ```cmake install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) ``` -------------------------------- ### GN Source List Example Source: https://github.com/google/webcrypto.dart/blob/master/third_party/boringssl/INCORPORATING.md Example of how GN source lists for BoringSSL are located. These lists help in integrating BoringSSL's source files into your build. ```gn gen/sources.gni ``` -------------------------------- ### Install Flutter Assets Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Ensures the Flutter assets directory is clean and then copies the application's assets into the bundle's data directory. This makes application resources available at runtime. ```cmake # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Install AOT Library (Non-Debug Builds) Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Conditionally installs the Ahead-Of-Time (AOT) compiled library into the bundle's library directory for non-Debug builds. This optimizes performance for release and profile builds. ```cmake # Install the AOT library on non-Debug builds only. if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### Install Native Assets Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Copies native assets provided by the build.dart script into the bundle's library directory. These assets are often required by plugins. ```cmake # Copy the native assets provided by the build.dart from all packages. set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") install(DIRECTORY "${NATIVE_ASSETS_DIR}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Import Key to be Wrapped (HMAC) Source: https://github.com/google/webcrypto.dart/blob/master/doc/wrap-key.md Imports an HMAC key that will be wrapped. This example uses SHA-256 as the hash function. ```dart final hmacKey = await HmacSecretKey.importRawKey( Uint8List.fromList(List.generate(32, (i) => 0x80 + i)), Hash.sha256, ); ``` -------------------------------- ### Define Flutter Library and Headers Source: https://github.com/google/webcrypto.dart/blob/master/example/windows/flutter/CMakeLists.txt Defines the Flutter library path and a list of header files. These are published to the parent scope for use in the installation step. ```cmake set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") # Published to parent scope for install step. set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) list(APPEND FLUTTER_LIBRARY_HEADERS "flutter_export.h" "flutter_windows.h" "flutter_messenger.h" "flutter_plugin_registrar.h" "flutter_texture_registrar.h" ) list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") ``` -------------------------------- ### Unwrap Key with Import Options Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Unwraps a key using specific import options, ensuring type safety and preventing incorrect usage of import methods. This example shows unwrapping for HMAC keys using JSON Web or Raw formats. ```dart final hmacKey = await secretKey.unwrapKey( // This must be a ImportKeyOptions, and then unwrapKey returns Future // This allows us to ensure: // - Typing when specifying HMAC import parameters // - Prevents the user from trying using SPKI with options belonging to // a private RsaPssPrivateKey which doesn't support importSpkiKey(...) // // Note: I do not like the naming HmacSecretKey.importJsonWebKeyOptions(Hash.sha256), wrappedKeyAsBytes, iv, ); final hmacKey = await secretKey.unwrapKey( HmacSecretKey.importRawKeyOptions(Hash.sha256), wrappedKeyAsBytes, iv, ); ``` -------------------------------- ### JavaScript: Wrap Raw HMAC Key with AES-GCM Source: https://github.com/google/webcrypto.dart/blob/master/doc/wrap-key.md Example of wrapping a raw HMAC key using the browser's Web Crypto API with AES-GCM. This demonstrates the input parameters and expected output format for key wrapping in JavaScript. ```javascript (async () => { const wrappingKeyBytes = Uint8Array.from( {length: 16}, (_, i) => i + 1, ); const hmacKeyBytes = Uint8Array.from( {length: 32}, (_, i) => 0x80 + i, ); const iv = Uint8Array.from({length: 12}, (_, i) => 0x20 + i); const additionalData = Uint8Array.from({length: 8}, (_, i) => 0x40 + i); const wrappingKey = await crypto.subtle.importKey( "raw", wrappingKeyBytes, {name: "AES-GCM", length: 128}, true, ["encrypt", "decrypt", "wrapKey", "unwrapKey"], ); const hmacKey = await crypto.subtle.importKey( "raw", hmacKeyBytes, {name: "HMAC", hash: "SHA-256"}, true, ["sign", "verify"], ); const jsWrapped = new Uint8Array(await crypto.subtle.wrapKey( "raw", hmacKey, wrappingKey, {name: "AES-GCM", iv, additionalData, tagLength: 128}, )); const jsWrappedHex = [...jsWrapped] .map((b) => b.toString(16).padStart(2, "0")) .join(""); console.log("JS_WRAPPED_HEX =", jsWrappedHex); })(); ``` -------------------------------- ### Derive Key with Derive Options Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Derives a key using specific derive options, limiting the types of keys that can be generated. This example shows deriving an HMAC key using SHA-256. ```dart final hmacKey = await hkdfKey.deriveKey( // This must be a DeriveKeyOptions, and then deriveKey returns Future // This allows us to limit what keys can be derived, webcrypto can only derive // HMAC, AES-CBC, AES-CTR, AES-GCM and AES-KW. HmacSecretKey.deriveKeyOptions(Hash.sha256), salt, info, ); ``` -------------------------------- ### Derive AES Key using PBKDF2 in Dart (webcrypto.dart) Source: https://github.com/google/webcrypto.dart/blob/master/doc/derive-key.md Derives a 256-bit AES-GCM key from a password using PBKDF2 with the same salt and iterations as the JavaScript example. This code verifies the compatibility of webcrypto.dart's PBKDF2 implementation by comparing the derived key's hex representation. ```dart import 'dart:convert'; import 'package:webcrypto/webcrypto.dart'; Future main() async { final password = utf8.encode('correct horse battery staple'); final salt = utf8.encode('demo-salt'); const iterations = 100000; const referenceHex = '44ca28d53395e39b8ecc67e6449f002a5239b4f86023ee54d76a1da28510f388'; // Import password final pbk = await Pbkdf2SecretKey.importRawKey(password); // **deriveBits** (256 bits) then import as AES-GCM key final bits = await pbk.deriveBits(256, Hash.sha256, salt, iterations); final aesKey = await AesGcmSecretKey.importRawKey(bits); // Export raw bytes and print hex final raw = await aesKey.exportRawKey(); final hex = raw.map((b) => b.toRadixString(16).padLeft(2, '0')).join(); print('DART_HEX = $hex'); print('REFERENCE_HEX = $referenceHex'); print('DART_HEX == REFERENCE_HEX: ${hex == referenceHex}'); } ``` -------------------------------- ### Dart: Wrap Raw HMAC Key with AES-GCM Source: https://github.com/google/webcrypto.dart/blob/master/doc/wrap-key.md Dart equivalent of the JavaScript example, performing raw key wrapping using `exportRawKey()` and `encryptBytes()`. This code verifies that the resulting ciphertext matches the JavaScript output. ```dart import 'dart:convert' show base64Encode; import 'dart:typed_data'; import 'package:webcrypto/webcrypto.dart'; Future main() async { final wrappingKey = await AesGcmSecretKey.importRawKey( Uint8List.fromList(List.generate(16, (i) => i + 1)), ); final hmacKey = await HmacSecretKey.importRawKey( Uint8List.fromList(List.generate(32, (i) => 0x80 + i)), Hash.sha256, ); final iv = Uint8List.fromList(List.generate(12, (i) => 0x20 + i)); final additionalData = Uint8List.fromList(List.generate(8, (i) => 0x40 + i)); const jsWrappedHex = ''; final wrappedKey = await wrappingKey.encryptBytes( await hmacKey.exportRawKey(), iv, additionalData: additionalData, ); final dartWrappedHex = wrappedKey .map((b) => b.toRadixString(16).padLeft(2, '0')) .join(); final unwrappedRaw = await wrappingKey.decryptBytes( wrappedKey, iv, additionalData: additionalData, ); print('DART_WRAPPED_HEX = $dartWrappedHex'); print('JS_WRAPPED_HEX = $jsWrappedHex'); print('DART_WRAPPED_HEX == JS_WRAPPED_HEX: ${dartWrappedHex == jsWrappedHex}'); print('UNWRAPPED_RAW_OK = ${base64Encode(unwrappedRaw) == base64Encode(await hmacKey.exportRawKey())}'); } ``` -------------------------------- ### Import Initial Key Material for HKDF Source: https://github.com/google/webcrypto.dart/blob/master/doc/derive-key.md Import raw byte array key material into an HkdfSecretKey. This is the first step in using HKDF for key derivation. ```dart final masterKeyData = utf8.encode('master-key'); // initial key material (as bytes) final hkdfKey = await HkdfSecretKey.importRawKey(masterKeyData); ``` -------------------------------- ### Windows Specific Build Settings Source: https://github.com/google/webcrypto.dart/blob/master/src/CMakeLists.txt Enables NASM for assembly, sets the C compiler to 'cl', and defines preprocessor macros for Windows builds. Use this for Windows environments. ```cmake if(WIN32) # Windows/MSVC option from CMakeLists.txt in BoringSSL # Use NASM on Windows. enable_language(ASM_NASM) set(OPENSSL_NASM TRUE) set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -gcv8") # On Windows, prefer cl over gcc if both are available. By default most of # the CMake generators prefer gcc, even on Windows. set(CMAKE_GENERATOR_CC cl) add_definitions(-D_HAS_EXCEPTIONS=0) add_definitions(-DWIN32_LEAN_AND_MEAN) add_definitions(-DNOMINMAX) # Allow use of fopen. add_definitions(-D_CRT_SECURE_NO_WARNINGS) # Ensure proper Windows entropy sources add_definitions(-DBORINGSSL_UNSAFE_DETERMINISTIC_MODE=0) endif() ``` -------------------------------- ### Import Raw Key with Options Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Imports a raw key by first configuring options (e.g., hash algorithm) and then specifying the raw key import method. This allows for a chained configuration before the import operation. ```dart final hmacKey = await HmacSecretKey.options(Hash.sha256).raw.import(...); ``` -------------------------------- ### Import JSON Web Key with Options Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Imports a key in JSON Web Key format after configuring the necessary options (e.g., hash algorithm) through a fluent interface. This provides a structured way to set up import parameters. ```dart final hmacKey = await HmacSecretKey.options(Hash.sha256).jwk.import(...); ``` -------------------------------- ### System Dependencies and Application Build Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Finds system-level dependencies using PkgConfig and includes the runner's CMakeLists.txt for the application build. This links external libraries and defines the main application target. ```cmake # System-level dependencies. find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) # Application build; see runner/CMakeLists.txt. add_subdirectory("runner") ``` -------------------------------- ### Apply Standard Build Settings Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/runner/CMakeLists.txt Applies a standard set of build settings to the specified target. This can be removed if custom build settings are required. ```cmake # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) ``` -------------------------------- ### Apply Standard Build Settings Source: https://github.com/google/webcrypto.dart/blob/master/example/windows/runner/CMakeLists.txt Applies a predefined set of build settings to the specified target. This is a convenience function that can be removed if custom build settings are required. ```cmake apply_standard_settings(${BINARY_NAME}) ``` -------------------------------- ### Wrap Key in JSON Web and Raw Formats Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Demonstrates wrapping a key in both JSON Web Key format and raw byte format using a secret key and an initialization vector (IV). ```dart final hmacKey = await HmacSecretKey.generate(Hash.sha256); // It's weird that wrapKey has the format in the method name. // but unwrapKey doesn't have format in the name. final = wrappedKeyAsBytes await secretKey.wrapJsonWebKey( hmacKey, // this is a JsonWebExportableKey iv, ); final = wrappedKeyAsBytes await secretKey.wrapRawKey( hmacKey, // this is a JsonWebExportableKey iv, ); ``` -------------------------------- ### Generate Key with Options Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Generates a key using a fluent API that first specifies options (e.g., hash algorithm) and then performs the generation. This approach aims for a more readable, step-by-step configuration. ```dart final hmacKey = await HmacSecretKey.options(Hash.sha256).generate(); ``` -------------------------------- ### Define C++ Wrapper Sources Source: https://github.com/google/webcrypto.dart/blob/master/example/windows/flutter/CMakeLists.txt Lists the source files for the C++ client wrapper, categorized for core, plugin, and application use. These paths are prefixed with the wrapper root directory. ```cmake list(APPEND CPP_WRAPPER_SOURCES_CORE "core_implementations.cc" "standard_codec.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") list(APPEND CPP_WRAPPER_SOURCES_PLUGIN "plugin_registrar.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") list(APPEND CPP_WRAPPER_SOURCES_APP "flutter_engine.cc" "flutter_view_controller.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") ``` -------------------------------- ### Import Wrapped Raw Key Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Imports a key from a wrapped raw format using specified unwrap key options. It requires the wrapped key data and the hash algorithm. ```dart final hmacKey = await HmacSecretKey.importWrappedRawKey( secretKey.unwrapKeyOptions(iv), wrappedKeyAsBytes, Hash.sha256, ); ``` -------------------------------- ### Project and Executable Configuration Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Sets the minimum CMake version, project name, executable name, and application identifier. This is essential for defining the basic structure of the build. ```cmake cmake_minimum_required(VERSION 3.13) project(runner LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. set(BINARY_NAME "webcrypto_example") # The unique GTK application identifier for this application. See: # https://wiki.gnome.org/HowDoI/ChooseApplicationID set(APPLICATION_ID "com.example.webcrypto_example") ``` -------------------------------- ### Executable Output Directory Configuration Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Configures the runtime output directory for the main executable to a subdirectory. This prevents accidental execution of unbundled copies. ```cmake # Only the install-generated bundle's copy of the executable will launch # correctly, since the resources must in the right relative locations. To avoid # people trying to run the unbundled copy, put it in a subdirectory instead of # the default top-level location. set_target_properties(${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) ``` -------------------------------- ### WebCrypto Include Directories Source: https://github.com/google/webcrypto.dart/blob/master/src/CMakeLists.txt Sets the private include directories for the 'webcrypto' library, pointing to the BoringSSL headers. This is necessary for compiling the library's C sources. ```cmake target_include_directories( webcrypto PRIVATE ../third_party/boringssl/src/include/ ) ``` -------------------------------- ### Add Preprocessor Definitions for Build Version Source: https://github.com/google/webcrypto.dart/blob/master/example/windows/runner/CMakeLists.txt Sets preprocessor definitions for the build version, allowing the application to access version information at compile time. Definitions are provided for the full version string and its components. ```cmake target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") ``` -------------------------------- ### Link Dependency Libraries and Include Directories Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/runner/CMakeLists.txt Links the application target against the 'flutter' and 'PkgConfig::GTK' libraries, and adds the source directory to the include paths. ```cmake # Add dependency libraries. Add any application-specific dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### Import Wrapped JSON Web Key Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Imports a key from a wrapped JSON Web Key format using specified unwrap key options. It requires the wrapped key data and the hash algorithm. ```dart final hmacKey = await HmacSecretKey.importWrappedJsonWebKey( // UnwrapKeyOptions secretKey.unwrapKeyOptions(iv), wrappedKeyAsBytes, Hash.sha256, ); ``` -------------------------------- ### Cross-Building System Root Configuration Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Configures the sysroot and find root path for cross-compilation. This is used when building for a different platform than the host. ```cmake # Root filesystem for cross-building. if(FLUTTER_TARGET_PLATFORM_SYSROOT) set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) endif() ``` -------------------------------- ### Unwrap Key with JSON Web Key Import Options Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Unwraps a key using JSON Web Key import options, specifying the hash algorithm. This method is used when the wrapped key is in JWK format. ```dart final hmacKey = await secretKey.unwrapKey( // KeyImportOptions HmacSecretKey.options(Hash.sha256).jwk, wrappedKeyAsBytes, iv, ); ``` -------------------------------- ### Link Libraries and Include Directories Source: https://github.com/google/webcrypto.dart/blob/master/example/windows/runner/CMakeLists.txt Specifies the libraries and include directories required for the build. This includes Flutter-specific libraries, wrapper libraries, and system libraries like dwmapi.lib. Application-specific dependencies should also be added here. ```cmake target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### Configure Flutter Interface Library Source: https://github.com/google/webcrypto.dart/blob/master/example/windows/flutter/CMakeLists.txt Creates an INTERFACE library for Flutter, specifying include directories and linking against the Flutter library. It also adds a dependency on flutter_assemble. ```cmake add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") add_dependencies(flutter flutter_assemble) ``` -------------------------------- ### Configure Flutter Library and Headers Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/flutter/CMakeLists.txt Configures the Flutter library and its associated header files for the Linux GTK platform. It sets up include directories and links against system libraries. ```cmake set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") # Published to parent scope for install step. set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) list(APPEND FLUTTER_LIBRARY_HEADERS "fl_basic_message_channel.h" "fl_binary_codec.h" "fl_binary_messenger.h" "fl_dart_project.h" "fl_engine.h" "fl_json_message_codec.h" "fl_json_method_codec.h" "fl_message_codec.h" "fl_method_call.h" "fl_method_channel.h" "fl_method_codec.h" "fl_method_response.h" "fl_plugin_registrar.h" "fl_plugin_registry.h" "fl_standard_message_codec.h" "fl_standard_method_codec.h" "fl_string_codec.h" "fl_value.h" "fl_view.h" "flutter_linux.h" ) list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") target_link_libraries(flutter INTERFACE PkgConfig::GTK PkgConfig::GLIB PkgConfig::GIO ) add_dependencies(flutter flutter_assemble) ``` -------------------------------- ### Create Static Library for Flutter Plugins Source: https://github.com/google/webcrypto.dart/blob/master/example/windows/flutter/CMakeLists.txt Builds a static library named 'flutter_wrapper_plugin' using core and plugin-specific C++ wrapper sources. It applies standard settings, ensures position-independent code, sets hidden visibility, links against the Flutter library, and includes necessary directories. ```cmake add_library(flutter_wrapper_plugin STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ) apply_standard_settings(flutter_wrapper_plugin) set_target_properties(flutter_wrapper_plugin PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(flutter_wrapper_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden) target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) target_include_directories(flutter_wrapper_plugin PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_plugin flutter_assemble) ``` -------------------------------- ### Dart: Wrap Public Key as SPKI with AES-GCM Source: https://github.com/google/webcrypto.dart/blob/master/doc/wrap-key.md Demonstrates wrapping an RSA-OAEP public key in SPKI format using AES-GCM encryption. This snippet shows the process of exporting the public key and then encrypting its byte representation. ```dart final wrappingKey = await AesGcmSecretKey.generateKey(128); final rsaKeyPair = await RsaOaepPrivateKey.generateKey(2048, BigInt.from(65537), Hash.sha256); final iv = Uint8List(12); fillRandomBytes(iv); final wrappedPublicKey = await wrappingKey.encryptBytes( await rsaKeyPair.publicKey.exportSpkiKey(), iv, ); final unwrappedSpki = await wrappingKey.decryptBytes(wrappedPublicKey, iv); final publicKey = await RsaOaepPublicKey.importSpkiKey( unwrappedSpki, Hash.sha256, ); ``` -------------------------------- ### Create Static Library for Flutter Runner Source: https://github.com/google/webcrypto.dart/blob/master/example/windows/flutter/CMakeLists.txt Builds a static library named 'flutter_wrapper_app' using core and application-specific C++ wrapper sources. It links against the Flutter library and includes the necessary wrapper header directory. ```cmake add_library(flutter_wrapper_app STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_APP} ) apply_standard_settings(flutter_wrapper_app) target_link_libraries(flutter_wrapper_app PUBLIC flutter) target_include_directories(flutter_wrapper_app PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_app flutter_assemble) ``` -------------------------------- ### Import AES-GCM Wrapping Key Source: https://github.com/google/webcrypto.dart/blob/master/doc/wrap-key.md Imports a 128-bit AES key to be used for encrypting other keys. Ensure the key material is correctly formatted. ```dart final wrappingKey = await AesGcmSecretKey.importRawKey( Uint8List.fromList(List.generate(16, (i) => i + 1)), ); ``` -------------------------------- ### Calculate SHA-256 Hash of a String Source: https://github.com/google/webcrypto.dart/blob/master/README.md Demonstrates how to compute the SHA-256 hash of a given string using the webcrypto package. Ensure UTF-8 encoding is applied before hashing. ```dart import 'dart:convert' show base64, utf8; import 'package:webcrypto/webcrypto.dart'; Future main() async { final digest = await Hash.sha256.digestBytes(utf8.encode('Hello World')); print(base.encode(digest)); } ``` -------------------------------- ### Python Script for Build File Generation Source: https://github.com/google/webcrypto.dart/blob/master/third_party/boringssl/INCORPORATING.md Historically, this Python script was used to generate build files for BoringSSL. While transitioning to pre-generated files, it might still be relevant for custom build needs. ```python util/generate_build_files.py ``` -------------------------------- ### Import Raw Key Data Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Imports key data directly into a raw key format. This method is part of a key import options interface and requires the key data as a list of integers. ```dart Future import(List keyData); ``` -------------------------------- ### WebCrypto Shared Library Definition Source: https://github.com/google/webcrypto.dart/blob/master/src/CMakeLists.txt Defines the 'webcrypto' shared library, including its source files and dependencies. This is the main library build target. ```cmake add_library( webcrypto # Build a shared library SHARED # Source files ../src/webcrypto.c ../src/symbols.generated.c ${crypto_sources} ${crypto_sources_${PLATFORM}_${ARCH}} ) ``` -------------------------------- ### Unwrap and Import HMAC Key with Options Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Unwraps a key from bytes and imports it as an HMAC secret key, specifying SHA-256 hashing and providing an IV. This method is used when the key was previously wrapped. ```dart final hmacKey = await secretKey.unwrap( wrappedKeyAsBytes, HmacSecretKey.options(Hash.sha256), iv, ) ``` -------------------------------- ### Flutter Library and Tool Integration Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Includes the Flutter managed directory, which contains Flutter-specific build rules. This is crucial for integrating Flutter's build system. ```cmake # Flutter library and tool build rules. set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) ``` -------------------------------- ### Unwrap and Import HMAC Key Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Unwraps a key from bytes and imports it as an HMAC secret key with SHA-256 hashing. Requires the unwrapped key bytes. ```dart final unwrappedKey = secretKey.unwrap( wrappedKeyInBytes, ); final hmacKey = HmacSecretKey.importUnwrappedKey(unwrappedKey, Hash.sha256); ``` -------------------------------- ### Import Opaque Keys from Wrapped or Derived Sources Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Imports keys as opaque types, suitable for scenarios where the exact key type is not immediately known or needs to be treated generically. Supports keys from wrapped bytes or derived keys, using SHA-256. ```dart final hmacKey = await HmacSecretKey.generate(Hash.sha256); final wrappedKeyAsBytes = secretKey.wrapKey(hmacKey, iv); final hmacKey = await HmacSecretKey.importOpaqueKey( secretKey.unwrapKey(wrappedKeyAsBytes, iv), // returns OpaqueKey Hash.sha256, ); final hmacKey = await HmacSecretKey.importOpaqueKey( hkdfKey.deriveKey(salt, info), // returns OpaqueKey Hash.sha256, ); ``` -------------------------------- ### Set Minimum CMake Version and Project Name Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/runner/CMakeLists.txt Specifies the minimum required CMake version and defines the project name for the build. ```cmake cmake_minimum_required(VERSION 3.13) project(runner LANGUAGES CXX) ``` -------------------------------- ### Wrap Key as JSON Web Key Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Wraps a key into the JSON Web Key format using the secret key and a provided IV. This is a direct method for key wrapping. ```dart final wrappedKeyAsBytes = await secretKey.wrapJsonWebKey(hmacKey, iv); ``` -------------------------------- ### Generic JSON Source List Source: https://github.com/google/webcrypto.dart/blob/master/third_party/boringssl/INCORPORATING.md A generic JSON file containing source lists for BoringSSL, useful for projects that need to consume this information programmatically. ```json gen/sources.json ``` -------------------------------- ### Import Wrapped and Derived Keys Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Imports keys that were previously wrapped or derived. It handles both wrapped byte arrays and derived keys, specifying SHA-256 for HMAC operations. ```dart final hmacKey = await HmacSecretKey.generate(Hash.sha256); final wrappedKeyAsBytes = secretKey.wrapKey(hmacKey, iv); final hmacKey = await HmacSecretKey.importWrappedKey( secretKey.unwrapKey(wrappedKeyAsBytes, iv), Hash.sha256, ); final hmacKey = await HmacSecretKey.importDerivedKey( hkdfKey.deriveKey(salt, info), Hash.sha256, ); ``` -------------------------------- ### Wrap Key as Bytes Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Wraps a secret key into a raw byte format using specified options and an initialization vector (IV). ```dart final wrappedKeyAsBytes = await secretKey.wrapKey( hmacKey.wrapRawKeyOptions(), iv, ); ``` -------------------------------- ### Derive AES Key using PBKDF2 in JavaScript (Web Crypto API) Source: https://github.com/google/webcrypto.dart/blob/master/doc/derive-key.md Derives a 256-bit AES-GCM key from a password using PBKDF2 with specified salt and iterations in a browser or Node.js environment. Ensure the password, salt, iterations, and hash algorithm match the Dart implementation for accurate comparison. ```javascript (async () => { const enc = new TextEncoder(); const password = enc.encode("correct horse battery staple"); const salt = enc.encode("demo-salt"); // fixed so the test is deterministic const iterations = 100_000; // Import password as a PBKDF2 base key const pwKey = await crypto.subtle.importKey( "raw", password, {name:"PBKDF2"}, false, ["deriveKey"] ); // **deriveKey** → AES-GCM (256 bit) const aesKey = await crypto.subtle.deriveKey( {name:"PBKDF2", salt, iterations, hash:"SHA-256"}, pwKey, {name:"AES-GCM", length:256}, true, ["encrypt","decrypt"] ); // Export key as raw bytes and print as hex const raw = new Uint8Array(await crypto.subtle.exportKey("raw", aesKey)); const hex = [...raw].map(b=>b.toString(16).padStart(2,"0")).join(""); console.log("REFERENCE_HEX =", hex); })(); ``` -------------------------------- ### Dart: Wrap Private Key as PKCS8 with AES-GCM Source: https://github.com/google/webcrypto.dart/blob/master/doc/wrap-key.md Illustrates wrapping an RSA-OAEP private key in PKCS8 format using AES-GCM encryption. Similar to public key wrapping, this involves exporting the private key and encrypting its bytes. ```dart final wrappedPrivateKey = await wrappingKey.encryptBytes( await rsaKeyPair.privateKey.exportPkcs8Key(), iv, ); final unwrappedPkcs8 = await wrappingKey.decryptBytes(wrappedPrivateKey, iv); final privateKey = await RsaOaepPrivateKey.importPkcs8Key( unwrappedPkcs8, Hash.sha256, ); ``` -------------------------------- ### Add Application ID Preprocessor Definition Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/runner/CMakeLists.txt Adds a preprocessor definition for the application ID, making it available to the C++ source files. ```cmake # Add preprocessor definitions for the application ID. add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") ``` -------------------------------- ### Unwrap HMAC Key with Raw Key Options Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Unwraps a key using raw key import options. This is an alternative to using JSON Web Key options for unwrapping. ```dart final hmacKey = await secretKey.unwrapKey( HmacSecretKey.importRawKeyOptions(Hash.sha256), wrappedKeyAsBytes, iv, ); ``` -------------------------------- ### Export Wrapped Raw Key Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Exports a raw key in a wrapped format using specified wrap key options, including an IV. This approach aims for brevity but requires careful handling of options to avoid unsafe reuse. ```dart final hmacKey = await HmacSecretKey.generate(Hash.sha256); final wrappedKeyAsBytes await = hmacKey.exportWrappedRawKey( // WrapKeyOptions secretKey.wrapKeyOptions(iv), ); ``` -------------------------------- ### Unwrap HMAC Key with JSON Web Key Options Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Unwraps a key using JSON Web Key import options. This ensures type safety for HMAC import parameters and prevents incorrect usage of SPKI options. ```dart final hmacKey = await secretKey.unwrapKey( // This must be a ImportKeyOptions, and then unwrapKey returns Future // This allows us to ensure: // - Typing when specifying HMAC import parameters // - Prevents the user from trying using SPKI with options belonging to // a private RsaPssPrivateKey which doesn't support importSpkiKey(...) // // Note: I do not like the naming, I'd love something shorter, maybe just: // HmacSecretKey.importJwkOptions or HmacSecretKey.importJwkParams HmacSecretKey.importJsonWebKeyOptions(Hash.sha256), wrappedKeyAsBytes, iv, ); ``` -------------------------------- ### Import Derived Key Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Imports a key that has been derived using HKDF, utilizing specific derive key options. This is used when the key material is the result of a key derivation process. ```dart final hmacKey = await HmacSecretKey.importDerivedKey( // DeriveKeyOptions hkdfKey.deriveKeyOptions(salt, info), ); ``` -------------------------------- ### Manually Wrap JWK with AES-GCM Source: https://github.com/google/webcrypto.dart/blob/master/doc/wrap-key.md Serializes a JWK, encrypts it using AES-GCM, and then decrypts and imports it. This manually reconstructs the key material, similar to browser's wrapKey("jwk", ...). ```dart import 'dart:convert'; import 'dart:typed_data'; import 'package:webcrypto/webcrypto.dart'; final wrappingKey = await AesGcmSecretKey.generateKey(128); final hmacKey = await HmacSecretKey.generateKey(Hash.sha256); final iv = Uint8List(12); fillRandomBytes(iv); final wrappedJwk = await wrappingKey.encryptBytes( utf8.encode(jsonEncode(await hmacKey.exportJsonWebKey())), iv, ); final decryptedJwkJson = jsonDecode( utf8.decode(await wrappingKey.decryptBytes(wrappedJwk, iv)), ) as Map; final unwrappedKey = await HmacSecretKey.importJsonWebKey( decryptedJwkJson, Hash.sha256, ); ``` -------------------------------- ### WebCrypto Target Properties Source: https://github.com/google/webcrypto.dart/blob/master/src/CMakeLists.txt Configures visibility properties for the 'webcrypto' library, setting C visibility to hidden. This is a common practice for shared libraries to reduce symbol exposure. ```cmake set_target_properties( webcrypto PROPERTIES C_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1 ) ``` -------------------------------- ### Generate Test Vectors Source: https://github.com/google/webcrypto.dart/blob/master/notes.md This command generates test vectors for RSA-PSS tests by running Flutter tests and filtering the output. ```bash flutter pub run test -p vm test/webcrypto/rsapss_test.dart | grep '^|' | sed -e 's#^| ##' > vectors.txt ``` -------------------------------- ### Define Executable Target Source: https://github.com/google/webcrypto.dart/blob/master/example/windows/runner/CMakeLists.txt Defines the main executable for the Windows runner application. Source files and resources are listed here. The BINARY_NAME should be managed in the top-level CMakeLists.txt to ensure `flutter run` compatibility. ```cmake add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" "utils.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" "runner.exe.manifest" ) ``` -------------------------------- ### PBKDF2 Derived Key Output Comparison Source: https://github.com/google/webcrypto.dart/blob/master/doc/derive-key.md Compares the hex output of a PBKDF2-derived AES key generated in Dart using webcrypto.dart against a reference hex value obtained from the Web Crypto API in JavaScript. This confirms the successful and compatible key derivation. ```shell DART_HEX = 44ca28d53395e39b8ecc67e6449f002a5239b4f86023ee54d76a1da28510f388 REFERENCE_HEX = 44ca28d53395e39b8ecc67e6449f002a5239b4f86023ee54d76a1da28510f388 DART_HEX == REFERENCE_HEX: true ``` -------------------------------- ### Derive Key Bits with PBKDF2 Source: https://github.com/google/webcrypto.dart/blob/master/doc/derive-key.md Derive cryptographic key bits using PBKDF2. Use a unique random salt for each password and a high iteration count (e.g., 100k+) to prevent brute-force attacks. The output length should match the desired key size. ```dart final salt = utf8.encode('unique salt'); // A unique salt for this password (public but should be random) final iterations = 100000; // Number of hash iterations (e.g., 100k or more) final derivedBits = await pbkdf2Key.deriveBits( 256, // derive 256-bit key Hash.sha256, // use HMAC-SHA256 as the PRF salt, iterations, ); ``` -------------------------------- ### Derive Key Bits with HKDF Source: https://github.com/google/webcrypto.dart/blob/master/doc/derive-key.md Derive a specified number of key bits using HKDF with a given salt, info, and hash function. The salt should be unique and ideally random for each derivation. ```dart final salt = utf8.encode('unique salt'); // A non-secret salt value (should be random for each derivation) final info = utf8.encode('context info'); // Optional context string final derivedBits = await hkdfKey.deriveBits( 256, // derive 256 bits Hash.sha256, // use SHA-256 in HKDF salt, info, ); ``` -------------------------------- ### Derive Key with Raw or Derive Options Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Derives a key using HKDF, restricted to raw or derive key import options. This ensures that only keys supporting derivation can be used, limiting the scope of possible key types. ```dart final hmacKey = await hkdfKey.deriveKey( // Only allows KeyImportRawOrDeriveOptions, which only keys that support // being derived can create. HmacSecretKey.options(Hash.sha256).raw, salt, info, ); ``` -------------------------------- ### Generate and Wrap HMAC Key Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Generates a new HMAC secret key and then wraps it using a provided secret key and IV. The wrapped key is returned as bytes. ```dart final hmacKey = await HmacSecretKey.generate(Hash.sha256); final wrappedKeyAsBytes = secretKey.wrapKey(hmacKey, iv); ``` -------------------------------- ### Define Executable Target Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/runner/CMakeLists.txt Adds the application executable target, listing all source files. The binary name is managed by the top-level CMakeLists.txt to ensure `flutter run` compatibility. ```cmake # Define the application target. To change its name, change BINARY_NAME in the # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer # work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} "main.cc" "my_application.cc" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" ) ``` -------------------------------- ### Include Generated Plugin Rules Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/CMakeLists.txt Includes the generated_plugins.cmake file, which manages the build rules for Flutter plugins. This is essential for integrating plugin functionality. ```cmake # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) ``` -------------------------------- ### Flutter Tool Backend Custom Command Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/flutter/CMakeLists.txt Defines a custom CMake command to invoke the Flutter tool backend script for building the Flutter library and headers. This command is designed to run whenever the output files are needed. ```cmake add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/_phony_ COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} VERBATIM ) add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" ${FLUTTER_LIBRARY_HEADERS} ) ``` -------------------------------- ### Unwrap Key from Raw Bytes Source: https://github.com/google/webcrypto.dart/blob/master/notes-wrap.md Unwraps a key from raw byte format using the appropriate options, the wrapped key data, and an initialization vector (IV). ```dart final hmacKey = await secretKey.unwrapKey( HmacSecretKey.unwrapRawKeyOptions(Hash.sha256), wrappedKeyAsBytes, iv, ); ``` -------------------------------- ### Define List Prepend Function Source: https://github.com/google/webcrypto.dart/blob/master/example/linux/flutter/CMakeLists.txt Defines a custom CMake function to prepend a prefix to each element in a list, as 'list(TRANSFORM ... PREPEND ...)' is not available in CMake 3.10. ```cmake function(list_prepend LIST_NAME PREFIX) set(NEW_LIST "") foreach(element ${${LIST_NAME}}) list(APPEND NEW_LIST "${PREFIX}${element}") endforeach(element) set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) endfunction() ``` -------------------------------- ### MSVC Compiler Flags and Warnings Source: https://github.com/google/webcrypto.dart/blob/master/src/CMakeLists.txt Configures C and C++ compiler flags for MSVC, including disabling specific warnings and enabling UTF-8 encoding. Use this for Windows builds with MSVC. ```cmake if(MSVC) # Windows/MSVC option from CMakeLists.txt in BoringSSL set(MSVC_DISABLED_WARNINGS_LIST "C4100" # 'exarg' : unreferenced formal parameter "C4127" # conditional expression is constant "C4132" # const object should be initialized "C4244" # 'function' : conversion from 'int' to 'uint8_t', # possible loss of data "C4267" # conversion from 'size_t' to 'int', possible loss of data "C4706" # assignment within conditional expression "C4141" "C4201" # nonstandard extension used: nameless struct/union ) string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR ${MSVC_DISABLED_WARNINGS_LIST}) set(CMAKE_C_FLAGS "-utf-8 -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}") set(CMAKE_CXX_FLAGS "-utf-8 -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}") # Hack because Windows compilers will put .dll files in # $CMAKE_BINARY_DIR/Debug/ folder. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${CMAKE_BINARY_DIR}>) endif() ``` -------------------------------- ### Wrap and Unwrap Raw HMAC Key with RSA-OAEP Source: https://github.com/google/webcrypto.dart/blob/master/doc/wrap-key.md Encrypts a raw HMAC key using RSA-OAEP public key and decrypts it with the private key. This demonstrates the equivalent of browser's wrapKey and unwrapKey for raw keys. ```dart final rsaKeyPair = await RsaOaepPrivateKey.generateKey(2048, BigInt.from(65537), Hash.sha256); final hmacKey = await HmacSecretKey.generateKey(Hash.sha256); final wrappedKey = await rsaKeyPair.publicKey.encryptBytes( await hmacKey.exportRawKey(), label: const [1, 2, 3, 4], ); final unwrappedRaw = await rsaKeyPair.privateKey.decryptBytes( wrappedKey, label: const [1, 2, 3, 4], ); final unwrappedKey = await HmacSecretKey.importRawKey( unwrappedRaw, Hash.sha256, ); ```