From 42cfc38acf3147d05dee48558072766984070c1b Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 6 May 2026 17:37:23 -0400 Subject: [PATCH] Embed the release tarball into the botan-src, instead of using a submodule This makes botan-src upgrades a lot simpler Bump MSRV to 1.85; we needed 1.83 for some of the lzma_rs deps and 1.85 gets us the new `rand 0.10` and 2024 Edition. Bump botan-src to using Botan 3.12.0 --- .ci/build.py | 29 ++++----- .github/workflows/ci.yml | 9 +-- .gitmodules | 4 -- NEWS.md | 20 ++++++ README.md | 2 +- botan-src/Cargo.toml | 36 +++++------ botan-src/README.md | 14 +++++ botan-src/botan | 1 - botan-src/build.rs | 107 ++++++++++++++++++++++++++++++++ botan-src/release.toml | 4 ++ botan-src/scripts/fetch.py | 44 ++++++++++++++ botan-src/src/lib.rs | 118 ++++++++++++++++++++++++++++++++++-- botan-src/vendor/.gitignore | 1 + botan-sys/Cargo.toml | 6 +- botan-sys/src/block.rs | 2 +- botan-sys/src/cipher.rs | 4 +- botan-sys/src/ec_group.rs | 4 +- botan-sys/src/errors.rs | 2 +- botan-sys/src/fpe.rs | 2 +- botan-sys/src/hash.rs | 2 +- botan-sys/src/kdf.rs | 2 +- botan-sys/src/keywrap.rs | 2 +- botan-sys/src/mac.rs | 2 +- botan-sys/src/mp.rs | 8 +-- botan-sys/src/oid.rs | 2 +- botan-sys/src/otp.rs | 4 +- botan-sys/src/passhash.rs | 2 +- botan-sys/src/pk_ops.rs | 2 +- botan-sys/src/pubkey.rs | 4 +- botan-sys/src/rng.rs | 2 +- botan-sys/src/srp6.rs | 2 +- botan-sys/src/tpm2.rs | 4 +- botan-sys/src/utils.rs | 2 +- botan-sys/src/version.rs | 2 +- botan-sys/src/x509.rs | 2 +- botan-sys/src/xof.rs | 2 +- botan-sys/src/zfec.rs | 2 +- botan/Cargo.toml | 6 +- botan/src/ec_group.rs | 2 +- botan/src/memutils.rs | 2 +- botan/src/utils.rs | 2 +- botan/src/x509_cert.rs | 2 +- botan/src/x509_crl.rs | 4 +- botan/tests/tests.rs | 78 ++++++++++++++++-------- botan/tests/wycheproof.rs | 2 +- clippy.toml | 2 +- 46 files changed, 439 insertions(+), 118 deletions(-) delete mode 100644 .gitmodules delete mode 160000 botan-src/botan create mode 100644 botan-src/build.rs create mode 100644 botan-src/release.toml create mode 100755 botan-src/scripts/fetch.py create mode 100644 botan-src/vendor/.gitignore diff --git a/.ci/build.py b/.ci/build.py index 7169ab5..ad9bb3e 100755 --- a/.ci/build.py +++ b/.ci/build.py @@ -62,13 +62,13 @@ def main(args = None): if "SCCACHE_MAXSIZE" not in os.environ: os.environ["SCCACHE_MAXSIZE"] = "2G" - KNOWN_TOOLCHAINS = ['stable', 'nightly', '1.64.0'] + KNOWN_TOOLCHAINS = ['stable', 'nightly', '1.85.1'] KNOWN_FEATURES = ['vendored', 'git', 'no-std'] toolchain = args[1] if toolchain not in KNOWN_TOOLCHAINS: - print("ERROR: Unknown toolchain %s" % (toolchain)) + print("ERROR: Unknown toolchain %s (need to update .ci/build.py?)" % (toolchain)) return 1 features = [] if len(args) < 3 else args[2].split('+') @@ -102,20 +102,22 @@ def main(args = None): return 1 if 'vendored' in features: - run_command(['git', 'submodule', 'update', '--init', '--depth', '3']) + run_command([sys.executable, './botan-src/scripts/fetch.py']) elif 'git' in features: nproc = multiprocessing.cpu_count() botan_src = 'botan-git' run_command(['git', 'clone', '--depth', '1', 'https://github.com/randombit/botan.git', botan_src]) import tomllib - excludes = tomllib.loads(open(os.path.join('botan-src', 'Cargo.toml')).read())['package']['exclude'] - for exclude in excludes: - path = exclude.replace('botan/', botan_src + '/') - if os.path.isdir(path): - shutil.rmtree(path) - elif os.path.isfile(path): - os.remove(path) + cargo_toml = tomllib.loads(open(os.path.join('botan-src', 'Cargo.toml')).read())['package'] + + if 'excludes' in cargo_toml: + for exclude in cargo_toml['excludes']: + path = exclude.replace('botan/', botan_src + '/') + if os.path.isdir(path): + shutil.rmtree(path) + elif os.path.isfile(path): + os.remove(path) run_command(['./configure.py', '--compiler-cache=%s' % (options.compiler_cache), @@ -133,6 +135,8 @@ def main(args = None): os.environ["RUSTFLAGS"] = "-D warnings -L/opt/homebrew/lib" os.environ["RUSTDOCFLAGS"] = "-D warnings -L/opt/homebrew/lib" os.environ["DYLD_LIBRARY_PATH"] = homebrew_dir + elif os.access('/usr/bin/apt-get', os.R_OK): + run_command(['sudo', 'apt-get', 'install', 'libbotan-2-dev']) run_command(['rustc', '--version']) @@ -143,10 +147,7 @@ def main(args = None): run_command(['cargo', 'test'] + sys_features, 'botan-sys') run_command(['cargo', 'build'] + lib_features, 'botan') - - # Can't build tests with 1.64 due to serde_json having MSRV of 1.71.0 now - if toolchain != '1.64.0': - run_command(['cargo', 'test'] + lib_features, 'botan') + run_command(['cargo', 'test'] + lib_features, 'botan') run_command([options.compiler_cache, '--show-stats']) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index df540c8..459c271 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,7 @@ jobs: - uses: actions/checkout@v4 + - run: ./botan-src/scripts/fetch.py - run: cargo +nightly clippy -- --deny warnings ci: runs-on: ubuntu-24.04 @@ -50,15 +51,15 @@ jobs: features: git - toolchain: stable features: vendored - - toolchain: 1.64.0 # MSRV no-std + - toolchain: 1.85.1 # MSRV no-std features: no-std+git - - toolchain: 1.64.0 # MSRV + - toolchain: 1.85.1 # MSRV - toolchain: nightly - toolchain: nightly features: no-std+git steps: - - run: sudo apt-get -qq install ccache libbotan-2-dev + - run: sudo apt-get -qq install ccache - uses: actions/checkout@v4 - uses: actions/cache@v4 with: @@ -90,7 +91,7 @@ jobs: - toolchain: nightly steps: - - run: sudo apt-get -qq install ccache libbotan-2-dev + - run: sudo apt-get -qq install ccache - uses: actions/checkout@v4 - uses: actions/cache@v4 with: diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 67b2aa6..0000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "botan-src/botan"] - path = botan-src/botan - url = https://github.com/randombit/botan.git - branch = release-3 diff --git a/NEWS.md b/NEWS.md index 14e6c25..a070156 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,23 @@ +## 0.13.0 Not Yet Released + +- Minor version bump due to MSRV increase +- Bump MSRV to 1.85.0 +- Bump Rust Edition to 2024 +- Add support for new FFI interfaces in Botan 3.10, 3.11, 3.12 +- The `botan-src` crate now ships the upstream Botan release tarball + (`.tar.xz`) inside the published crate and extracts it at build time + rather than building from a git submodule. +- Add locking to Privkey to work around bugs in versions of Botan prior to 3.11.0. + This requires `std` support; thus `no_std` builds now require at least Botan 3.11.0 +- Update `botan-src` to Botan 3.12.0 +- Implement `rand::TryRngCore` for `RandomNumberGenerator` +- Add `Signer::signature_length` +- Add `Pubkey::load_rsa_pkcs1` for loading RSA public keys in PKCS#1 form +- Add various interfaces for CRL generation and handling +- Add additional X.509 certificate getters: `ocsp_responders`, + `issuer_dn`, `subject_dn`, `is_ca`, `path_limit`, `pem_encode`, `der_encode` +- Fix some tests that hit behavior changes in Botan 3.12 + ## 0.12.0 2025-08-05 - Minor version bump due to removing a feature diff --git a/README.md b/README.md index 0313e9a..16e4322 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ PRs and comments/issues happily accepted. MSRV ----- -The Minimum Supported Rust Version (MSRV) of this crate is Rust 1.64.0. +The Minimum Supported Rust Version (MSRV) of this crate is Rust 1.85.0. Any future increase in the MSRV will be accompanied by increasing the minor version number. diff --git a/botan-src/Cargo.toml b/botan-src/Cargo.toml index 59cf81c..f1af834 100644 --- a/botan-src/Cargo.toml +++ b/botan-src/Cargo.toml @@ -1,32 +1,32 @@ [package] name = "botan-src" -version = "0.30900.2" -authors = ["Rodolphe Breard ", "Jack Lloyd "] +version = "0.31200.0" +authors = ["Jack Lloyd ", "Rodolphe Breard "] description = "Sources of Botan cryptography library" license = "MIT" -edition = "2021" +edition = "2024" homepage = "https://botan.randombit.net/" repository = "https://github.com/randombit/botan-rs" readme = "README.md" categories = ["cryptography"] -rust-version = "1.64" +rust-version = "1.85" +build = "build.rs" -exclude = ["botan/doc", - "botan/src/bogo_shim", - "botan/src/cli", - "botan/src/ct_selftest", - "botan/src/examples", - "botan/src/fuzzer", - "botan/src/lib/compat/sodium", - "botan/src/lib/filters", - "botan/src/lib/prov/pkcs11", - "botan/src/lib/prov/tpm", - "botan/src/lib/prov/tpm2", - "botan/src/lib/tls", - "botan/src/python", - "botan/src/tests"] +include = [ + "Cargo.toml", + "README.md", + "build.rs", + "release.toml", + "src/**/*.rs", + "examples/**/*.rs", + "scripts/fetch.py", + "vendor/Botan-*.tar.xz", +] [dependencies] +lzma-rs = { version = "0.3", default-features = false } +sha2 = { version = "0.10", default-features = false } +tar = { version = "0.4", default-features = false } [[example]] name = "build" diff --git a/botan-src/README.md b/botan-src/README.md index 7ff066a..11bcd1c 100644 --- a/botan-src/README.md +++ b/botan-src/README.md @@ -7,3 +7,17 @@ library. It is supposed to be used by the A high level Rust interface built on this library is included in the [botan](https://crates.io/crates/botan) crate. + +## Building against a custom Botan tree + +The crate ships the upstream Botan release tarball in `vendor/` and +extracts it at build time. Two environment variables let you override +that, which is useful when testing a fork or pre-release: + +- `BOTAN_SRC_DIR=/path/to/checkout` — build from an existing source tree + (e.g. a git checkout). No extraction, no checksum. +- `BOTAN_SRC_TARBALL=/path/to/foo.tar.xz` — extract this `.tar.xz` + instead of the bundled one. No checksum. + +If neither is set, the bundled tarball is extracted and verified against +the pinned SHA-256. diff --git a/botan-src/botan b/botan-src/botan deleted file mode 160000 index 07e1cfe..0000000 --- a/botan-src/botan +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 07e1cfe0a06b224bbb37ad534736924931184246 diff --git a/botan-src/build.rs b/botan-src/build.rs new file mode 100644 index 0000000..308bed1 --- /dev/null +++ b/botan-src/build.rs @@ -0,0 +1,107 @@ +// Parses release.toml and exposes its values as compile-time `env!` +// strings inside src/lib.rs. The hand-rolled parser handles the +// trivial subset of TOML actually used in release.toml — three +// top-level `key = "value"` lines plus comments — to avoid pulling in +// a TOML build-dependency. +use std::fs; +use std::path::Path; + +fn extract(content: &str, key: &str) -> Option { + for line in content.lines() { + let line = line.split('#').next().unwrap_or("").trim(); + if line.is_empty() { + continue; + } + if let Some((k, v)) = line.split_once('=') { + if k.trim() == key { + return Some(v.trim().trim_matches('"').to_string()); + } + } + } + None +} + +fn parse_botan_version(s: &str) -> Option<(u32, u32, u32)> { + let mut parts = s.split('.').map(|p| p.parse::().ok()); + Some((parts.next()??, parts.next()??, parts.next()??)) +} + +// botan-src crate version is `0.MNNPP.X` where M.NN.PP is the bundled +// Botan version. Cross-check that against release.toml so we never +// publish e.g. 0.31100.0 with a Botan 3.11.1 tarball inside. +fn parse_crate_botan_version(crate_version: &str) -> Option<(u32, u32, u32)> { + let mut parts = crate_version.split('.'); + parts.next()?; // leading "0" + let encoded: u32 = parts.next()?.parse().ok()?; + Some((encoded / 10000, (encoded / 100) % 100, encoded % 100)) +} + +fn main() { + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"); + let manifest_dir = Path::new(&manifest_dir); + let release_path = manifest_dir.join("release.toml"); + println!("cargo:rerun-if-changed=release.toml"); + let content = fs::read_to_string(&release_path) + .unwrap_or_else(|e| panic!("read {}: {e}", release_path.display())); + + let pairs = [ + ("version", "BOTAN_VERSION"), + ("sha256", "BOTAN_TARBALL_SHA256"), + ("url", "BOTAN_TARBALL_URL"), + ]; + let mut values = std::collections::HashMap::new(); + for (key, _) in pairs { + let value = + extract(&content, key).unwrap_or_else(|| panic!("release.toml missing key `{key}`")); + values.insert(key, value); + } + // Expand `{key}` references between fields (so `url` can refer to `{version}`). + let raw: Vec<(&str, String)> = values.iter().map(|(k, v)| (*k, v.clone())).collect(); + for v in values.values_mut() { + for (k, replacement) in &raw { + *v = v.replace(&format!("{{{k}}}"), replacement); + } + } + for (key, env_var) in pairs { + println!("cargo:rustc-env={env_var}={}", values[key]); + } + + let botan_version = parse_botan_version(&values["version"]).unwrap_or_else(|| { + panic!( + "release.toml `version` not in M.N.P form: {}", + values["version"] + ) + }); + let crate_version = std::env::var("CARGO_PKG_VERSION").expect("CARGO_PKG_VERSION"); + let crate_encoded = parse_crate_botan_version(&crate_version).unwrap_or_else(|| { + panic!("can't decode botan version from crate version `{crate_version}`") + }); + if crate_encoded != botan_version { + panic!( + "\nbotan-src crate version `{crate_version}` encodes Botan {}.{}.{},\n\ + but release.toml says Botan {}.{}.{}. Bump one or the other so they agree.\n", + crate_encoded.0, + crate_encoded.1, + crate_encoded.2, + botan_version.0, + botan_version.1, + botan_version.2, + ); + } + + // Refuse to build (or publish, via the default `cargo publish` verify + // step) without the upstream tarball staged in vendor/. Catches the + // "publish with empty vendor/" footgun. + let tarball = manifest_dir + .join("vendor") + .join(format!("Botan-{}.tar.xz", values["version"])); + println!("cargo:rerun-if-changed={}", tarball.display()); + if !tarball.exists() { + panic!( + "\nBotan source tarball missing at {}.\n\ + Run `python3 scripts/fetch.py` from botan-src/ to download it\n\ + before building or publishing this crate.\n", + tarball.display() + ); + } +} diff --git a/botan-src/release.toml b/botan-src/release.toml new file mode 100644 index 0000000..0b51543 --- /dev/null +++ b/botan-src/release.toml @@ -0,0 +1,4 @@ +# Pinned release, override using BOTAN_SRC_DIR or BOTAN_SRC_TARBALL +version = "3.12.0" +sha256 = "5370f98dc15f8c222ee1ce52cd61c8756a53be0dc57cc4c1b0714d5a09ad74fb" +url = "https://botan.randombit.net/releases/Botan-{version}.tar.xz" diff --git a/botan-src/scripts/fetch.py b/botan-src/scripts/fetch.py new file mode 100755 index 0000000..971eddd --- /dev/null +++ b/botan-src/scripts/fetch.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +"""Download and verify the upstream Botan release tarball into vendor/. + +Run before `cargo publish -p botan-src`. Reads release.toml so the +version/sha/URL stays in lockstep with what build.rs sees. + +Requires Python 3.11+ (for tomllib). +""" + +import hashlib +import sys +import tomllib +import urllib.request +from pathlib import Path + + +def main() -> int: + repo = Path(__file__).resolve().parent.parent + raw = tomllib.loads((repo / "release.toml").read_text()) + # Expand `{key}` references between fields so e.g. url can refer to {version}. + info = {k: v.format(**raw) if isinstance(v, str) else v for k, v in raw.items()} + vendor = repo / "vendor" + vendor.mkdir(exist_ok=True) + tarball = vendor / f"Botan-{info['version']}.tar.xz" + + if not tarball.exists(): + print(f"downloading {info['url']}") + urllib.request.urlretrieve(info["url"], tarball) + + actual = hashlib.sha256(tarball.read_bytes()).hexdigest() + if actual != info["sha256"]: + tarball.unlink() + print( + f"sha256 mismatch for {tarball.name}: " + f"expected {info['sha256']}, got {actual}", + file=sys.stderr, + ) + return 1 + print(f"ok: {tarball}") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/botan-src/src/lib.rs b/botan-src/src/lib.rs index dc8009f..0599f80 100644 --- a/botan-src/src/lib.rs +++ b/botan-src/src/lib.rs @@ -1,12 +1,19 @@ use std::env; -use std::path::PathBuf; +use std::fs; +use std::io; +use std::path::{Path, PathBuf}; use std::process::Command; const BUILD_ERROR_MSG: &str = "Unable to build botan."; const SRC_DIR_ERROR_MSG: &str = "Unable to find the source directory."; -const SRC_DIR: &str = "botan"; const INCLUDE_DIR: &str = "build/include/public"; +// Pinned upstream release. Single source of truth lives in release.toml; +// build.rs parses that file and re-exports it via `cargo:rustc-env`. +pub const BOTAN_VERSION: &str = env!("BOTAN_VERSION"); +pub const BOTAN_TARBALL_SHA256: &str = env!("BOTAN_TARBALL_SHA256"); +pub const BOTAN_TARBALL_URL: &str = env!("BOTAN_TARBALL_URL"); + macro_rules! pathbuf_to_string { ($s: ident) => { $s.to_str().expect(BUILD_ERROR_MSG).to_string() @@ -115,10 +122,111 @@ fn make(build_dir: &str) { } } +fn bundled_tarball_path() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("vendor") + .join(format!("Botan-{BOTAN_VERSION}.tar.xz")) +} + +fn verify_sha256(path: &Path) { + use sha2::{Digest, Sha256}; + let bytes = fs::read(path).expect("read tarball"); + let actual = format!("{:x}", Sha256::digest(&bytes)); + if actual != BOTAN_TARBALL_SHA256 { + panic!( + "Botan tarball at {} has unexpected sha256 (expected {}, got {})", + path.display(), + BOTAN_TARBALL_SHA256, + actual, + ); + } +} + +fn extract_tarball(tarball: &Path, dest: &Path) { + let file = fs::File::open(tarball).expect("open tarball"); + let mut reader = io::BufReader::new(file); + let mut decompressed = Vec::new(); + lzma_rs::xz_decompress(&mut reader, &mut decompressed).expect("xz decompress"); + let mut archive = tar::Archive::new(io::Cursor::new(decompressed)); + archive.unpack(dest).expect("untar"); +} + +// After unpacking, find the single top-level directory the tarball +// produced. Bundled Botan releases use `Botan-X.Y.Z`, but a developer's +// custom tarball (BOTAN_SRC_TARBALL) might use anything. +fn find_extracted_root(extract_root: &Path) -> PathBuf { + let mut dirs = fs::read_dir(extract_root) + .expect("read extract root") + .filter_map(Result::ok) + .map(|e| e.path()) + .filter(|p| p.is_dir()); + let first = dirs + .next() + .expect("tarball produced no top-level directory"); + if dirs.next().is_some() { + panic!("tarball must contain exactly one top-level directory"); + } + first +} + +/// Returns the directory containing Botan sources to build against. +/// +/// Resolution order, highest priority first: +/// - `BOTAN_SRC_DIR` — use this directory as the source tree directly +/// (no extraction, no checksum). Useful for testing a local git +/// checkout or fork. +/// - `BOTAN_SRC_TARBALL` — extract this `.tar.xz` instead of the bundled +/// one. No checksum: the caller is responsible for what they hand us. +/// - otherwise: extract the bundled `vendor/Botan-X.Y.Z.tar.xz`, +/// verifying it matches the pinned SHA-256. +fn ensure_source(out_dir: &Path) -> PathBuf { + println!("cargo:rerun-if-env-changed=BOTAN_SRC_DIR"); + println!("cargo:rerun-if-env-changed=BOTAN_SRC_TARBALL"); + + if let Some(custom_dir) = env::var_os("BOTAN_SRC_DIR") { + let path = PathBuf::from(custom_dir); + if !path.join("configure.py").is_file() { + panic!( + "BOTAN_SRC_DIR={} does not contain configure.py", + path.display() + ); + } + return path; + } + + let custom_tarball = env::var_os("BOTAN_SRC_TARBALL").map(PathBuf::from); + let tarball = custom_tarball.clone().unwrap_or_else(bundled_tarball_path); + let stamp_marker = match &custom_tarball { + Some(p) => format!("custom:{}", p.display()), + None => format!("bundled:{BOTAN_TARBALL_SHA256}"), + }; + + let extract_root = out_dir.join("botan-src"); + let stamp = extract_root.join(".extracted"); + let already_extracted = fs::read_to_string(&stamp) + .map(|s| s.trim() == stamp_marker) + .unwrap_or(false); + if !already_extracted { + if !tarball.exists() { + panic!("Botan source tarball missing at {}", tarball.display()); + } + if custom_tarball.is_none() { + verify_sha256(&tarball); + } + let _ = fs::remove_dir_all(&extract_root); + fs::create_dir_all(&extract_root).expect("mkdir extract root"); + extract_tarball(&tarball, &extract_root); + fs::write(&stamp, &stamp_marker).expect("write stamp"); + } + find_extracted_root(&extract_root) +} + pub fn build() -> (String, std::path::PathBuf) { - let src_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(SRC_DIR); - let build_dir = env::var_os("OUT_DIR").map_or(src_dir.to_owned(), PathBuf::from); - let build_dir = build_dir.join("botan"); + let out_dir = env::var_os("OUT_DIR") + .map(PathBuf::from) + .expect("OUT_DIR is set when invoked from a build script"); + let src_dir = ensure_source(&out_dir); + let build_dir = out_dir.join("botan-build"); let include_dir = build_dir.join(INCLUDE_DIR); let build_dir = pathbuf_to_string!(build_dir); let orig_dir = env::current_dir().expect(SRC_DIR_ERROR_MSG); diff --git a/botan-src/vendor/.gitignore b/botan-src/vendor/.gitignore new file mode 100644 index 0000000..b5624b7 --- /dev/null +++ b/botan-src/vendor/.gitignore @@ -0,0 +1 @@ +*.tar.xz diff --git a/botan-sys/Cargo.toml b/botan-sys/Cargo.toml index 2fef7ec..1266031 100644 --- a/botan-sys/Cargo.toml +++ b/botan-sys/Cargo.toml @@ -11,8 +11,8 @@ repository = "https://github.com/randombit/botan-rs" documentation = "https://docs.rs/botan-sys" readme = "README.md" categories = [ "cryptography", "external-ffi-bindings", "no-std" ] -edition = "2021" -rust-version = "1.64" +edition = "2024" +rust-version = "1.85" [features] default = [] @@ -21,6 +21,6 @@ static = [] pkg-config = ["dep:pkg-config"] [build-dependencies] -botan-src = { version = "0.30900.1", optional = true, path = "../botan-src" } +botan-src = { version = "0.31200.0", optional = true, path = "../botan-src" } pkg-config = { version = "0.3.30", optional = true } cc = "1" diff --git a/botan-sys/src/block.rs b/botan-sys/src/block.rs index 6f313ee..6c2ad43 100644 --- a/botan-sys/src/block.rs +++ b/botan-sys/src/block.rs @@ -3,7 +3,7 @@ use crate::ffi_types::{c_char, c_int}; pub enum botan_block_cipher_struct {} pub type botan_block_cipher_t = *mut botan_block_cipher_struct; -extern "C" { +unsafe extern "C" { pub fn botan_block_cipher_init( bc: *mut botan_block_cipher_t, diff --git a/botan-sys/src/cipher.rs b/botan-sys/src/cipher.rs index 094f2aa..e7fed41 100644 --- a/botan-sys/src/cipher.rs +++ b/botan-sys/src/cipher.rs @@ -3,9 +3,9 @@ use crate::ffi_types::{c_char, c_int}; pub enum botan_cipher_struct {} pub type botan_cipher_t = *mut botan_cipher_struct; -extern "C" { +unsafe extern "C" { pub fn botan_cipher_init(cipher: *mut botan_cipher_t, name: *const c_char, flags: u32) - -> c_int; + -> c_int; pub fn botan_cipher_valid_nonce_length(cipher: botan_cipher_t, nl: usize) -> c_int; pub fn botan_cipher_get_tag_length(cipher: botan_cipher_t, tag_size: *mut usize) -> c_int; pub fn botan_cipher_get_default_nonce_length(cipher: botan_cipher_t, nl: *mut usize) -> c_int; diff --git a/botan-sys/src/ec_group.rs b/botan-sys/src/ec_group.rs index a0d3eff..593cf84 100644 --- a/botan-sys/src/ec_group.rs +++ b/botan-sys/src/ec_group.rs @@ -23,7 +23,7 @@ pub enum botan_ec_point_struct {} pub type botan_ec_point_t = *mut botan_ec_point_struct; #[cfg(botan_ffi_20250506)] -extern "C" { +unsafe extern "C" { pub fn botan_ec_group_destroy(bc: botan_ec_group_t) -> c_int; pub fn botan_ec_group_supports_application_specific_group(res: *mut c_int) -> c_int; @@ -83,7 +83,7 @@ extern "C" { } #[cfg(botan_ffi_20260506)] -extern "C" { +unsafe extern "C" { pub fn botan_ec_scalar_destroy(ec_scalar: botan_ec_scalar_t) -> c_int; pub fn botan_ec_scalar_random( diff --git a/botan-sys/src/errors.rs b/botan-sys/src/errors.rs index ae0cf78..e79e450 100644 --- a/botan-sys/src/errors.rs +++ b/botan-sys/src/errors.rs @@ -29,7 +29,7 @@ pub const BOTAN_FFI_ERROR_ROUGHTIME_ERROR: BOTAN_FFI_ERROR = -77; pub const BOTAN_FFI_ERROR_TPM_ERROR: BOTAN_FFI_ERROR = -78; pub const BOTAN_FFI_ERROR_UNKNOWN_ERROR: BOTAN_FFI_ERROR = -100; -extern "C" { +unsafe extern "C" { pub fn botan_error_description(err: BOTAN_FFI_ERROR) -> *const c_char; diff --git a/botan-sys/src/fpe.rs b/botan-sys/src/fpe.rs index f9f28fa..6f76ef5 100644 --- a/botan-sys/src/fpe.rs +++ b/botan-sys/src/fpe.rs @@ -5,7 +5,7 @@ use crate::mp::botan_mp_t; pub enum botan_fpe_struct {} pub type botan_fpe_t = *mut botan_fpe_struct; -extern "C" { +unsafe extern "C" { pub fn botan_fpe_fe1_init( fpe: *mut botan_fpe_t, diff --git a/botan-sys/src/hash.rs b/botan-sys/src/hash.rs index c56fcbc..dcb9fc6 100644 --- a/botan-sys/src/hash.rs +++ b/botan-sys/src/hash.rs @@ -3,7 +3,7 @@ use crate::ffi_types::{c_char, c_int}; pub enum botan_hash_struct {} pub type botan_hash_t = *mut botan_hash_struct; -extern "C" { +unsafe extern "C" { pub fn botan_hash_init(hash: *mut botan_hash_t, hash_name: *const c_char, flags: u32) -> c_int; diff --git a/botan-sys/src/kdf.rs b/botan-sys/src/kdf.rs index 30653b8..3180d3b 100644 --- a/botan-sys/src/kdf.rs +++ b/botan-sys/src/kdf.rs @@ -1,6 +1,6 @@ use crate::ffi_types::{c_char, c_int}; -extern "C" { +unsafe extern "C" { pub fn botan_pbkdf( pbkdf_algo: *const c_char, diff --git a/botan-sys/src/keywrap.rs b/botan-sys/src/keywrap.rs index 28719c5..6cae7f7 100644 --- a/botan-sys/src/keywrap.rs +++ b/botan-sys/src/keywrap.rs @@ -1,6 +1,6 @@ use crate::ffi_types::{c_char, c_int}; -extern "C" { +unsafe extern "C" { pub fn botan_key_wrap3394( input: *const u8, diff --git a/botan-sys/src/mac.rs b/botan-sys/src/mac.rs index 08dad77..59fa17b 100644 --- a/botan-sys/src/mac.rs +++ b/botan-sys/src/mac.rs @@ -3,7 +3,7 @@ use crate::ffi_types::{c_char, c_int}; pub enum botan_mac_struct {} pub type botan_mac_t = *mut botan_mac_struct; -extern "C" { +unsafe extern "C" { pub fn botan_mac_init(mac: *mut botan_mac_t, mac_name: *const c_char, flags: u32) -> c_int; diff --git a/botan-sys/src/mp.rs b/botan-sys/src/mp.rs index f86fedf..6845a41 100644 --- a/botan-sys/src/mp.rs +++ b/botan-sys/src/mp.rs @@ -9,7 +9,7 @@ use crate::rng::botan_rng_t; pub enum botan_mp_struct {} pub type botan_mp_t = *mut botan_mp_struct; -extern "C" { +unsafe extern "C" { pub fn botan_mp_init(mp: *mut botan_mp_t) -> c_int; pub fn botan_mp_destroy(mp: botan_mp_t) -> c_int; @@ -26,7 +26,7 @@ extern "C" { pub fn botan_mp_set_from_str(dest: botan_mp_t, str: *const c_char) -> c_int; pub fn botan_mp_set_from_radix_str(dest: botan_mp_t, str: *const c_char, radix: usize) - -> c_int; + -> c_int; pub fn botan_mp_num_bits(n: botan_mp_t, bits: *mut usize) -> c_int; pub fn botan_mp_num_bytes(n: botan_mp_t, bytes: *mut usize) -> c_int; pub fn botan_mp_to_bin(mp: botan_mp_t, vec: *mut u8) -> c_int; @@ -82,7 +82,7 @@ extern "C" { #[cfg(botan_ffi_20250506)] pub fn botan_mp_view_hex(mp: botan_mp_t, ctx: botan_view_ctx, view: botan_view_str_fn) - -> c_int; + -> c_int; #[cfg(botan_ffi_20250506)] pub fn botan_mp_view_str( @@ -94,6 +94,6 @@ extern "C" { #[cfg(botan_ffi_20250506)] pub fn botan_mp_view_bin(mp: botan_mp_t, ctx: botan_view_ctx, view: botan_view_bin_fn) - -> c_int; + -> c_int; } diff --git a/botan-sys/src/oid.rs b/botan-sys/src/oid.rs index fefd835..1ee6d28 100644 --- a/botan-sys/src/oid.rs +++ b/botan-sys/src/oid.rs @@ -8,7 +8,7 @@ pub enum botan_asn1_oid_struct {} pub type botan_asn1_oid_t = *mut botan_asn1_oid_struct; #[cfg(botan_ffi_20250506)] -extern "C" { +unsafe extern "C" { pub fn botan_oid_destroy(bc: botan_asn1_oid_t) -> c_int; pub fn botan_oid_from_string(oid: *mut botan_asn1_oid_t, oid_str: *const c_char) -> c_int; diff --git a/botan-sys/src/otp.rs b/botan-sys/src/otp.rs index 34cbe40..ea0ea87 100644 --- a/botan-sys/src/otp.rs +++ b/botan-sys/src/otp.rs @@ -6,7 +6,7 @@ pub type botan_hotp_t = *mut botan_hotp_struct; pub enum botan_totp_struct {} pub type botan_totp_t = *mut botan_totp_struct; -extern "C" { +unsafe extern "C" { pub fn botan_hotp_init( hotp: *mut botan_hotp_t, @@ -19,7 +19,7 @@ extern "C" { pub fn botan_hotp_destroy(hotp: botan_hotp_t) -> c_int; pub fn botan_hotp_generate(hotp: botan_hotp_t, hotp_code: *mut u32, hotp_counter: u64) - -> c_int; + -> c_int; pub fn botan_hotp_check( hotp: botan_hotp_t, diff --git a/botan-sys/src/passhash.rs b/botan-sys/src/passhash.rs index c60a34e..0fb0c91 100644 --- a/botan-sys/src/passhash.rs +++ b/botan-sys/src/passhash.rs @@ -2,7 +2,7 @@ use crate::ffi_types::{c_char, c_int}; use crate::rng::botan_rng_t; -extern "C" { +unsafe extern "C" { pub fn botan_bcrypt_generate( out: *mut u8, diff --git a/botan-sys/src/pk_ops.rs b/botan-sys/src/pk_ops.rs index 7079306..dfe7882 100644 --- a/botan-sys/src/pk_ops.rs +++ b/botan-sys/src/pk_ops.rs @@ -24,7 +24,7 @@ pub type botan_pk_op_kem_encrypt_t = *mut botan_pk_op_kem_encrypt_struct; pub enum botan_pk_op_kem_decrypt_struct {} pub type botan_pk_op_kem_decrypt_t = *mut botan_pk_op_kem_decrypt_struct; -extern "C" { +unsafe extern "C" { pub fn botan_pk_op_encrypt_create( op: *mut botan_pk_op_encrypt_t, key: botan_pubkey_t, diff --git a/botan-sys/src/pubkey.rs b/botan-sys/src/pubkey.rs index 5607817..2152312 100644 --- a/botan-sys/src/pubkey.rs +++ b/botan-sys/src/pubkey.rs @@ -15,7 +15,7 @@ pub type botan_pubkey_t = *mut botan_pubkey_struct; pub enum botan_privkey_struct {} pub type botan_privkey_t = *mut botan_privkey_struct; -extern "C" { +unsafe extern "C" { pub fn botan_privkey_create( key: *mut botan_privkey_t, algo_name: *const c_char, @@ -555,5 +555,5 @@ extern "C" { #[cfg(botan_ffi_20260506)] pub fn botan_ec_pubkey_get_group(key: botan_pubkey_t, ec_group: *mut botan_ec_group_t) - -> c_int; + -> c_int; } diff --git a/botan-sys/src/rng.rs b/botan-sys/src/rng.rs index 9ca7b9b..1b0d86a 100644 --- a/botan-sys/src/rng.rs +++ b/botan-sys/src/rng.rs @@ -3,7 +3,7 @@ use crate::ffi_types::{c_char, c_int, c_void}; pub enum botan_rng_struct {} pub type botan_rng_t = *mut botan_rng_struct; -extern "C" { +unsafe extern "C" { pub fn botan_rng_init(rng: *mut botan_rng_t, rng_type: *const c_char) -> c_int; diff --git a/botan-sys/src/srp6.rs b/botan-sys/src/srp6.rs index 30549ec..c0fbcfa 100644 --- a/botan-sys/src/srp6.rs +++ b/botan-sys/src/srp6.rs @@ -5,7 +5,7 @@ pub enum botan_srp6_server_session_struct {} pub type botan_srp6_server_session_t = *mut botan_srp6_server_session_struct; #[cfg(botan_ffi_20230403)] -extern "C" { +unsafe extern "C" { pub fn botan_srp6_server_session_init(srp6: *mut botan_srp6_server_session_t) -> c_int; pub fn botan_srp6_server_session_destroy(srp6: botan_srp6_server_session_t) -> c_int; diff --git a/botan-sys/src/tpm2.rs b/botan-sys/src/tpm2.rs index e79a348..b8ec5c8 100644 --- a/botan-sys/src/tpm2.rs +++ b/botan-sys/src/tpm2.rs @@ -17,7 +17,7 @@ pub struct ESYS_CONTEXT { } #[cfg(botan_ffi_20250506)] -extern "C" { +unsafe extern "C" { pub fn botan_tpm2_supports_crypto_backend() -> c_int; pub fn botan_tpm2_ctx_init( @@ -47,7 +47,7 @@ extern "C" { ) -> c_int; pub fn botan_tpm2_crypto_backend_state_destroy(cbs: botan_tpm2_crypto_backend_state_t) - -> c_int; + -> c_int; pub fn botan_tpm2_rng_init( rng_out: *mut botan_rng_t, diff --git a/botan-sys/src/utils.rs b/botan-sys/src/utils.rs index 3925f51..3cebffd 100644 --- a/botan-sys/src/utils.rs +++ b/botan-sys/src/utils.rs @@ -1,6 +1,6 @@ use crate::ffi_types::{c_char, c_int, c_void}; -extern "C" { +unsafe extern "C" { pub fn botan_constant_time_compare(x: *const u8, y: *const u8, len: usize) -> c_int; diff --git a/botan-sys/src/version.rs b/botan-sys/src/version.rs index f6662a0..c9d0ee5 100644 --- a/botan-sys/src/version.rs +++ b/botan-sys/src/version.rs @@ -1,6 +1,6 @@ use crate::ffi_types::{c_char, c_int}; -extern "C" { +unsafe extern "C" { pub fn botan_ffi_api_version() -> u32; diff --git a/botan-sys/src/x509.rs b/botan-sys/src/x509.rs index dc838fe..2d59e95 100644 --- a/botan-sys/src/x509.rs +++ b/botan-sys/src/x509.rs @@ -106,7 +106,7 @@ impl TryFrom for X509CrlReasonCode { } } -extern "C" { +unsafe extern "C" { pub fn botan_x509_cert_load( cert_obj: *mut botan_x509_cert_t, cert: *const u8, diff --git a/botan-sys/src/xof.rs b/botan-sys/src/xof.rs index cc6d6a4..4b1de14 100644 --- a/botan-sys/src/xof.rs +++ b/botan-sys/src/xof.rs @@ -4,7 +4,7 @@ pub enum botan_xof_struct {} pub type botan_xof_t = *mut botan_xof_struct; #[cfg(botan_ffi_20260303)] -extern "C" { +unsafe extern "C" { pub fn botan_xof_init(xof: *mut botan_xof_t, xof_name: *const c_char, flags: u32) -> c_int; pub fn botan_xof_copy_state(dest: *mut botan_xof_t, source: botan_xof_t) -> c_int; diff --git a/botan-sys/src/zfec.rs b/botan-sys/src/zfec.rs index ec723c2..998e48a 100644 --- a/botan-sys/src/zfec.rs +++ b/botan-sys/src/zfec.rs @@ -1,4 +1,4 @@ -extern "C" { +unsafe extern "C" { #[cfg(botan_ffi_20230403)] pub fn botan_zfec_encode( diff --git a/botan/Cargo.toml b/botan/Cargo.toml index 7327dd1..69fc02d 100644 --- a/botan/Cargo.toml +++ b/botan/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "botan" -version = "0.12.0" +version = "0.13.0" authors = ["Jack Lloyd "] description = "Rust wrapper for Botan cryptography library" license = "MIT" @@ -10,8 +10,8 @@ documentation = "https://docs.rs/botan" keywords = [ "crypto" ] readme = "../README.md" categories = [ "cryptography", "api-bindings", "no-std" ] -edition = "2021" -rust-version = "1.64" +edition = "2024" +rust-version = "1.85" [dependencies] botan-sys = { version = "1.20260506", path = "../botan-sys" } diff --git a/botan/src/ec_group.rs b/botan/src/ec_group.rs index 3d9bc15..fcf13fc 100644 --- a/botan/src/ec_group.rs +++ b/botan/src/ec_group.rs @@ -1,4 +1,4 @@ -use crate::{utils::*, MPI}; +use crate::{MPI, utils::*}; use botan_sys::*; #[cfg(botan_ffi_20250506)] diff --git a/botan/src/memutils.rs b/botan/src/memutils.rs index bc4f067..3d65c92 100644 --- a/botan/src/memutils.rs +++ b/botan/src/memutils.rs @@ -72,7 +72,7 @@ pub fn hex_decode(x: &str) -> Result> { /// assert_eq!(botan::base64_encode(&[0x5A, 0x16, 0xAD, 0x4E, 0x17, 0x87, 0x79, 0xC9]).unwrap(), "WhatTheHeck="); /// ``` pub fn base64_encode(x: &[u8]) -> Result { - let b64_len = 1 + ((x.len() + 2) / 3) * 4; + let b64_len = 1 + x.len().div_ceil(3) * 4; call_botan_ffi_returning_string(b64_len, &|out_buf, out_len| unsafe { botan_base64_encode(x.as_ptr(), x.len(), out_buf as *mut c_char, out_len) diff --git a/botan/src/utils.rs b/botan/src/utils.rs index 1100d20..915ff04 100644 --- a/botan/src/utils.rs +++ b/botan/src/utils.rs @@ -148,7 +148,7 @@ fn cstr_slice_to_str(raw_cstr: &[u8]) -> Result { #[cfg(botan_ffi_20230403)] unsafe fn cstr_to_str(raw_cstr: *const c_char) -> Result { - let cstr = CStr::from_ptr(raw_cstr); + let cstr = unsafe { CStr::from_ptr(raw_cstr) }; Ok(cstr.to_str().map_err(Error::conversion_error)?.to_owned()) } diff --git a/botan/src/x509_cert.rs b/botan/src/x509_cert.rs index 92333e0..296b949 100644 --- a/botan/src/x509_cert.rs +++ b/botan/src/x509_cert.rs @@ -1,4 +1,4 @@ -use crate::{utils::*, CRL}; +use crate::{CRL, utils::*}; use botan_sys::*; use crate::pubkey::Pubkey; diff --git a/botan/src/x509_crl.rs b/botan/src/x509_crl.rs index bbc46ad..c3617e5 100644 --- a/botan/src/x509_crl.rs +++ b/botan/src/x509_crl.rs @@ -1,6 +1,6 @@ -use crate::{utils::*, Pubkey}; #[cfg(botan_ffi_20260303)] -use crate::{Certificate, Privkey, RandomNumberGenerator, MPI}; +use crate::{Certificate, MPI, Privkey, RandomNumberGenerator}; +use crate::{Pubkey, utils::*}; use botan_sys::*; #[derive(Debug)] diff --git a/botan/tests/tests.rs b/botan/tests/tests.rs index 39bcf70..105423a 100644 --- a/botan/tests/tests.rs +++ b/botan/tests/tests.rs @@ -68,13 +68,17 @@ fn test_hash() -> Result<(), botan::Error> { let digest = hash.finish()?; - assert_eq!(botan::hex_encode(&digest)?, - "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7"); + assert_eq!( + botan::hex_encode(&digest)?, + "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7" + ); let digest_dup = hash_dup.finish()?; - assert_eq!(botan::hex_encode(&digest_dup)?, - "5D15BCEBB965FA77926C23471C96E3A326B363F5F105C3EF17CFD033B9734FA46556F81A26BB3044D2DDA50481325EF7"); + assert_eq!( + botan::hex_encode(&digest_dup)?, + "5D15BCEBB965FA77926C23471C96E3A326B363F5F105C3EF17CFD033B9734FA46556F81A26BB3044D2DDA50481325EF7" + ); let bad_hash = botan::HashFunction::new("BunnyHash9000"); @@ -104,8 +108,10 @@ fn test_mac() -> Result<(), botan::Error> { let r = mac.finish()?; - assert_eq!(botan::hex_encode(&r)?, - "88062608D3E6AD8A0AA2ACE014C8A86F0AA635D947AC9FEBE83EF4E55966144B2A5AB39DC13814B94E3AB6E101A34F27"); + assert_eq!( + botan::hex_encode(&r)?, + "88062608D3E6AD8A0AA2ACE014C8A86F0AA635D947AC9FEBE83EF4E55966144B2A5AB39DC13814B94E3AB6E101A34F27" + ); Ok(()) } @@ -204,8 +210,12 @@ fn test_incremental_cipher() -> Result<(), botan::Error> { let key = botan::hex_decode("00000000000000000000000000000000")?; let nonce = botan::hex_decode("0AAC82F3E53C2756034F7BD5827C9EDD")?; - let input = botan::hex_decode("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")?; - let output = botan::hex_decode("38C21B6430D9A3E4BC6749405765653AE91051E96CE0D076141DD7B515EC150FDB8A65EE988D206C9F64874664CDBF61257FFAE521B9A5EB5B35E3745F4232025B269A6CD7DCFE19153ECF7341CE2C6A6A87F95F2109841350DA3D24EEED4E4E32D2BED880737670FFE8ED76DB890FD72A0076300E50914984A777C9F2BC843977396C602B24E7A045F04D15CD2EAC01AD8808064CFE5A2DC1AE9FFFA4BF0A6F0C07668097DEEB9C5CA5EC1F9A52F96A403B73FEA2DBBF44473D355553EE7FB1B4D6630777DAF67804BE213089B9F78652CE970C582FD813F87FF0ECBACCE1CA46247E20D09F3E0B4EF6BFCD13244C6877F25E6646252CAD6EB7DBBA3476AAAC83BC3285FF70B50D6CDEDC8E5921944A")?; + let input = botan::hex_decode( + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + )?; + let output = botan::hex_decode( + "38C21B6430D9A3E4BC6749405765653AE91051E96CE0D076141DD7B515EC150FDB8A65EE988D206C9F64874664CDBF61257FFAE521B9A5EB5B35E3745F4232025B269A6CD7DCFE19153ECF7341CE2C6A6A87F95F2109841350DA3D24EEED4E4E32D2BED880737670FFE8ED76DB890FD72A0076300E50914984A777C9F2BC843977396C602B24E7A045F04D15CD2EAC01AD8808064CFE5A2DC1AE9FFFA4BF0A6F0C07668097DEEB9C5CA5EC1F9A52F96A403B73FEA2DBBF44473D355553EE7FB1B4D6630777DAF67804BE213089B9F78652CE970C582FD813F87FF0ECBACCE1CA46247E20D09F3E0B4EF6BFCD13244C6877F25E6646252CAD6EB7DBBA3476AAAC83BC3285FF70B50D6CDEDC8E5921944A", + )?; // encode let mut cipher = botan::Cipher::new("AES-128/GCM", botan::CipherDirection::Encrypt)?; @@ -228,8 +238,10 @@ fn test_incremental_cipher() -> Result<(), botan::Error> { enc_out.append(&mut res); } - assert_eq!(botan::hex_encode(&enc_out)?, - "38C21B6430D9A3E4BC6749405765653AE91051E96CE0D076141DD7B515EC150FDB8A65EE988D206C9F64874664CDBF61257FFAE521B9A5EB5B35E3745F4232025B269A6CD7DCFE19153ECF7341CE2C6A6A87F95F2109841350DA3D24EEED4E4E32D2BED880737670FFE8ED76DB890FD72A0076300E50914984A777C9F2BC843977396C602B24E7A045F04D15CD2EAC01AD8808064CFE5A2DC1AE9FFFA4BF0A6F0C07668097DEEB9C5CA5EC1F9A52F96A403B73FEA2DBBF44473D355553EE7FB1B4D6630777DAF67804BE213089B9F78652CE970C582FD813F87FF0ECBACCE1CA46247E20D09F3E0B4EF6BFCD13244C6877F25E6646252CAD6EB7DBBA3476AAAC83BC3285FF70B50D6CDEDC8E5921944A"); + assert_eq!( + botan::hex_encode(&enc_out)?, + "38C21B6430D9A3E4BC6749405765653AE91051E96CE0D076141DD7B515EC150FDB8A65EE988D206C9F64874664CDBF61257FFAE521B9A5EB5B35E3745F4232025B269A6CD7DCFE19153ECF7341CE2C6A6A87F95F2109841350DA3D24EEED4E4E32D2BED880737670FFE8ED76DB890FD72A0076300E50914984A777C9F2BC843977396C602B24E7A045F04D15CD2EAC01AD8808064CFE5A2DC1AE9FFFA4BF0A6F0C07668097DEEB9C5CA5EC1F9A52F96A403B73FEA2DBBF44473D355553EE7FB1B4D6630777DAF67804BE213089B9F78652CE970C582FD813F87FF0ECBACCE1CA46247E20D09F3E0B4EF6BFCD13244C6877F25E6646252CAD6EB7DBBA3476AAAC83BC3285FF70B50D6CDEDC8E5921944A" + ); // Try the same with the allocation-free interface. cipher.set_key(&key)?; @@ -271,8 +283,10 @@ fn test_incremental_cipher() -> Result<(), botan::Error> { remain.append(v.to_vec().as_mut()); let mut res = cipher.finish(&remain)?; dec_out.append(&mut res); - assert_eq!(botan::hex_encode(&dec_out)?, - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + assert_eq!( + botan::hex_encode(&dec_out)?, + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); // Try the same with the allocation-free interface. cipher.set_key(&key)?; @@ -306,7 +320,9 @@ fn test_chacha() -> Result<(), botan::Error> { let key = vec![0; 32]; - let expected = botan::hex_decode("76B8E0ADA0F13D90405D6AE55386BD28BDD219B8A08DED1AA836EFCC8B770DC7DA41597C5157488D7724E03FB8D84A376A43B8F41518A11CC387B669")?; + let expected = botan::hex_decode( + "76B8E0ADA0F13D90405D6AE55386BD28BDD219B8A08DED1AA836EFCC8B770DC7DA41597C5157488D7724E03FB8D84A376A43B8F41518A11CC387B669", + )?; cipher.set_key(&key)?; @@ -540,12 +556,16 @@ rWSdD+Aor4KcEQ== let crl = botan::CRL::new(&mut rng, &ca_cert, &ca_key, now, 600, None, None)?; assert!(crl.verify(&ca_pubkey)?); - assert!(sub1_cert - .verify_with_crl(&[], &[&ca_cert], None, None, None, &[&crl])? - .success()); - assert!(sub2_cert - .verify_with_crl(&[], &[&ca_cert], None, None, None, &[&crl])? - .success()); + assert!( + sub1_cert + .verify_with_crl(&[], &[&ca_cert], None, None, None, &[&crl])? + .success() + ); + assert!( + sub2_cert + .verify_with_crl(&[], &[&ca_cert], None, None, None, &[&crl])? + .success() + ); let to_revoke = botan::CRLEntry::new(&sub2_cert, botan::CRLReason::KeyCompromise)?; @@ -560,12 +580,16 @@ rWSdD+Aor4KcEQ== None, )?; assert!(crl.verify(&ca_pubkey)?); - assert!(sub1_cert - .verify_with_crl(&[], &[&ca_cert], None, None, None, &[&crl])? - .success()); - assert!(!sub2_cert - .verify_with_crl(&[], &[&ca_cert], None, None, None, &[&crl])? - .success()); + assert!( + sub1_cert + .verify_with_crl(&[], &[&ca_cert], None, None, None, &[&crl])? + .success() + ); + assert!( + !sub2_cert + .verify_with_crl(&[], &[&ca_cert], None, None, None, &[&crl])? + .success() + ); let revoked = crl.revoked()?; assert_eq!(revoked.len(), 1); @@ -585,7 +609,9 @@ rWSdD+Aor4KcEQ== #[test] fn test_certs() -> Result<(), botan::Error> { - let cert_bits = botan::hex_decode("3082035A30820305A003020102020101300C06082A8648CE3D04030105003050310B3009060355040613024445310D300B060355040A0C0462756E64310C300A060355040B0C03627369310D300B06035504051304343536373115301306035504030C0C637363612D6765726D616E79301E170D3037303731393135323731385A170D3238303131393135313830305A3050310B3009060355040613024445310D300B060355040A0C0462756E64310C300A060355040B0C03627369310D300B06035504051304343536373115301306035504030C0C637363612D6765726D616E79308201133081D406072A8648CE3D02013081C8020101302806072A8648CE3D0101021D00D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF303C041C68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43041C2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B0439040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD021D00D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F020101033A000401364A4B0F0102E9502AB9DC6855D90B065A6F5E5E48395F8309D57C11ABAFF21756607EF6757EC9886CA222D83CA04B1A99FA43C5A9BCE1A38201103082010C30360603551D11042F302D8118637363612D6765726D616E79406273692E62756E642E646586116661783A2B343932323839353832373232300E0603551D0F0101FF040403020106301D0603551D0E041604140096452DE588F966C4CCDF161DD1F3F5341B71E7301F0603551D230418301680140096452DE588F966C4CCDF161DD1F3F5341B71E730410603551D20043A30383036060904007F0007030101013029302706082B06010505070201161B687474703A2F2F7777772E6273692E62756E642E64652F6373636130120603551D130101FF040830060101FF020100302B0603551D1004243022800F32303037303731393135323731385A810F32303237313131393135313830305A300C06082A8648CE3D0403010500034100303E021D00C6B41E830217FD4C93B59E9E2B13734E09C182FA63FAEE4115A8EDD5021D00D27938DA01B8951A9064A1B696AEDF181B74968829C138F0EB2F623B")?; + let cert_bits = botan::hex_decode( + "3082035A30820305A003020102020101300C06082A8648CE3D04030105003050310B3009060355040613024445310D300B060355040A0C0462756E64310C300A060355040B0C03627369310D300B06035504051304343536373115301306035504030C0C637363612D6765726D616E79301E170D3037303731393135323731385A170D3238303131393135313830305A3050310B3009060355040613024445310D300B060355040A0C0462756E64310C300A060355040B0C03627369310D300B06035504051304343536373115301306035504030C0C637363612D6765726D616E79308201133081D406072A8648CE3D02013081C8020101302806072A8648CE3D0101021D00D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF303C041C68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43041C2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B0439040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD021D00D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F020101033A000401364A4B0F0102E9502AB9DC6855D90B065A6F5E5E48395F8309D57C11ABAFF21756607EF6757EC9886CA222D83CA04B1A99FA43C5A9BCE1A38201103082010C30360603551D11042F302D8118637363612D6765726D616E79406273692E62756E642E646586116661783A2B343932323839353832373232300E0603551D0F0101FF040403020106301D0603551D0E041604140096452DE588F966C4CCDF161DD1F3F5341B71E7301F0603551D230418301680140096452DE588F966C4CCDF161DD1F3F5341B71E730410603551D20043A30383036060904007F0007030101013029302706082B06010505070201161B687474703A2F2F7777772E6273692E62756E642E64652F6373636130120603551D130101FF040830060101FF020100302B0603551D1004243022800F32303037303731393135323731385A810F32303237313131393135313830305A300C06082A8648CE3D0403010500034100303E021D00C6B41E830217FD4C93B59E9E2B13734E09C182FA63FAEE4115A8EDD5021D00D27938DA01B8951A9064A1B696AEDF181B74968829C138F0EB2F623B", + )?; let cert = botan::Certificate::load(&cert_bits)?; diff --git a/botan/tests/wycheproof.rs b/botan/tests/wycheproof.rs index def67ec..1deba31 100644 --- a/botan/tests/wycheproof.rs +++ b/botan/tests/wycheproof.rs @@ -515,7 +515,7 @@ fn wycheproof_mac_with_nonce_tests() -> Result<(), botan::Error> { #[test] fn wycheproof_primality_tests() -> Result<(), botan::Error> { - use wycheproof::{primality::*, TestResult}; + use wycheproof::{TestResult, primality::*}; let mut rng = botan::RandomNumberGenerator::new_system()?; diff --git a/clippy.toml b/clippy.toml index 22fd4be..4972822 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -msrv = "1.64.0" +msrv = "1.85.0"