| [](https://github.com/dart-lang/tools/actions/workflows/boring.yaml) | |
| [](https://pub.dev/packages/boring) | |
| [](https://pub.dev/packages/boring/publisher) | |
| Raw `ffigen` bindings to Google's | |
| [BoringSSL](https://boringssl.googlesource.com/boringssl/) (`bssl_dart`). | |
| > [!WARNING] | |
| > `package:boring` is not meant to be used directly by application developers. | |
| > It is meant to facilitate code reuse for developers building higher-level | |
| > cryptography packages on top of BoringSSL. | |
| > [!NOTE] | |
| > This package is currently experimental and published under the | |
| > [labs.dart.dev](https://dart.dev/dart-team-packages) pub publisher in order | |
| > to solicit feedback. | |
| > | |
| > For packages in the labs.dart.dev publisher we generally plan to either | |
| > graduate the package into a supported publisher (dart.dev, tools.dart.dev) | |
| > after a period of feedback and iteration, or discontinue the package. | |
| > These packages have a much higher expected rate of API and breaking changes. | |
| > | |
| > Your feedback is valuable and will help us evolve this package. For general | |
| > feedback, suggestions, and comments, please file an issue in the | |
| > [bug tracker](https://github.com/dart-lang/tools/issues). | |
| ## Error Handling | |
| BoringSSL signals failure through return values and pushes details onto a | |
| per-thread error queue. A Dart isolate may resume on a different OS thread | |
| after an `await`, and every package using `package:boring` on a thread shares | |
| its queue, so: | |
| - Read errors with `extractBoringSslError()`, which also clears the queue, | |
| right after the failing call. Don't leave an `await` in between, and don't | |
| defer it to a `finally` that may run after one, such as the release of an | |
| `async` `BoringArena.using`. | |
| - Discard errors you ignore with `ERR_clear_error()`, for example when a failed | |
| signature verification just means `false`. Otherwise they are reported for | |
| the next, unrelated failure. | |
| - Call `ERR_clear_error()` before a call whose errors you report, so errors | |
| left behind by other code aren't attributed to it. | |
| ## Native Asset Build Modes | |
| Configured in `pubspec.yaml` under `hooks.user_defines.boring`: | |
| ```yaml | |
| hooks: | |
| user_defines: | |
| boring: | |
| buildMode: fetch # 'fetch', 'checkout', or 'local' | |
| ``` | |
| - **`fetch`** *(default)*: Downloads the prebuilt library of the pinned | |
| release from GitHub Releases and verifies it against the SHA-256 hash pinned | |
| in the package. A hash mismatch is an error. | |
| - **`checkout`**: Compiles BoringSSL locally from bundled sources via CMake and | |
| Ninja. | |
| - **`local`**: Uses a custom prebuilt dynamic library at `localPath`, which is | |
| bundled as is, without [tree-shaking](#tree-shaking). | |
| Prebuilt libraries exist for Linux (x64 and arm64), macOS (arm64 and x64), | |
| Windows (x64), Android (arm, arm64 and x64; API 21 and later), and iOS (arm64, | |
| and the arm64 and x64 simulators; iOS 12 and later). Other targets require | |
| `buildMode: checkout`, which requires CMake, Ninja, and a C toolchain (Clang or | |
| GCC, Xcode, MSVC, or the Android NDK), plus NASM on Windows. | |
| ## Tree-Shaking | |
| When linking is enabled (`dart build`, and Flutter profile and release builds), | |
| `hook/link.dart` links a dynamic library with only the functions the | |
| application uses from the static library. The bindings are annotated with | |
| `@RecordUse()`, so the Dart compiler records which of them the application | |
| calls, tears off, or takes the address of with `addresses.*`. For the | |
| [example](example/boring_example.dart), the bundled library shrinks from 2.9 MB | |
| to 240 KB on Linux x64. | |
| - Use `addresses.X` rather than `Native.addressOf(X)` for the address of a | |
| function, for example for a `NativeFinalizer`. `Native.addressOf` isn't | |
| recorded, so the function would be missing from the library. | |
| - Without recorded uses, for example with `flutter config | |
| --no-enable-record-use`, all functions are kept. | |
| - Linking requires a C toolchain for the target (Clang or GCC, Xcode, MSVC, or | |
| the Android NDK). Without one, for example when cross-compiling, the `fetch` | |
| build mode bundles the prebuilt dynamic library instead, which is not | |
| tree-shaken, and prints a warning. | |
| ## Conformance Testing | |
| CI checks the bundled BoringSSL and the generated bindings against two external | |
| suites, calling BoringSSL directly through the bindings (see | |
| [`test/conformance/`](test/conformance/)): | |
| - [**Project Wycheproof**](https://github.com/C2SP/wycheproof) | |
| (`./tool/run_conformance_tests.sh`): AES-GCM, ChaCha20-Poly1305, | |
| XChaCha20-Poly1305, AES-CBC, AES Key Wrap, Ed25519, ECDSA (P-256, P-384, | |
| P-521), RSA PKCS#1 v1.5 and RSA-PSS signatures, RSA-OAEP, ECDH, HKDF, HMAC, | |
| and PBKDF2. | |
| - [**x509-limbo**](https://x509-limbo.com) (`./tool/run_x509_limbo_tests.sh`): | |
| 9,770 of the 9,793 path validation testcases run against `X509_verify_cert`, | |
| and 9,240 (94.6%) agree. The divergences, mostly name constraint types | |
| BoringSSL does not support and CA/Browser Forum profile checks it leaves to | |
| the caller, are listed and explained in | |
| [`test/conformance/x509_limbo_expected_failures.txt`][limbo-failures]. | |
| [limbo-failures]: test/conformance/x509_limbo_expected_failures.txt | |
| ## License | |
| See [LICENSE](LICENSE) for details. BoringSSL is licensed under Apache 2.0 and | |
| BSD-style licenses; see | |
| [`third_party/boringssl/LICENSE`](third_party/boringssl/LICENSE). |