From 1c046d08c138b367ad789a3d7ea1b7e32b166784 Mon Sep 17 00:00:00 2001 From: Colin D Murphy Date: Tue, 18 Feb 2025 13:55:02 -0500 Subject: [PATCH] feat: Wasm32 wasi 0.41.0 (#888) feat: Add wasi compatibility. - wasip2 will require +nightly until https://github.com/rust-lang/rust/issues/130323 is resolved and/or std::os::wasip2 is available in stable. - Support was added to rustix for version 0.38.39 https://github.com/bytecodealliance/rustix/pull/1205 - Support was added to tempfile for version 3.14 https://github.com/Stebalien/tempfile/pull/305 - Tempfile is not supported in wasip1 - Working remote manifest fetch. Tests passing with WASI. CARGO_TARGET_WASM32_WASIP2_RUNNER="wasmtime -S common -S http --dir ." --- .github/workflows/ci.yml | 50 +++++ .gitignore | 1 + Cargo.lock | 138 ++++++------- Makefile | 6 + internal/crypto/Cargo.toml | 22 +- internal/crypto/src/tests/base64.rs | 12 +- .../src/tests/cose/certificate_profile.rs | 12 +- .../tests/cose/certificate_trust_policy.rs | 98 +++++++-- internal/crypto/src/tests/hash.rs | 12 +- internal/crypto/src/tests/internal/time.rs | 7 +- internal/crypto/src/tests/mod.rs | 2 +- internal/crypto/src/tests/ocsp.rs | 12 +- .../src/tests/raw_signature/async_signers.rs | 11 +- .../tests/raw_signature/async_validators.rs | 31 ++- .../raw_signature/rust_native/signers.rs | 28 ++- .../raw_signature/rust_native/validators.rs | 89 +++++++-- .../crypto/src/tests/raw_signature/signers.rs | 25 ++- .../src/tests/raw_signature/validators.rs | 95 +++++++-- internal/crypto/src/tests/signing_alg.rs | 17 +- internal/crypto/src/time_stamp/verify.rs | 16 +- make_test_images/Cargo.toml | 2 +- sdk/Cargo.toml | 42 ++-- sdk/examples/data_hash.rs | 6 +- sdk/src/asset_handlers/bmff_io.rs | 32 ++- sdk/src/asset_handlers/c2pa_io.rs | 4 +- sdk/src/asset_handlers/jpeg_io.rs | 26 ++- sdk/src/asset_handlers/mp3_io.rs | 16 +- sdk/src/asset_handlers/pdf.rs | 151 ++++++++++---- sdk/src/asset_handlers/png_io.rs | 19 +- sdk/src/asset_handlers/riff_io.rs | 25 +-- sdk/src/asset_handlers/svg_io.rs | 27 +-- sdk/src/asset_handlers/tiff_io.rs | 28 +-- sdk/src/builder.rs | 23 ++- sdk/src/cose_sign.rs | 9 +- sdk/src/error.rs | 6 +- sdk/src/ingredient.rs | 6 +- sdk/src/manifest.rs | 104 +++++++--- sdk/src/manifest_store.rs | 25 ++- sdk/src/reader.rs | 8 +- sdk/src/resource_store.rs | 5 +- sdk/src/settings.rs | 6 +- sdk/src/store.rs | 189 +++++++++++++----- sdk/src/utils/io_utils.rs | 36 +++- sdk/src/utils/test.rs | 110 +--------- sdk/tests/common/mod.rs | 11 + sdk/tests/integration.rs | 77 ++++++- sdk/tests/test_builder.rs | 6 +- sdk/tests/v2_api_integration.rs | 12 +- 48 files changed, 1103 insertions(+), 592 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b993c518f..05436cd24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -287,6 +287,56 @@ jobs: run: wasm-pack test --chrome --headless working-directory: ./cawg_identity + tests-wasi: + name: Unit tests (WASI) + if: | + github.event_name != 'pull_request' || + github.event.pull_request.author_association == 'COLLABORATOR' || + github.event.pull_request.author_association == 'MEMBER' || + github.event.pull_request.user.login == 'dependabot[bot]' || + contains(github.event.pull_request.labels.*.name, 'safe to test') + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # nightly required for testing until this issue is resolved: + # wasip2 target should not conditionally feature gate stdlib APIs rust-lang/rust#130323 https://github.com/rust-lang/rust/issues/130323 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@nightly + + - name: Install wasmtime + run: | + curl https://wasmtime.dev/install.sh -sSf | bash + echo "$HOME/.wasmtime/bin" >> $GITHUB_PATH + + - name: Install WASI SDK + run: | + if [ "${RUNNER_ARCH}" = "X64" ]; then + ARCH="x86_64"; + else + ARCH="${RUNNER_ARCH}"; + fi + wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-${ARCH}-${RUNNER_OS}.tar.gz + tar xvf wasi-sdk-25.0-${ARCH}-${RUNNER_OS}.tar.gz + mv $(echo wasi-sdk-25.0-${ARCH}-${RUNNER_OS} | tr '[:upper:]' '[:lower:]') /opt/wasi-sdk + + - name: Add wasm32-wasip2 target + run: rustup target add --toolchain nightly wasm32-wasip2 + + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v2 + + - name: Run WASI tests (c2pa-rs) + env: + CARGO_TARGET_WASM32_WASIP2_RUNNER: "wasmtime -S cli -S http --dir ." + CC: /opt/wasi-sdk/bin/clang + WASI_SDK_PATH: /opt/wasi-sdk + RUST_MIN_STACK: 16777216 + run: cargo +nightly test --target wasm32-wasip2 -p c2pa -p c2pa-crypto --all-features + test-direct-minimal-versions: name: Unit tests with minimum versions of direct dependencies if: | diff --git a/.gitignore b/.gitignore index a43edfdfa..035358b14 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /target/ **/*.rs.bk +**/*.tmp* .DS_Store .idea diff --git a/Cargo.lock b/Cargo.lock index 76f2dd6b2..7d7e0e9d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -734,7 +734,7 @@ dependencies = [ "coset", "ed25519-dalek", "extfmt", - "getrandom 0.2.15", + "getrandom", "glob", "hex", "hex-literal", @@ -750,7 +750,7 @@ dependencies = [ "memchr", "mockall", "mp4", - "pem 3.0.4", + "pem", "png_pong", "quick-xml", "rand", @@ -781,10 +781,12 @@ dependencies = [ "ureq", "url", "uuid", + "wasi 0.14.1+wasi-0.2.3", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", "web-sys", + "wstd", "x509-certificate", "x509-parser", "zip", @@ -810,7 +812,7 @@ dependencies = [ "der", "ecdsa", "ed25519-dalek", - "getrandom 0.2.15", + "getrandom", "hex", "js-sys", "nom", @@ -825,6 +827,7 @@ dependencies = [ "rasn", "rasn-ocsp", "rasn-pkix", + "ring", "rsa", "schemars", "serde", @@ -840,6 +843,7 @@ dependencies = [ "wasm-bindgen-test", "web-sys", "web-time", + "wstd", "x509-certificate", "x509-parser", ] @@ -864,7 +868,7 @@ dependencies = [ "log", "mockall", "openssl", - "pem 3.0.4", + "pem", "predicates", "reqwest", "serde", @@ -1102,7 +1106,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.15", + "getrandom", "once_cell", "tiny-keccak", ] @@ -1815,18 +1819,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "getrandom" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets", -] - [[package]] name = "gimli" version = "0.31.1" @@ -2558,7 +2550,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.9.8", + "spin", ] [[package]] @@ -3082,16 +3074,6 @@ dependencies = [ "utf8-decode", ] -[[package]] -name = "pem" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a" -dependencies = [ - "base64 0.21.7", - "serde", -] - [[package]] name = "pem" version = "3.0.4" @@ -3427,9 +3409,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" dependencies = [ "bytes", - "getrandom 0.2.15", + "getrandom", "rand", - "ring 0.17.9", + "ring", "rustc-hash", "rustls", "rustls-pki-types", @@ -3496,7 +3478,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom", ] [[package]] @@ -3634,7 +3616,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.15", + "getrandom", "libredox", "thiserror 1.0.69", ] @@ -3734,21 +3716,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c601484456988d75017d86700d3743b949c21cdc7399f940c75e34680d185c5" -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - [[package]] name = "ring" version = "0.17.9" @@ -3757,9 +3724,9 @@ checksum = "e75ec5e92c4d8aede845126adc388046234541629e76029599ed35a003c7ed24" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom", "libc", - "untrusted 0.9.0", + "untrusted", "windows-sys 0.52.0", ] @@ -3857,7 +3824,7 @@ checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" dependencies = [ "log", "once_cell", - "ring 0.17.9", + "ring", "rustls-pki-types", "rustls-webpki", "subtle", @@ -3888,9 +3855,9 @@ version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ - "ring 0.17.9", + "ring", "rustls-pki-types", - "untrusted 0.9.0", + "untrusted", ] [[package]] @@ -4251,12 +4218,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -4405,13 +4366,13 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.16.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand", - "getrandom 0.3.1", + "getrandom", "once_cell", "rustix", "windows-sys 0.59.0", @@ -4734,12 +4695,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" @@ -4799,12 +4754,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.13.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced87ca4be083373936a67f8de945faa23b6b42384bd5b64434850802c6dccd0" +checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4" dependencies = [ - "getrandom 0.3.1", - "js-sys", + "getrandom", "serde", "wasm-bindgen", ] @@ -4863,9 +4817,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.1+wasi-0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "ad7df608df60a1c33e247881838b0f809512086e3e3bb1c18323b77eeb1f844e" dependencies = [ "wit-bindgen-rt", ] @@ -5163,9 +5117,9 @@ dependencies = [ [[package]] name = "wit-bindgen-rt" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags 2.8.0", ] @@ -5182,6 +5136,31 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +[[package]] +name = "wstd" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26293c0587d2203a141282311221f9ba0048425a04b21d9fcff8fc62fc8ecd75" +dependencies = [ + "futures-core", + "http 1.2.0", + "itoa", + "pin-project-lite", + "slab", + "wasi 0.14.1+wasi-0.2.3", + "wstd-macro", +] + +[[package]] +name = "wstd-macro" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75a8316f91fc3e508b03fdc979dec4ceeddb29744fc1c2c2ed825e00159f96f9" +dependencies = [ + "quote", + "syn 2.0.98", +] + [[package]] name = "wyz" version = "0.5.1" @@ -5193,20 +5172,21 @@ dependencies = [ [[package]] name = "x509-certificate" -version = "0.21.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5d27c90840e84503cf44364de338794d5d5680bdd1da6272d13f80b0769ee0" +checksum = "66534846dec7a11d7c50a74b7cdb208b9a581cad890b7866430d438455847c85" dependencies = [ "bcder", "bytes", "chrono", "der", "hex", - "pem 2.0.1", - "ring 0.16.20", + "pem", + "ring", "signature", "spki", "thiserror 1.0.69", + "zeroize", ] [[package]] diff --git a/Makefile b/Makefile index e3f8b0a81..385dd97bc 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,12 @@ test-wasm: test-wasm-web: cd sdk && wasm-pack test --chrome --headless -- --features="serialize_thumbnails" +# WASI testing requires the WASI SDK https://github.com/WebAssembly/wasi-sdk installed in /opt, +# wasmtime, and the target wasm32-wasip2 on the nightly toolchain +test-wasi: + CC=/opt/wasi-sdk/bin/clang CARGO_TARGET_WASM32_WASIP2_RUNNER="wasmtime -S cli -S http --dir ." cargo +nightly test --target wasm32-wasip2 -p c2pa -p c2pa-crypto --all-features + rm -r sdk/Users + # Full local validation, build and test all features including wasm # Run this before pushing a PR to pre-validate test: check-format check-docs clippy test-local test-wasm-web diff --git a/internal/crypto/Cargo.toml b/internal/crypto/Cargo.toml index 2d404c966..ae75d2639 100644 --- a/internal/crypto/Cargo.toml +++ b/internal/crypto/Cargo.toml @@ -78,7 +78,7 @@ sha2 = "0.10.6" spki = { version = "0.7.3", optional = true } thiserror = "2.0.8" web-time = "1.1" -x509-certificate = "0.21.0" +x509-certificate = "0.23.1" x509-parser = "0.16.0" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] @@ -89,15 +89,15 @@ url = "2.5.3" [package.metadata.cargo-udeps.ignore] normal = ["openssl"] # TEMPORARY: Remove after openssl transition complete. -[dependencies.chrono] +[target.'cfg(all(target_arch = "wasm32", not(target_os = "wasi")))'.dependencies.chrono] version = "0.4.39" default-features = false features = ["wasmbind"] -[target.'cfg(not(target_arch = "wasm32"))'.dependencies.chrono] +[target.'cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))'.dependencies.chrono] version = "0.4.39" default-features = false -features = ["now", "wasmbind"] +features = ["now"] [target.'cfg(target_arch = "wasm32")'.dependencies] async-trait = "0.1.77" @@ -108,6 +108,11 @@ num-bigint-dig = "0.8.4" pkcs1 = "0.7.5" rsa = { version = "0.9.7", features = ["pem", "sha2"] } spki = "0.7.3" + +[target.'cfg(all(target_arch = "wasm32", not(target_os = "wasi")))'.dependencies] +getrandom = { version = "0.2.7", features = ["js"] } +js-sys = "0.3.58" +ring = { version = "0.17", features = ["wasm32_unknown_unknown_js"]} wasm-bindgen = "0.2.83" wasm-bindgen-futures = "0.4.31" web-sys = { version = "0.3.58", features = [ @@ -119,10 +124,6 @@ web-sys = { version = "0.3.58", features = [ "WorkerGlobalScope", ] } -[target.'cfg(all(target_arch = "wasm32", not(target_os = "wasi")))'.dependencies] -getrandom = { version = "0.2.7", features = ["js"] } -js-sys = "0.3.58" - [dev-dependencies] const-oid = "0.9.6" der = "0.7.9" @@ -135,5 +136,8 @@ spki = "0.7.3" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] actix = "0.13.1" -[target.'cfg(target_arch = "wasm32")'.dev-dependencies] +[target.'cfg(all(target_arch = "wasm32", not(target_os = "wasi")))'.dev-dependencies] wasm-bindgen-test = "0.3.31" + +[target.'cfg(target_os = "wasi")'.dev-dependencies] +wstd = "0.5" diff --git a/internal/crypto/src/tests/base64.rs b/internal/crypto/src/tests/base64.rs index 1ef58fce5..4dd937890 100644 --- a/internal/crypto/src/tests/base64.rs +++ b/internal/crypto/src/tests/base64.rs @@ -11,19 +11,25 @@ // specific language governing permissions and limitations under // each license. -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use crate::base64; #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn encode() { assert_eq!(base64::encode(b"Hello, world"), "SGVsbG8sIHdvcmxk"); } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn decode() { assert_eq!( base64::decode("SGVsbG8sIHdvcmxk"), diff --git a/internal/crypto/src/tests/cose/certificate_profile.rs b/internal/crypto/src/tests/cose/certificate_profile.rs index 9af841ad8..094821955 100644 --- a/internal/crypto/src/tests/cose/certificate_profile.rs +++ b/internal/crypto/src/tests/cose/certificate_profile.rs @@ -14,14 +14,17 @@ use c2pa_status_tracker::{ validation_codes::SIGNING_CREDENTIAL_EXPIRED, DetailedStatusTracker, StatusTracker, }; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use x509_parser::pem::Pem; use crate::cose::{check_certificate_profile, CertificateTrustPolicy}; #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn expired_cert() { let ctp = CertificateTrustPolicy::default(); let mut validation_log = DetailedStatusTracker::default(); @@ -41,7 +44,10 @@ fn expired_cert() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn cert_algorithms() { let ctp = CertificateTrustPolicy::default(); diff --git a/internal/crypto/src/tests/cose/certificate_trust_policy.rs b/internal/crypto/src/tests/cose/certificate_trust_policy.rs index d2ec2b860..9daad1f60 100644 --- a/internal/crypto/src/tests/cose/certificate_trust_policy.rs +++ b/internal/crypto/src/tests/cose/certificate_trust_policy.rs @@ -12,7 +12,7 @@ // each license. use asn1_rs::{oid, Oid}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use x509_parser::{extensions::ExtendedKeyUsage, pem::Pem}; @@ -22,14 +22,20 @@ use crate::{ }; #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn impl_debug() { let ctp = CertificateTrustPolicy::new(); let _ = format!("{ctp:#?}"); } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn new() { let ctp = CertificateTrustPolicy::new(); @@ -52,7 +58,10 @@ fn new() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn default() { let ctp = CertificateTrustPolicy::default(); @@ -78,7 +87,10 @@ fn default() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn clear() { let mut ctp = CertificateTrustPolicy::default(); ctp.clear(); @@ -102,7 +114,10 @@ fn clear() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn add_valid_ekus_err_bad_utf8() { let mut ctp = CertificateTrustPolicy::new(); ctp.add_valid_ekus(&[128, 0]); @@ -126,28 +141,40 @@ fn add_valid_ekus_err_bad_utf8() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn add_trust_anchors_err_bad_pem() { let mut ctp = CertificateTrustPolicy::new(); assert!(ctp.add_trust_anchors(BAD_PEM.as_bytes()).is_err()); } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn add_end_entity_credentials_err_bad_pem() { let mut ctp = CertificateTrustPolicy::new(); assert!(ctp.add_end_entity_credentials(BAD_PEM.as_bytes()).is_err()); } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn err_to_string() { let ice = InvalidCertificateError("foo".to_string()); assert_eq!(ice.to_string(), "Unable to parse certificate list: foo"); } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn err_debug() { let ice = InvalidCertificateError("foo".to_string()); assert_eq!( @@ -237,16 +264,22 @@ fn test_trust_store() { let ps256 = test_signer(SigningAlg::Ps256); let ps384 = test_signer(SigningAlg::Ps384); let ps512 = test_signer(SigningAlg::Ps512); + #[cfg(not(target_arch = "wasm32"))] let es256 = test_signer(SigningAlg::Es256); + #[cfg(not(target_arch = "wasm32"))] let es384 = test_signer(SigningAlg::Es384); + #[cfg(not(target_arch = "wasm32"))] let es512 = test_signer(SigningAlg::Es512); let ed25519 = test_signer(SigningAlg::Ed25519); let ps256_certs = ps256.cert_chain().unwrap(); let ps384_certs = ps384.cert_chain().unwrap(); let ps512_certs = ps512.cert_chain().unwrap(); + #[cfg(not(target_arch = "wasm32"))] let es256_certs = es256.cert_chain().unwrap(); + #[cfg(not(target_arch = "wasm32"))] let es384_certs = es384.cert_chain().unwrap(); + #[cfg(not(target_arch = "wasm32"))] let es512_certs = es512.cert_chain().unwrap(); let ed25519_certs = ed25519.cert_chain().unwrap(); @@ -256,10 +289,13 @@ fn test_trust_store() { .unwrap(); ctp.check_certificate_trust(&ps512_certs[1..], &ps512_certs[0], None) .unwrap(); + #[cfg(not(target_arch = "wasm32"))] ctp.check_certificate_trust(&es256_certs[1..], &es256_certs[0], None) .unwrap(); + #[cfg(not(target_arch = "wasm32"))] ctp.check_certificate_trust(&es384_certs[1..], &es384_certs[0], None) .unwrap(); + #[cfg(not(target_arch = "wasm32"))] ctp.check_certificate_trust(&es512_certs[1..], &es512_certs[0], None) .unwrap(); ctp.check_certificate_trust(&ed25519_certs[1..], &ed25519_certs[0], None) @@ -267,7 +303,11 @@ fn test_trust_store() { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn test_trust_store_async() { let ctp = CertificateTrustPolicy::default(); @@ -309,16 +349,22 @@ fn test_broken_trust_chain() { let ps256 = test_signer(SigningAlg::Ps256); let ps384 = test_signer(SigningAlg::Ps384); let ps512 = test_signer(SigningAlg::Ps512); + #[cfg(not(target_arch = "wasm32"))] let es256 = test_signer(SigningAlg::Es256); + #[cfg(not(target_arch = "wasm32"))] let es384 = test_signer(SigningAlg::Es384); + #[cfg(not(target_arch = "wasm32"))] let es512 = test_signer(SigningAlg::Es512); let ed25519 = test_signer(SigningAlg::Ed25519); let ps256_certs = ps256.cert_chain().unwrap(); let ps384_certs = ps384.cert_chain().unwrap(); let ps512_certs = ps512.cert_chain().unwrap(); + #[cfg(not(target_arch = "wasm32"))] let es256_certs = es256.cert_chain().unwrap(); + #[cfg(not(target_arch = "wasm32"))] let es384_certs = es384.cert_chain().unwrap(); + #[cfg(not(target_arch = "wasm32"))] let es512_certs = es512.cert_chain().unwrap(); let ed25519_certs = ed25519.cert_chain().unwrap(); @@ -347,18 +393,21 @@ fn test_broken_trust_chain() { CertificateTrustError::CertificateNotTrusted ); + #[cfg(not(target_arch = "wasm32"))] assert_eq!( ctp.check_certificate_trust(&es256_certs[2..], &es256_certs[0], None) .unwrap_err(), CertificateTrustError::CertificateNotTrusted ); + #[cfg(not(target_arch = "wasm32"))] assert_eq!( ctp.check_certificate_trust(&es384_certs[2..], &es384_certs[0], None) .unwrap_err(), CertificateTrustError::CertificateNotTrusted ); + #[cfg(not(target_arch = "wasm32"))] assert_eq!( ctp.check_certificate_trust(&es512_certs[2..], &es512_certs[0], None) .unwrap_err(), @@ -373,7 +422,11 @@ fn test_broken_trust_chain() { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn test_broken_trust_chain_async() { let ctp = CertificateTrustPolicy::default(); @@ -465,16 +518,22 @@ fn test_allowed_list() { let ps256 = test_signer(SigningAlg::Ps256); let ps384 = test_signer(SigningAlg::Ps384); let ps512 = test_signer(SigningAlg::Ps512); + #[cfg(not(target_arch = "wasm32"))] let es256 = test_signer(SigningAlg::Es256); + #[cfg(not(target_arch = "wasm32"))] let es384 = test_signer(SigningAlg::Es384); + #[cfg(not(target_arch = "wasm32"))] let es512 = test_signer(SigningAlg::Es512); let ed25519 = test_signer(SigningAlg::Ed25519); let ps256_certs = ps256.cert_chain().unwrap(); let ps384_certs = ps384.cert_chain().unwrap(); let ps512_certs = ps512.cert_chain().unwrap(); + #[cfg(not(target_arch = "wasm32"))] let es256_certs = es256.cert_chain().unwrap(); + #[cfg(not(target_arch = "wasm32"))] let es384_certs = es384.cert_chain().unwrap(); + #[cfg(not(target_arch = "wasm32"))] let es512_certs = es512.cert_chain().unwrap(); let ed25519_certs = ed25519.cert_chain().unwrap(); @@ -484,10 +543,13 @@ fn test_allowed_list() { .unwrap(); ctp.check_certificate_trust(&ps512_certs[1..], &ps512_certs[0], None) .unwrap(); + #[cfg(not(target_arch = "wasm32"))] ctp.check_certificate_trust(&es256_certs[1..], &es256_certs[0], None) .unwrap(); + #[cfg(not(target_arch = "wasm32"))] ctp.check_certificate_trust(&es384_certs[1..], &es384_certs[0], None) .unwrap(); + #[cfg(not(target_arch = "wasm32"))] ctp.check_certificate_trust(&es512_certs[1..], &es512_certs[0], None) .unwrap(); ctp.check_certificate_trust(&ed25519_certs[1..], &ed25519_certs[0], None) @@ -495,7 +557,11 @@ fn test_allowed_list() { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn test_allowed_list_async() { let mut ctp = CertificateTrustPolicy::new(); @@ -579,7 +645,11 @@ fn test_allowed_list_hashes() { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn test_allowed_list_hashes_async() { let mut ctp = CertificateTrustPolicy::new(); diff --git a/internal/crypto/src/tests/hash.rs b/internal/crypto/src/tests/hash.rs index e80ff1b9d..47c051279 100644 --- a/internal/crypto/src/tests/hash.rs +++ b/internal/crypto/src/tests/hash.rs @@ -11,13 +11,16 @@ // specific language governing permissions and limitations under // each license. -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use crate::hash::{sha1, sha256}; #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn test_sha1() { let hash = sha1(b"test message"); assert_eq!( @@ -30,7 +33,10 @@ fn test_sha1() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn test_sha256() { let hash = sha256(b"test message"); assert_eq!( diff --git a/internal/crypto/src/tests/internal/time.rs b/internal/crypto/src/tests/internal/time.rs index c6f3eaba7..21f578529 100644 --- a/internal/crypto/src/tests/internal/time.rs +++ b/internal/crypto/src/tests/internal/time.rs @@ -11,13 +11,16 @@ // specific language governing permissions and limitations under // each license. -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use crate::internal::time; #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn now() { let time_now = time::utc_now(); let unix_ts = time_now.timestamp(); diff --git a/internal/crypto/src/tests/mod.rs b/internal/crypto/src/tests/mod.rs index 4b3430e67..93679da97 100644 --- a/internal/crypto/src/tests/mod.rs +++ b/internal/crypto/src/tests/mod.rs @@ -18,7 +18,7 @@ #![allow(clippy::panic)] #![allow(clippy::unwrap_used)] -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); mod base64; diff --git a/internal/crypto/src/tests/ocsp.rs b/internal/crypto/src/tests/ocsp.rs index 2167161cd..7edc6bbf5 100644 --- a/internal/crypto/src/tests/ocsp.rs +++ b/internal/crypto/src/tests/ocsp.rs @@ -13,13 +13,16 @@ use c2pa_status_tracker::DetailedStatusTracker; use chrono::{TimeZone, Utc}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use crate::ocsp::OcspResponse; #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn good() { let rsp_data = include_bytes!("fixtures/ocsp/good.data"); @@ -35,7 +38,10 @@ fn good() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn revoked() { let rsp_data = include_bytes!("fixtures/ocsp/revoked.data"); diff --git a/internal/crypto/src/tests/raw_signature/async_signers.rs b/internal/crypto/src/tests/raw_signature/async_signers.rs index f165cd0ef..5bc4c7b20 100644 --- a/internal/crypto/src/tests/raw_signature/async_signers.rs +++ b/internal/crypto/src/tests/raw_signature/async_signers.rs @@ -13,7 +13,7 @@ #![allow(unused)] // test fns appear unused on WASM -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use crate::raw_signature::{ @@ -99,7 +99,11 @@ async fn es512() { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn ed25519() { let cert_chain = include_bytes!("../fixtures/raw_signature/ed25519.pub"); let private_key = include_bytes!("../fixtures/raw_signature/ed25519.priv"); @@ -126,6 +130,7 @@ async fn ed25519() { #[cfg_attr(not(target_arch = "wasm32"), actix::test)] // #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn ps256() { let cert_chain = include_bytes!("../fixtures/raw_signature/ps256.pub"); let private_key = include_bytes!("../fixtures/raw_signature/ps256.priv"); @@ -152,6 +157,7 @@ async fn ps256() { #[cfg_attr(not(target_arch = "wasm32"), actix::test)] // #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn ps384() { let cert_chain = include_bytes!("../fixtures/raw_signature/ps384.pub"); let private_key = include_bytes!("../fixtures/raw_signature/ps384.priv"); @@ -178,6 +184,7 @@ async fn ps384() { #[cfg_attr(not(target_arch = "wasm32"), actix::test)] // #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn ps512() { let cert_chain = include_bytes!("../fixtures/raw_signature/ps512.pub"); let private_key = include_bytes!("../fixtures/raw_signature/ps512.priv"); diff --git a/internal/crypto/src/tests/raw_signature/async_validators.rs b/internal/crypto/src/tests/raw_signature/async_validators.rs index 032a2dccc..a3359f7e8 100644 --- a/internal/crypto/src/tests/raw_signature/async_validators.rs +++ b/internal/crypto/src/tests/raw_signature/async_validators.rs @@ -11,6 +11,7 @@ // specific language governing permissions and limitations under // each license. +#[cfg(not(target_os = "wasi"))] use wasm_bindgen_test::wasm_bindgen_test; use crate::raw_signature::{ @@ -19,7 +20,11 @@ use crate::raw_signature::{ const SAMPLE_DATA: &[u8] = b"some sample content to sign"; -#[wasm_bindgen_test] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn es256() { let signature = include_bytes!("../fixtures/raw_signature/es256.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/es256.pub_key"); @@ -32,7 +37,11 @@ async fn es256() { .unwrap(); } -#[wasm_bindgen_test] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn es256_bad_signature() { let mut signature = include_bytes!("../fixtures/raw_signature/es256.raw_sig").to_vec(); assert_ne!(signature[10], 10); @@ -51,7 +60,11 @@ async fn es256_bad_signature() { ); } -#[wasm_bindgen_test] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn es256_bad_data() { let signature = include_bytes!("../fixtures/raw_signature/es256.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/es256.pub_key"); @@ -70,7 +83,11 @@ async fn es256_bad_data() { ); } -#[wasm_bindgen_test] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn es384() { let signature = include_bytes!("../fixtures/raw_signature/es384.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/es384.pub_key"); @@ -83,7 +100,11 @@ async fn es384() { .unwrap(); } -#[wasm_bindgen_test] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] +#[cfg_attr(target_os = "wasi", wstd::test)] async fn es512() { let signature = include_bytes!("../fixtures/raw_signature/es512.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/es512.pub_key"); diff --git a/internal/crypto/src/tests/raw_signature/rust_native/signers.rs b/internal/crypto/src/tests/raw_signature/rust_native/signers.rs index 1ce036e46..fbe06bbeb 100644 --- a/internal/crypto/src/tests/raw_signature/rust_native/signers.rs +++ b/internal/crypto/src/tests/raw_signature/rust_native/signers.rs @@ -11,14 +11,14 @@ // specific language governing permissions and limitations under // each license. -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use crate::raw_signature::{rust_native, SigningAlg}; /* Not implemented in rust_native yet. #[test] -// #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +// #[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), wasm_bindgen_test)] fn es256() { let cert_chain = include_bytes!("../../fixtures/raw_signature/es256.pub"); let private_key = include_bytes!("../../fixtures/raw_signature/es256.priv"); @@ -40,7 +40,7 @@ fn es256() { } #[test] -// #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +// #[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), wasm_bindgen_test)] fn es384() { let cert_chain = include_bytes!("../../fixtures/raw_signature/es384.pub"); let private_key = include_bytes!("../../fixtures/raw_signature/es384.priv"); @@ -62,7 +62,7 @@ fn es384() { } #[test] -// #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +// #[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), wasm_bindgen_test)] fn es512() { let cert_chain = include_bytes!("../../fixtures/raw_signature/es512.pub"); let private_key = include_bytes!("../../fixtures/raw_signature/es512.priv"); @@ -85,7 +85,10 @@ fn es512() { */ #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ed25519() { let cert_chain = include_bytes!("../../fixtures/raw_signature/ed25519.pub"); let private_key = include_bytes!("../../fixtures/raw_signature/ed25519.priv"); @@ -112,7 +115,10 @@ fn ed25519() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps256() { let cert_chain = include_bytes!("../../fixtures/raw_signature/ps256.pub"); let private_key = include_bytes!("../../fixtures/raw_signature/ps256.priv"); @@ -138,7 +144,10 @@ fn ps256() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps384() { let cert_chain = include_bytes!("../../fixtures/raw_signature/ps384.pub"); let private_key = include_bytes!("../../fixtures/raw_signature/ps384.priv"); @@ -164,7 +173,10 @@ fn ps384() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps512() { let cert_chain = include_bytes!("../../fixtures/raw_signature/ps512.pub"); let private_key = include_bytes!("../../fixtures/raw_signature/ps512.priv"); diff --git a/internal/crypto/src/tests/raw_signature/rust_native/validators.rs b/internal/crypto/src/tests/raw_signature/rust_native/validators.rs index f9ac4be4c..a9161f629 100644 --- a/internal/crypto/src/tests/raw_signature/rust_native/validators.rs +++ b/internal/crypto/src/tests/raw_signature/rust_native/validators.rs @@ -13,7 +13,7 @@ use bcder::Oid; use rasn::types::OctetString; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use crate::raw_signature::{rust_native, RawSignatureValidationError, SigningAlg}; @@ -21,7 +21,10 @@ use crate::raw_signature::{rust_native, RawSignatureValidationError, SigningAlg} const SAMPLE_DATA: &[u8] = b"some sample content to sign"; #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn es256() { let signature = include_bytes!("../../fixtures/raw_signature/es256.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/es256.pub_key"); @@ -32,7 +35,10 @@ fn es256() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn es256_bad_signature() { let mut signature = include_bytes!("../../fixtures/raw_signature/es256.raw_sig").to_vec(); assert_ne!(signature[10], 10); @@ -51,7 +57,10 @@ fn es256_bad_signature() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn es256_bad_data() { let signature = include_bytes!("../../fixtures/raw_signature/es256.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/es256.pub_key"); @@ -68,7 +77,10 @@ fn es256_bad_data() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn es384() { let signature = include_bytes!("../../fixtures/raw_signature/es384.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/es384.pub_key"); @@ -79,7 +91,10 @@ fn es384() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn es512() { let signature = include_bytes!("../../fixtures/raw_signature/es512.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/es512.pub_key"); @@ -90,7 +105,10 @@ fn es512() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ed25519() { let signature = include_bytes!("../../fixtures/raw_signature/ed25519.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/ed25519.pub_key"); @@ -102,7 +120,10 @@ fn ed25519() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ed25519_bad_data() { let signature = include_bytes!("../../fixtures/raw_signature/ed25519.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/ed25519.pub_key"); @@ -121,7 +142,10 @@ fn ed25519_bad_data() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps256() { let signature = include_bytes!("../../fixtures/raw_signature/ps256.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/ps256.pub_key"); @@ -132,7 +156,10 @@ fn ps256() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps256_bad_signature() { let mut signature = include_bytes!("../../fixtures/raw_signature/ps256.raw_sig").to_vec(); assert_ne!(signature[10], 10); @@ -151,7 +178,10 @@ fn ps256_bad_signature() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps256_bad_data() { let signature = include_bytes!("../../fixtures/raw_signature/ps256.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/ps256.pub_key"); @@ -168,7 +198,10 @@ fn ps256_bad_data() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps384() { let signature = include_bytes!("../../fixtures/raw_signature/ps384.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/ps384.pub_key"); @@ -179,7 +212,10 @@ fn ps384() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps512() { let signature = include_bytes!("../../fixtures/raw_signature/ps512.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/ps512.pub_key"); @@ -202,7 +238,10 @@ const SHA384_OID: Oid = bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 10 const SHA512_OID: Oid = bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 101, 3, 4, 2, 3])); #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn legacy_rs256() { let signature = include_bytes!("../../fixtures/raw_signature/legacy/rs256.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/legacy/rs256.pub_key"); @@ -214,7 +253,10 @@ fn legacy_rs256() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn legacy_rs256_bad_signature() { let mut signature = include_bytes!("../../fixtures/raw_signature/legacy/rs256.raw_sig").to_vec(); @@ -235,7 +277,10 @@ fn legacy_rs256_bad_signature() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn legacy_rs256_bad_data() { let signature = include_bytes!("../../fixtures/raw_signature/legacy/rs256.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/legacy/rs256.pub_key"); @@ -253,7 +298,10 @@ fn legacy_rs256_bad_data() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn rs384() { let signature = include_bytes!("../../fixtures/raw_signature/legacy/rs384.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/legacy/rs384.pub_key"); @@ -265,7 +313,10 @@ fn rs384() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn rs512() { let signature = include_bytes!("../../fixtures/raw_signature/legacy/rs512.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/legacy/rs512.pub_key"); @@ -280,7 +331,7 @@ fn rs512() { const SHA1_OID: Oid = bcder::Oid(OctetString::from_static(&[43, 14, 3, 2, 26])); #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), wasm_bindgen_test)] fn sha1() { let signature = include_bytes!("../../fixtures/raw_signature/legacy/sha1.raw_sig"); let pub_key = include_bytes!("../../fixtures/raw_signature/legacy/sha1.pub_key"); diff --git a/internal/crypto/src/tests/raw_signature/signers.rs b/internal/crypto/src/tests/raw_signature/signers.rs index 1ddd0b782..14d98697b 100644 --- a/internal/crypto/src/tests/raw_signature/signers.rs +++ b/internal/crypto/src/tests/raw_signature/signers.rs @@ -11,7 +11,7 @@ // specific language governing permissions and limitations under // each license. -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use crate::raw_signature::{ @@ -19,7 +19,8 @@ use crate::raw_signature::{ }; #[test] -// #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +// #[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), wasm_bindgen_test)] +#[cfg(not(target_arch = "wasm32"))] fn es256() { let cert_chain = include_bytes!("../fixtures/raw_signature/es256.pub"); let private_key = include_bytes!("../fixtures/raw_signature/es256.priv"); @@ -41,7 +42,8 @@ fn es256() { } #[test] -// #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +// #[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), wasm_bindgen_test)] +#[cfg(not(target_arch = "wasm32"))] fn es384() { let cert_chain = include_bytes!("../fixtures/raw_signature/es384.pub"); let private_key = include_bytes!("../fixtures/raw_signature/es384.priv"); @@ -63,7 +65,8 @@ fn es384() { } #[test] -// #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +// #[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), wasm_bindgen_test)] +#[cfg(not(target_arch = "wasm32"))] fn es512() { let cert_chain = include_bytes!("../fixtures/raw_signature/es512.pub"); let private_key = include_bytes!("../fixtures/raw_signature/es512.priv"); @@ -85,7 +88,10 @@ fn es512() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ed25519() { let cert_chain = include_bytes!("../fixtures/raw_signature/ed25519.pub"); let private_key = include_bytes!("../fixtures/raw_signature/ed25519.priv"); @@ -107,7 +113,8 @@ fn ed25519() { } #[test] -// #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +// #[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), +// wasm_bindgen_test)] fn ps256() { let cert_chain = include_bytes!("../fixtures/raw_signature/ps256.pub"); let private_key = include_bytes!("../fixtures/raw_signature/ps256.priv"); @@ -129,7 +136,8 @@ fn ps256() { } #[test] -// #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +// #[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), +// wasm_bindgen_test)] fn ps384() { let cert_chain = include_bytes!("../fixtures/raw_signature/ps384.pub"); let private_key = include_bytes!("../fixtures/raw_signature/ps384.priv"); @@ -151,7 +159,8 @@ fn ps384() { } #[test] -// #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +// #[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), +// wasm_bindgen_test)] fn ps512() { let cert_chain = include_bytes!("../fixtures/raw_signature/ps512.pub"); let private_key = include_bytes!("../fixtures/raw_signature/ps512.priv"); diff --git a/internal/crypto/src/tests/raw_signature/validators.rs b/internal/crypto/src/tests/raw_signature/validators.rs index 50df94130..146c2b5d0 100644 --- a/internal/crypto/src/tests/raw_signature/validators.rs +++ b/internal/crypto/src/tests/raw_signature/validators.rs @@ -15,7 +15,7 @@ use std::str::FromStr; use bcder::Oid; use rasn::types::OctetString; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use crate::raw_signature::{ @@ -26,7 +26,10 @@ use crate::raw_signature::{ const SAMPLE_DATA: &[u8] = b"some sample content to sign"; #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn es256() { let signature = include_bytes!("../fixtures/raw_signature/es256.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/es256.pub_key"); @@ -37,7 +40,10 @@ fn es256() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn es256_bad_signature() { let mut signature = include_bytes!("../fixtures/raw_signature/es256.raw_sig").to_vec(); assert_ne!(signature[10], 10); @@ -56,7 +62,10 @@ fn es256_bad_signature() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn es256_bad_data() { let signature = include_bytes!("../fixtures/raw_signature/es256.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/es256.pub_key"); @@ -73,7 +82,10 @@ fn es256_bad_data() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn es384() { let signature = include_bytes!("../fixtures/raw_signature/es384.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/es384.pub_key"); @@ -84,8 +96,8 @@ fn es384() { } #[test] -// #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] // ES512 not -// implemented +// #[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), +// wasm_bindgen_test)] // ES512 not implemented fn es512() { let signature = include_bytes!("../fixtures/raw_signature/es512.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/es512.pub_key"); @@ -96,7 +108,10 @@ fn es512() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ed25519() { let signature = include_bytes!("../fixtures/raw_signature/ed25519.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/ed25519.pub_key"); @@ -107,7 +122,10 @@ fn ed25519() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ed25519_bad_data() { let signature = include_bytes!("../fixtures/raw_signature/ed25519.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/ed25519.pub_key"); @@ -125,7 +143,10 @@ fn ed25519_bad_data() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps256() { let signature = include_bytes!("../fixtures/raw_signature/ps256.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/ps256.pub_key"); @@ -136,7 +157,10 @@ fn ps256() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps256_bad_signature() { let mut signature = include_bytes!("../fixtures/raw_signature/ps256.raw_sig").to_vec(); assert_ne!(signature[10], 10); @@ -155,7 +179,10 @@ fn ps256_bad_signature() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps256_bad_data() { let signature = include_bytes!("../fixtures/raw_signature/ps256.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/ps256.pub_key"); @@ -172,7 +199,10 @@ fn ps256_bad_data() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps384() { let signature = include_bytes!("../fixtures/raw_signature/ps384.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/ps384.pub_key"); @@ -183,7 +213,10 @@ fn ps384() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn ps512() { let signature = include_bytes!("../fixtures/raw_signature/ps512.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/ps512.pub_key"); @@ -205,10 +238,14 @@ const SHA384_OID: Oid = bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 10 const SHA512_OID: Oid = bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 101, 3, 4, 2, 3])); +#[cfg_attr(target_arch = "wasm32", allow(unused))] const SHA1_OID: Oid = bcder::Oid(OctetString::from_static(&[43, 14, 3, 2, 26])); #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn legacy_rs256() { let signature = include_bytes!("../fixtures/raw_signature/legacy/rs256.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/legacy/rs256.pub_key"); @@ -219,7 +256,10 @@ fn legacy_rs256() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn legacy_rs256_bad_signature() { let mut signature = include_bytes!("../fixtures/raw_signature/legacy/rs256.raw_sig").to_vec(); assert_ne!(signature[10], 10); @@ -238,7 +278,10 @@ fn legacy_rs256_bad_signature() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn legacy_rs256_bad_data() { let signature = include_bytes!("../fixtures/raw_signature/legacy/rs256.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/legacy/rs256.pub_key"); @@ -255,7 +298,10 @@ fn legacy_rs256_bad_data() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn rs384() { let signature = include_bytes!("../fixtures/raw_signature/legacy/rs384.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/legacy/rs384.pub_key"); @@ -266,7 +312,10 @@ fn rs384() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn rs512() { let signature = include_bytes!("../fixtures/raw_signature/legacy/rs512.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/legacy/rs512.pub_key"); @@ -277,8 +326,9 @@ fn rs512() { } #[test] -// #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] // SHA1 not +// #[cfg_attr(all(target_arch = "wasm32", not(target_os = "wasi")), wasm_bindgen_test)] // SHA1 not // implemented +#[cfg(not(target_arch = "wasm32"))] fn sha1() { let signature = include_bytes!("../fixtures/raw_signature/legacy/sha1.raw_sig"); let pub_key = include_bytes!("../fixtures/raw_signature/legacy/sha1.pub_key"); @@ -297,7 +347,10 @@ fn ans1_oid_bcder_oid(asn1_oid: &asn1_rs::Oid) -> bcder::Oid { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn test_get_by_sig_and_alg() { use crate::raw_signature::oids::*; diff --git a/internal/crypto/src/tests/signing_alg.rs b/internal/crypto/src/tests/signing_alg.rs index 92adafc54..443ea13ce 100644 --- a/internal/crypto/src/tests/signing_alg.rs +++ b/internal/crypto/src/tests/signing_alg.rs @@ -11,13 +11,16 @@ // specific language governing permissions and limitations under // each license. -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; use crate::raw_signature::{SigningAlg, UnknownAlgorithmError}; #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn alg_from_str() { assert_eq!("es256".parse(), Ok(SigningAlg::Es256)); assert_eq!("es384".parse(), Ok(SigningAlg::Es384)); @@ -32,7 +35,10 @@ fn alg_from_str() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn signing_alg_impl_display() { assert_eq!(format!("{}", SigningAlg::Es256), "es256"); assert_eq!(format!("{}", SigningAlg::Es384), "es384"); @@ -44,7 +50,10 @@ fn signing_alg_impl_display() { } #[test] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test +)] fn err_impl_display() { assert_eq!( format!("{}", UnknownAlgorithmError("bogus".to_owned())), diff --git a/internal/crypto/src/time_stamp/verify.rs b/internal/crypto/src/time_stamp/verify.rs index f7b9b39b0..95512bd30 100644 --- a/internal/crypto/src/time_stamp/verify.rs +++ b/internal/crypto/src/time_stamp/verify.rs @@ -352,15 +352,13 @@ async fn validate_timestamp_sig_async( .validate_async(&sig_val.to_bytes(), tbs, signing_key_der) .await .map_err(|_| TimeStampError::InvalidData) + } else if let Some(validator) = + crate::raw_signature::validator_for_sig_and_hash_algs(sig_alg, hash_alg) + { + validator + .validate(&sig_val.to_bytes(), tbs, signing_key_der) + .map_err(|_| TimeStampError::InvalidData) } else { - if let Some(validator) = - crate::raw_signature::validator_for_sig_and_hash_algs(sig_alg, hash_alg) - { - validator - .validate(&sig_val.to_bytes(), tbs, signing_key_der) - .map_err(|_| TimeStampError::InvalidData) - } else { - Err(TimeStampError::UnsupportedAlgorithm) - } + Err(TimeStampError::UnsupportedAlgorithm) } } diff --git a/make_test_images/Cargo.toml b/make_test_images/Cargo.toml index 275a3ff32..72d290463 100644 --- a/make_test_images/Cargo.toml +++ b/make_test_images/Cargo.toml @@ -28,7 +28,7 @@ nom = "7.1.3" regex = "1.5.6" serde = "1.0.197" serde_json = { version = "1.0.117", features = ["preserve_order"] } -tempfile = "3.10.1" +tempfile = "3.15.0" [features] # prevents these features from being always enabled in the workspace diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 6e8d27b5c..4bda462a5 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -30,7 +30,7 @@ add_thumbnails = ["image"] file_io = ["openssl_sign"] serialize_thumbnails = [] no_interleaved_io = ["file_io"] -fetch_remote_manifests = [] +fetch_remote_manifests = ["dep:wasi"] openssl = [] openssl_sign = ["openssl"] json_schema = ["dep:schemars", "c2pa-crypto/json_schema"] @@ -74,10 +74,7 @@ byteorder = { version = "1.4.3", default-features = false } byteordered = "0.6.0" c2pa-crypto = { path = "../internal/crypto", version = "0.6.2" } c2pa-status-tracker = { path = "../internal/status-tracker", version = "0.5.0" } -chrono = { version = "0.4.39", default-features = false, features = [ - "serde", - "wasmbind", -] } +chrono = { version = "0.4.39", default-features = false, features = ["serde"] } ciborium = "0.2.2" config = { version = "0.14.0", default-features = false, features = [ "json", @@ -119,30 +116,46 @@ serde_with = "3.11.0" serde-transcode = "1.1.1" sha1 = "0.10.6" sha2 = "0.10.6" -tempfile = "3.10.1" +tempfile = "=3.15.0" thiserror = "2.0.8" treeline = "0.1.0" url = "2.5.3" -uuid = { version = "1.10.0", features = ["serde", "v4", "js"] } +uuid = { version = "=1.12.0", features = ["serde", "v4"] } +x509-certificate = "0.23.1" x509-parser = "0.16.0" -x509-certificate = "0.21.0" zip = { version = "2.2.1", default-features = false } +[target.'cfg(target_arch = "wasm32")'.dependencies] +rsa = { version = "0.9.6", features = ["sha2"] } +spki = "0.7.3" + +[target.'cfg(target_env = "p2")'.dependencies] +tempfile = { version = "3.15", features = ["nightly"] } + [target.'cfg(not(target_arch = "wasm32"))'.dependencies] ureq = "2.4.0" + +[target.'cfg(any(target_os = "wasi", not(target_arch = "wasm32")))'.dependencies] image = { version = "0.24.7", default-features = false, features = [ "jpeg", "png", ], optional = true } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(target_os = "wasi")'.dependencies] +getrandom = "0.2.7" +wasi = {version = "0.14", optional = true} + +[target.'cfg(all(target_arch = "wasm32",not(target_os = "wasi")))'.dependencies] +chrono = { version = "0.4.39", default-features = false, features = [ + "serde", + "wasmbind", +] } console_log = { version = "1.0.0", features = ["color"] } getrandom = { version = "0.2.7", features = ["js"] } js-sys = "0.3.58" rand_core = "0.9.0-alpha.2" -rsa = { version = "0.9.6", features = ["sha2"] } serde-wasm-bindgen = "0.6.5" -spki = "0.7.3" +uuid = { version = "1.10.0", features = ["serde", "v4", "js"] } wasm-bindgen = "0.2.83" wasm-bindgen-futures = "0.4.31" web-sys = { version = "0.3.58", features = [ @@ -160,9 +173,12 @@ hex-literal = "0.4.1" jumbf = "0.4.0" mockall = "0.13.1" -[target.'cfg(target_arch = "wasm32")'.dev-dependencies] -wasm-bindgen-test = "0.3.31" +[target.'cfg(all(target_arch = "wasm32",not(target_os = "wasi")))'.dev-dependencies] +wasm-bindgen-test = "0.3.45" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] actix = "0.13.1" tokio = { version = "1.36.0", features = ["full"] } + +[target.'cfg(target_os = "wasi")'.dev-dependencies] +wstd = "0.5" diff --git a/sdk/examples/data_hash.rs b/sdk/examples/data_hash.rs index c17fbc87a..75b1f5d8e 100644 --- a/sdk/examples/data_hash.rs +++ b/sdk/examples/data_hash.rs @@ -14,13 +14,13 @@ // Example code (in unit test) for how you might use client DataHash values. This allows clients // to perform the manifest embedding and optionally the hashing -#[cfg(all(feature = "openssl_sign", not(target_arch = "wasm32")))] +#[cfg(any(feature = "openssl_sign", feature = "file_io"))] use std::{ io::{Cursor, Read, Seek, Write}, path::{Path, PathBuf}, }; -#[cfg(all(feature = "openssl_sign", not(target_arch = "wasm32")))] +#[cfg(any(feature = "openssl_sign", feature = "file_io"))] use c2pa::{ assertions::{ c2pa_action, labels::*, Action, Actions, CreativeWork, DataHash, Exif, SchemaDotOrgPerson, @@ -28,7 +28,7 @@ use c2pa::{ create_signer, hash_stream_by_alg, Builder, ClaimGeneratorInfo, HashRange, Ingredient, Reader, Relationship, Result, }; -#[cfg(all(feature = "openssl_sign", not(target_arch = "wasm32")))] +#[cfg(any(feature = "openssl_sign", feature = "file_io"))] use c2pa_crypto::raw_signature::SigningAlg; fn main() -> std::result::Result<(), Box> { diff --git a/sdk/src/asset_handlers/bmff_io.rs b/sdk/src/asset_handlers/bmff_io.rs index 61cacb3e1..b5851f498 100644 --- a/sdk/src/asset_handlers/bmff_io.rs +++ b/sdk/src/asset_handlers/bmff_io.rs @@ -22,7 +22,6 @@ use std::{ use atree::{Arena, Token}; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use conv::ValueFrom; -use tempfile::Builder; use crate::{ assertions::{BmffMerkleMap, ExclusionsMap}, @@ -33,7 +32,7 @@ use crate::{ error::{Error, Result}, utils::{ hash_utils::{vec_compare, HashRange}, - io_utils::{stream_len, ReaderUtils}, + io_utils::{stream_len, tempfile_builder, ReaderUtils}, xmp_inmemory_utils::{add_provenance, MIN_XMP}, }, }; @@ -1278,10 +1277,7 @@ impl AssetIO for BmffIO { .open(asset_path) .map_err(Error::IoError)?; - let mut temp_file = Builder::new() - .prefix("c2pa_temp") - .rand_bytes(5) - .tempfile()?; + let mut temp_file = tempfile_builder("c2pa_temp")?; self.write_cai(&mut input_stream, &mut temp_file, store_bytes)?; @@ -1300,10 +1296,7 @@ impl AssetIO for BmffIO { fn remove_cai_store(&self, asset_path: &Path) -> Result<()> { let mut input_file = std::fs::File::open(asset_path)?; - let mut temp_file = Builder::new() - .prefix("c2pa_temp") - .rand_bytes(5) - .tempfile()?; + let mut temp_file = tempfile_builder("c2pa_temp")?; self.remove_cai_store_from_stream(&mut input_file, &mut temp_file)?; @@ -1842,17 +1835,18 @@ impl RemoteRefEmbed for BmffIO { } } } + #[cfg(test)] pub mod tests { #![allow(clippy::expect_used)] #![allow(clippy::panic)] #![allow(clippy::unwrap_used)] - use tempfile::tempdir; - use super::*; - use crate::utils::test::{fixture_path, temp_dir_path}; - + use crate::utils::{ + io_utils::tempdirectory, + test::{fixture_path, temp_dir_path}, + }; #[cfg(all(feature = "openssl", feature = "file_io"))] #[test] fn test_read_mp4() { @@ -1878,7 +1872,7 @@ pub mod tests { let data = "some test data"; let source = fixture_path("video1.mp4"); - let temp_dir = tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "video1-out.mp4"); std::fs::copy(source, &output).unwrap(); @@ -1904,7 +1898,7 @@ pub mod tests { let source = fixture_path("video1.mp4"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "mp4_test.mp4"); if let Ok(_size) = std::fs::copy(source, &output) { @@ -1928,7 +1922,7 @@ pub mod tests { let source = fixture_path("video1.mp4"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "mp4_test.mp4"); if let Ok(_size) = std::fs::copy(&source, &output) { @@ -1954,7 +1948,7 @@ pub mod tests { let source = fixture_path("video1.mp4"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "mp4_test.mp4"); if let Ok(_size) = std::fs::copy(source, &output) { @@ -1981,7 +1975,7 @@ pub mod tests { fn test_remove_c2pa() { let source = fixture_path("video1.mp4"); - let temp_dir = tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "mp4_test.mp4"); std::fs::copy(source, &output).unwrap(); diff --git a/sdk/src/asset_handlers/c2pa_io.rs b/sdk/src/asset_handlers/c2pa_io.rs index 0db895ac7..2505e7536 100644 --- a/sdk/src/asset_handlers/c2pa_io.rs +++ b/sdk/src/asset_handlers/c2pa_io.rs @@ -148,12 +148,12 @@ pub mod tests { use c2pa_crypto::raw_signature::SigningAlg; use c2pa_status_tracker::OneShotStatusTracker; - use tempfile::tempdir; use super::{AssetIO, C2paIO, CAIReader, CAIWriter}; use crate::{ store::Store, utils::{ + io_utils::tempdirectory, test::{fixture_path, temp_dir_path}, test_signer::test_signer, }, @@ -163,7 +163,7 @@ pub mod tests { fn c2pa_io_parse() { let path = fixture_path("C.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let temp_path = temp_dir_path(&temp_dir, "test.c2pa"); let c2pa_io = C2paIO {}; diff --git a/sdk/src/asset_handlers/jpeg_io.rs b/sdk/src/asset_handlers/jpeg_io.rs index b48b30531..b3b0757f7 100644 --- a/sdk/src/asset_handlers/jpeg_io.rs +++ b/sdk/src/asset_handlers/jpeg_io.rs @@ -27,7 +27,6 @@ use img_parts::{ Bytes, DynImage, }; use serde_bytes::ByteBuf; -use tempfile::Builder; use crate::{ assertions::{BoxMap, C2PA_BOXHASH}, @@ -37,7 +36,10 @@ use crate::{ RemoteRefEmbedType, }, error::{Error, Result}, - utils::xmp_inmemory_utils::{add_provenance, MIN_XMP}, + utils::{ + io_utils::tempfile_builder, + xmp_inmemory_utils::{add_provenance, MIN_XMP}, + }, }; static SUPPORTED_TYPES: [&str; 3] = ["jpg", "jpeg", "image/jpeg"]; @@ -481,10 +483,7 @@ impl AssetIO for JpegIO { .open(asset_path) .map_err(Error::IoError)?; - let mut temp_file = Builder::new() - .prefix("c2pa_temp") - .rand_bytes(5) - .tempfile()?; + let mut temp_file = tempfile_builder("c2pa_temp")?; self.write_cai(&mut input_stream, &mut temp_file, store_bytes)?; @@ -1120,10 +1119,11 @@ pub mod tests { use std::io::{Read, Seek}; - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::*; use super::*; + use crate::utils::io_utils::tempdirectory; #[test] fn test_extract_xmp() { let contents = Bytes::from_static(b"http://ns.adobe.com/xap/1.0/\0stuff"); @@ -1151,7 +1151,7 @@ pub mod tests { fn test_remove_c2pa() { let source = crate::utils::test::fixture_path("CA.jpg"); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = crate::utils::test::temp_dir_path(&temp_dir, "CA_test.jpg"); std::fs::copy(source, &output).unwrap(); @@ -1195,7 +1195,7 @@ pub mod tests { fn test_xmp_read_write() { let source = crate::utils::test::fixture_path("CA.jpg"); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = crate::utils::test::temp_dir_path(&temp_dir, "CA_test.jpg"); std::fs::copy(source, &output).unwrap(); @@ -1223,7 +1223,11 @@ pub mod tests { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] + #[allow(unused)] // not run for WASI async fn test_xmp_read_write_stream() { let source_bytes = include_bytes!("../../tests/fixtures/CA.jpg"); @@ -1273,7 +1277,7 @@ pub mod tests { .unwrap(); let curr_manifest = jpeg_io.read_cai_store(&source).unwrap(); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = crate::utils::test::temp_dir_path(&temp_dir, "CA_test.jpg"); std::fs::copy(source, &output).unwrap(); diff --git a/sdk/src/asset_handlers/mp3_io.rs b/sdk/src/asset_handlers/mp3_io.rs index f9c6d66bb..c37b4c11b 100644 --- a/sdk/src/asset_handlers/mp3_io.rs +++ b/sdk/src/asset_handlers/mp3_io.rs @@ -24,7 +24,6 @@ use id3::{ *, }; use memchr::memmem; -use tempfile::Builder; use crate::{ asset_io::{ @@ -34,7 +33,7 @@ use crate::{ }, error::{Error, Result}, utils::{ - io_utils::{stream_len, ReaderUtils}, + io_utils::{stream_len, tempfile_builder, ReaderUtils}, xmp_inmemory_utils::{self, MIN_XMP}, }, }; @@ -318,10 +317,7 @@ impl AssetIO for Mp3IO { .open(asset_path) .map_err(Error::IoError)?; - let mut temp_file = Builder::new() - .prefix("c2pa_temp") - .rand_bytes(5) - .tempfile()?; + let mut temp_file = tempfile_builder("c2pa_temp")?; self.write_cai(&mut input_stream, &mut temp_file, store_bytes)?; @@ -506,12 +502,12 @@ pub mod tests { #![allow(clippy::panic)] #![allow(clippy::unwrap_used)] - use tempfile::tempdir; use xmp_inmemory_utils::extract_provenance; use super::*; use crate::utils::{ hash_utils::vec_compare, + io_utils::tempdirectory, test::{fixture_path, temp_dir_path}, }; @@ -521,7 +517,7 @@ pub mod tests { let source = fixture_path("sample1.mp3"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "sample1-mp3.mp3"); if let Ok(_size) = std::fs::copy(source, &output) { @@ -544,7 +540,7 @@ pub mod tests { let source = fixture_path("sample1.mp3"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "sample1-mp3.mp3"); if let Ok(_size) = std::fs::copy(source, &output) { @@ -573,7 +569,7 @@ pub mod tests { fn test_remove_c2pa() { let source = fixture_path("sample1.mp3"); - let temp_dir = tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "sample1-mp3.mp3"); std::fs::copy(source, &output).unwrap(); diff --git a/sdk/src/asset_handlers/pdf.rs b/sdk/src/asset_handlers/pdf.rs index 370b1ee96..b9ea0e97f 100644 --- a/sdk/src/asset_handlers/pdf.rs +++ b/sdk/src/asset_handlers/pdf.rs @@ -544,30 +544,39 @@ mod tests { use super::*; - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::*; - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_loads_pdf_from_bytes() { let bytes = include_bytes!("../../tests/fixtures/basic.pdf"); let pdf_result = Pdf::from_bytes(bytes); assert!(pdf_result.is_ok()); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_loads_pdf_from_bytes_with_invalid_file() { let bytes = include_bytes!("../../tests/fixtures/XCA.jpg"); let pdf_result = Pdf::from_bytes(bytes); assert!(matches!(pdf_result, Err(Error::UnableToReadPdf(_)))); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_is_password_protected() { let bytes = include_bytes!("../../tests/fixtures/basic-password.pdf"); let pdf_result = Pdf::from_bytes(bytes).unwrap(); @@ -578,16 +587,22 @@ mod tests { assert!(!pdf.is_password_protected()); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_has_c2pa_manifest_on_file_without_manifest() { let bytes = include_bytes!("../../tests/fixtures/basic.pdf"); let pdf = Pdf::from_bytes(bytes).unwrap(); assert!(!pdf.has_c2pa_manifest()) } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_has_c2pa_manifest_on_file_with_manifest() { let bytes = include_bytes!("../../tests/fixtures/basic.pdf"); let mut pdf = Pdf::from_bytes(bytes).unwrap(); @@ -597,8 +612,11 @@ mod tests { assert!(pdf.has_c2pa_manifest()); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_adds_embedded_file_spec_to_pdf_stream() { let bytes = include_bytes!("../../tests/fixtures/express.pdf"); let mut pdf = Pdf::from_bytes(bytes).unwrap(); @@ -615,8 +633,11 @@ mod tests { assert_eq!(stream.unwrap().as_stream().unwrap().content, bytes); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_write_manifest_as_annotation() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/express.pdf")).unwrap(); assert!(!pdf.has_c2pa_manifest()); @@ -624,8 +645,11 @@ mod tests { assert!(pdf.has_c2pa_manifest()); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_write_manifest_bytes_to_pdf_with_existing_annotations() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic-annotation.pdf")).unwrap(); @@ -633,8 +657,11 @@ mod tests { assert!(pdf.has_c2pa_manifest()); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_add_manifest_to_embedded_files() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic.pdf")).unwrap(); pdf.write_manifest_as_embedded_file(vec![10u8, 20u8]) @@ -643,8 +670,11 @@ mod tests { assert!(pdf.has_c2pa_manifest()); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_add_manifest_to_embedded_files_attachments_present() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic-attachments.pdf")).unwrap(); @@ -654,8 +684,11 @@ mod tests { assert!(pdf.has_c2pa_manifest()); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_save_to() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic.pdf")).unwrap(); assert!(!pdf.has_c2pa_manifest()); @@ -670,8 +703,11 @@ mod tests { assert!(saved_pdf.has_c2pa_manifest()); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_reads_manifest_bytes_for_embedded_files_manifest() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/express.pdf")).unwrap(); assert!(!pdf.has_c2pa_manifest()); @@ -687,8 +723,11 @@ mod tests { )); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_reads_manifest_bytes_for_annotation_manifest() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic.pdf")).unwrap(); assert!(!pdf.has_c2pa_manifest()); @@ -704,16 +743,22 @@ mod tests { )); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_read_manifest_bytes_from_pdf_without_bytes_returns_none() { let pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic.pdf")).unwrap(); assert!(!pdf.has_c2pa_manifest()); assert!(matches!(pdf.read_manifest_bytes(), Ok(None))); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_read_manifest_bytes_from_pdf_with_other_af_relationship_returns_none() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic.pdf")).unwrap(); pdf.document @@ -724,8 +769,11 @@ mod tests { assert!(matches!(pdf.read_manifest_bytes(), Ok(None))); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_read_pdf_with_associated_file_that_is_not_manifest() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic.pdf")).unwrap(); pdf.document @@ -736,22 +784,31 @@ mod tests { assert!(matches!(pdf.read_manifest_bytes(), Ok(None))); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_read_xmp_on_pdf_with_none() { let pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic-no-xmp.pdf")).unwrap(); assert_eq!(pdf.read_xmp(), None); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_read_xmp_on_pdf_with_some_metadata() { let pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic.pdf")).unwrap(); assert!(pdf.read_xmp().is_some()); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_remove_manifest_bytes_from_file_without_c2pa_returns_error() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic.pdf")).unwrap(); @@ -761,8 +818,11 @@ mod tests { )); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_remove_manifest_from_file_with_annotation_based_manifest() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic.pdf")).unwrap(); let manifest_bytes = vec![0u8, 1u8, 1u8, 2u8, 3u8]; @@ -774,8 +834,11 @@ mod tests { assert!(!pdf.has_c2pa_manifest()); } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[test] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] fn test_remove_manifest_from_file_with_embedded_file_based_manifest() { let mut pdf = Pdf::from_bytes(include_bytes!("../../tests/fixtures/basic.pdf")).unwrap(); let manifest_bytes = vec![0u8, 1u8, 1u8, 2u8, 3u8]; diff --git a/sdk/src/asset_handlers/png_io.rs b/sdk/src/asset_handlers/png_io.rs index 3b9eae73e..590dfbadd 100644 --- a/sdk/src/asset_handlers/png_io.rs +++ b/sdk/src/asset_handlers/png_io.rs @@ -21,7 +21,6 @@ use byteorder::{BigEndian, ReadBytesExt}; use conv::ValueFrom; use png_pong::chunk::InternationalText; use serde_bytes::ByteBuf; -use tempfile::Builder; use crate::{ assertions::{BoxMap, C2PA_BOXHASH}, @@ -32,7 +31,7 @@ use crate::{ }, error::{Error, Result}, utils::{ - io_utils::ReaderUtils, + io_utils::{tempfile_builder, ReaderUtils}, xmp_inmemory_utils::{add_provenance, MIN_XMP}, }, }; @@ -479,10 +478,7 @@ impl AssetIO for PngIO { .open(asset_path) .map_err(Error::IoError)?; - let mut temp_file = Builder::new() - .prefix("c2pa_temp") - .rand_bytes(5) - .tempfile()?; + let mut temp_file = tempfile_builder("c2pa_temp")?; self.write_cai(&mut stream, &mut temp_file, store_bytes)?; @@ -793,7 +789,10 @@ pub mod tests { use memchr::memmem; use super::*; - use crate::utils::test::{self, temp_dir_path}; + use crate::utils::{ + io_utils::tempdirectory, + test::{self, temp_dir_path}, + }; #[test] fn test_png_xmp() { @@ -815,7 +814,7 @@ pub mod tests { let ap = test::fixture_path("libpng-test.png"); let mut source_stream = std::fs::File::open(ap).unwrap(); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "out.png"); let mut output_stream = std::fs::OpenOptions::new() .read(true) @@ -981,7 +980,7 @@ pub mod tests { #[test] fn test_remove_c2pa() { let source = test::fixture_path("exp-test1.png"); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = test::temp_dir_path(&temp_dir, "exp-test1_tmp.png"); std::fs::copy(source, &output).unwrap(); @@ -1034,7 +1033,7 @@ pub mod tests { .unwrap(); let curr_manifest = png_io.read_cai_store(&source).unwrap(); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = crate::utils::test::temp_dir_path(&temp_dir, "exp-test1-out.png"); std::fs::copy(source, &output).unwrap(); diff --git a/sdk/src/asset_handlers/riff_io.rs b/sdk/src/asset_handlers/riff_io.rs index b1e8dc711..1f1695a23 100644 --- a/sdk/src/asset_handlers/riff_io.rs +++ b/sdk/src/asset_handlers/riff_io.rs @@ -21,7 +21,6 @@ use std::{ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use conv::ValueFrom; use riff::*; -use tempfile::Builder; use crate::{ asset_io::{ @@ -31,7 +30,7 @@ use crate::{ }, error::{Error, Result}, utils::{ - io_utils::stream_len, + io_utils::{stream_len, tempfile_builder}, xmp_inmemory_utils::{add_provenance, MIN_XMP}, }, }; @@ -363,10 +362,7 @@ impl AssetIO for RiffIO { fn save_cai_store(&self, asset_path: &Path, store_bytes: &[u8]) -> Result<()> { let mut input_stream = File::open(asset_path)?; - let mut temp_file = Builder::new() - .prefix("c2pa_temp") - .rand_bytes(5) - .tempfile()?; + let mut temp_file = tempfile_builder("c2pa_temp")?; self.write_cai(&mut input_stream, &mut temp_file, store_bytes)?; @@ -632,11 +628,10 @@ pub mod tests { use std::panic; - use tempfile::tempdir; - use super::*; use crate::utils::{ hash_utils::vec_compare, + io_utils::tempdirectory, test::{fixture_path, temp_dir_path}, xmp_inmemory_utils::extract_provenance, }; @@ -647,7 +642,7 @@ pub mod tests { let source = fixture_path("sample1.wav"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "sample1-wav.wav"); if let Ok(_size) = std::fs::copy(source, &output) { @@ -685,7 +680,7 @@ pub mod tests { let mut source = File::open(fixture_path("sample1.wav")).unwrap(); let riff_io = RiffIO::new("wav"); - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "sample1-wav.wav"); let mut output_stream = File::create(&output).unwrap(); @@ -706,7 +701,7 @@ pub mod tests { let source = fixture_path("sample1.wav"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "sample1-wav.wav"); if let Ok(_size) = std::fs::copy(source, &output) { @@ -735,7 +730,7 @@ pub mod tests { fn test_remove_c2pa() { let source = fixture_path("sample1.wav"); - let temp_dir = tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "sample1-wav.wav"); std::fs::copy(source, &output).unwrap(); @@ -767,7 +762,7 @@ pub mod tests { let source = fixture_path("test_xmp.webp"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "test_xmp.webp"); std::fs::copy(source, &output).unwrap(); @@ -803,7 +798,7 @@ pub mod tests { let source = fixture_path("test.webp"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "test.webp"); std::fs::copy(source, &output).unwrap(); @@ -839,7 +834,7 @@ pub mod tests { let source = fixture_path("test_lossless.webp"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "test_lossless.webp"); std::fs::copy(source, &output).unwrap(); diff --git a/sdk/src/asset_handlers/svg_io.rs b/sdk/src/asset_handlers/svg_io.rs index 3f0d7fe88..447250dbb 100644 --- a/sdk/src/asset_handlers/svg_io.rs +++ b/sdk/src/asset_handlers/svg_io.rs @@ -24,7 +24,6 @@ use quick_xml::{ events::{BytesText, Event}, Reader, Writer, }; -use tempfile::Builder; use crate::{ asset_io::{ @@ -43,7 +42,7 @@ use crate::{ }, error::{Error, Result}, utils::{ - io_utils::{patch_stream, stream_len, ReaderUtils}, + io_utils::{patch_stream, stream_len, tempfile_builder, ReaderUtils}, xmp_inmemory_utils::{self, MIN_XMP}, }, }; @@ -125,10 +124,7 @@ impl AssetIO for SvgIO { .open(asset_path) .map_err(Error::IoError)?; - let mut temp_file = Builder::new() - .prefix("c2pa_temp") - .rand_bytes(5) - .tempfile()?; + let mut temp_file = tempfile_builder("c2pa_temp")?; self.write_cai(&mut input_stream, &mut temp_file, store_bytes)?; @@ -149,10 +145,7 @@ impl AssetIO for SvgIO { fn remove_cai_store(&self, asset_path: &Path) -> Result<()> { let mut input_file = File::open(asset_path)?; - let mut temp_file = Builder::new() - .prefix("c2pa_temp") - .rand_bytes(5) - .tempfile()?; + let mut temp_file = tempfile_builder("c2pa_temp")?; self.remove_cai_store_from_stream(&mut input_file, &mut temp_file)?; @@ -752,12 +745,12 @@ pub mod tests { use std::io::Read; - use tempfile::tempdir; use xmp_inmemory_utils::extract_provenance; use super::*; use crate::utils::{ hash_utils::vec_compare, + io_utils::tempdirectory, test::{fixture_path, temp_dir_path}, }; @@ -767,7 +760,7 @@ pub mod tests { let source = fixture_path("sample1.svg"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "sample1.svg"); if let Ok(_size) = std::fs::copy(source, &output) { @@ -790,7 +783,7 @@ pub mod tests { let source = fixture_path("sample2.svg"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "sample2.svg"); if let Ok(_size) = std::fs::copy(source, &output) { @@ -813,7 +806,7 @@ pub mod tests { let source = fixture_path("sample3.svg"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "sample3.svg"); if let Ok(_size) = std::fs::copy(source, &output) { @@ -836,7 +829,7 @@ pub mod tests { let source = fixture_path("sample1.svg"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "sample1.svg"); if let Ok(_size) = std::fs::copy(source, &output) { @@ -865,7 +858,7 @@ pub mod tests { fn test_remove_c2pa() { let source = fixture_path("sample4.svg"); - let temp_dir = tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "sample4.svg"); std::fs::copy(source, &output).unwrap(); @@ -886,7 +879,7 @@ pub mod tests { let source = fixture_path("sample1.svg"); let mut success = false; - if let Ok(temp_dir) = tempdir() { + if let Ok(temp_dir) = tempdirectory() { let output = temp_dir_path(&temp_dir, "sample1.svg"); if let Ok(_size) = std::fs::copy(source, &output) { diff --git a/sdk/src/asset_handlers/tiff_io.rs b/sdk/src/asset_handlers/tiff_io.rs index ba60370e3..c5b2cdb9b 100644 --- a/sdk/src/asset_handlers/tiff_io.rs +++ b/sdk/src/asset_handlers/tiff_io.rs @@ -23,7 +23,6 @@ use atree::{Arena, Token}; use byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt}; use byteordered::{with_order, ByteOrdered, Endianness}; use conv::ValueFrom; -use tempfile::Builder; use crate::{ asset_io::{ @@ -33,7 +32,7 @@ use crate::{ }, error::{Error, Result}, utils::{ - io_utils::{safe_vec, stream_len, ReaderUtils}, + io_utils::{safe_vec, stream_len, tempfile_builder, ReaderUtils}, xmp_inmemory_utils::{add_provenance, MIN_XMP}, }, }; @@ -1369,10 +1368,7 @@ impl AssetIO for TiffIO { .open(asset_path) .map_err(Error::IoError)?; - let mut temp_file = Builder::new() - .prefix("c2pa_temp") - .rand_bytes(5) - .tempfile()?; + let mut temp_file = tempfile_builder("c2pa_temp")?; self.write_cai(&mut input_stream, &mut temp_file, store_bytes)?; @@ -1393,10 +1389,7 @@ impl AssetIO for TiffIO { fn remove_cai_store(&self, asset_path: &std::path::Path) -> Result<()> { let mut input_file = std::fs::File::open(asset_path)?; - let mut temp_file = Builder::new() - .prefix("c2pa_temp") - .rand_bytes(5) - .tempfile()?; + let mut temp_file = tempfile_builder("c2pa_temp")?; self.remove_cai_store_from_stream(&mut input_file, &mut temp_file)?; @@ -1637,18 +1630,15 @@ pub mod tests { use core::panic; - use tempfile::tempdir; - use super::*; - use crate::utils::test::temp_dir_path; - + use crate::utils::{io_utils::tempdirectory, test::temp_dir_path}; #[test] fn test_read_write_manifest() { let data = "some data"; let source = crate::utils::test::fixture_path("TUSCANY.TIF"); - let temp_dir = tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "test.tif"); std::fs::copy(source, &output).unwrap(); @@ -1670,7 +1660,7 @@ pub mod tests { let source = crate::utils::test::fixture_path("TUSCANY.TIF"); - let temp_dir = tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "test.tif"); std::fs::copy(source, &output).unwrap(); @@ -1696,7 +1686,7 @@ pub mod tests { let source = crate::utils::test::fixture_path("TUSCANY.TIF"); - let temp_dir = tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "test.tif"); std::fs::copy(source, &output).unwrap(); @@ -1728,7 +1718,7 @@ pub mod tests { let source = crate::utils::test::fixture_path("TUSCANY.TIF"); - let temp_dir = tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "test.tif"); std::fs::copy(source, &output).unwrap(); @@ -1810,7 +1800,7 @@ pub mod tests { let source = crate::utils::test::fixture_path("test.DNG"); //let source = crate::utils::test::fixture_path("sample1.dng"); - let temp_dir = tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "test.DNG"); std::fs::copy(&source, &output).unwrap(); diff --git a/sdk/src/builder.rs b/sdk/src/builder.rs index b71a200c6..d388dec93 100644 --- a/sdk/src/builder.rs +++ b/sdk/src/builder.rs @@ -1112,7 +1112,7 @@ mod tests { use c2pa_crypto::raw_signature::SigningAlg; use serde_json::json; - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::*; use super::*; @@ -1125,7 +1125,7 @@ mod tests { Reader, }; - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); fn parent_json() -> String { @@ -1190,7 +1190,7 @@ mod tests { .to_string() } - #[cfg(all(feature = "openssl_sign", not(target_arch = "wasm32")))] + #[cfg(any(feature = "file_io", feature = "openssl_sign"))] const TEST_IMAGE_CLEAN: &[u8] = include_bytes!("../tests/fixtures/IMG_0003.jpg"); const TEST_IMAGE: &[u8] = include_bytes!("../tests/fixtures/CA.jpg"); const TEST_THUMBNAIL: &[u8] = include_bytes!("../tests/fixtures/thumbnail.jpg"); @@ -1329,6 +1329,7 @@ mod tests { builder.to_archive(&mut zipped).unwrap(); // write the zipped stream to a file for debugging + #[cfg(not(target_os = "wasi"))] // target directory is outside of sandbox std::fs::write("../target/test.zip", zipped.get_ref()).unwrap(); // unzip the manifest builder from the zipped stream @@ -1357,8 +1358,10 @@ mod tests { #[test] #[cfg(feature = "file_io")] fn test_builder_sign_file() { + use crate::utils::io_utils::tempdirectory; + let source = "tests/fixtures/CA.jpg"; - let dir = tempfile::tempdir().unwrap(); + let dir = tempdirectory().unwrap(); let dest = dir.path().join("test_file.jpg"); let mut builder = Builder::from_json(&manifest_json()).unwrap(); @@ -1452,8 +1455,12 @@ mod tests { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] #[cfg_attr(not(any(target_arch = "wasm32", feature = "openssl_sign")), ignore)] + #[cfg_attr(target_os = "wasi", wstd::test)] async fn test_builder_remote_sign() { let format = "image/jpeg"; let mut source = Cursor::new(TEST_IMAGE); @@ -1584,7 +1591,11 @@ mod tests { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] + #[cfg_attr(target_os = "wasi", wstd::test)] #[cfg(any( target_arch = "wasm32", all(feature = "openssl_sign", feature = "file_io") diff --git a/sdk/src/cose_sign.rs b/sdk/src/cose_sign.rs index 7e53de81e..3cc757250 100644 --- a/sdk/src/cose_sign.rs +++ b/sdk/src/cose_sign.rs @@ -268,7 +268,7 @@ mod tests { use c2pa_crypto::raw_signature::SigningAlg; use super::sign_claim; - #[cfg(all(feature = "openssl_sign", not(target_arch = "wasm32")))] + #[cfg(all(any(feature = "openssl_sign", target_os = "wasi"), feature = "file_io"))] use crate::utils::test_signer::async_test_signer; use crate::{claim::Claim, utils::test_signer::test_signer, Result, Signer}; @@ -288,8 +288,9 @@ mod tests { assert_eq!(cose_sign1.len(), box_size); } - #[cfg(all(feature = "openssl_sign", feature = "file_io"))] - #[actix::test] + #[cfg(all(any(feature = "openssl_sign", target_os = "wasi"), feature = "file_io"))] + #[cfg_attr(not(target_arch = "wasm32"), actix::test)] + #[cfg_attr(target_os = "wasi", wstd::test)] async fn test_sign_claim_async() { use c2pa_crypto::raw_signature::SigningAlg; @@ -356,7 +357,7 @@ mod tests { let _cose_sign1 = sign_claim(&claim_bytes, &signer, box_size); - #[cfg(feature = "openssl")] // there is no verify on sign when openssl is disabled + #[cfg(any(feature = "openssl", target_os = "wasi"))] // there is no verify on sign when openssl is disabled assert!(_cose_sign1.is_err()); } } diff --git a/sdk/src/error.rs b/sdk/src/error.rs index 0dc95dfa4..49d4892ff 100644 --- a/sdk/src/error.rs +++ b/sdk/src/error.rs @@ -191,10 +191,10 @@ pub enum Error { #[error("required JUMBF box not found")] JumbfBoxNotFound, - #[error("could not fetch the remote manifest")] + #[error("could not fetch the remote manifest {0}")] RemoteManifestFetch(String), - #[error("must fetch remote manifests from url")] + #[error("must fetch remote manifests from url {0}")] RemoteManifestUrl(String), #[error("stopped because of logged error")] @@ -282,7 +282,7 @@ pub enum Error { JsonError(#[from] serde_json::Error), #[error(transparent)] - #[cfg(all(not(target_arch = "wasm32"), feature = "add_thumbnails"))] + #[cfg(feature = "add_thumbnails")] ImageError(#[from] image::ImageError), #[error(transparent)] diff --git a/sdk/src/ingredient.rs b/sdk/src/ingredient.rs index 947a6d8e0..a2f617d3b 100644 --- a/sdk/src/ingredient.rs +++ b/sdk/src/ingredient.rs @@ -1491,7 +1491,7 @@ impl IngredientOptions for DefaultOptions { } } -#[cfg(test)] +#[cfg(all(test, not(target_os = "wasi")))] mod tests { #![allow(clippy::expect_used)] #![allow(clippy::unwrap_used)] @@ -1702,12 +1702,12 @@ mod tests_file_io { #![allow(clippy::expect_used)] #![allow(clippy::unwrap_used)] - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::*; use super::*; use crate::utils::test::fixture_path; - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); const NO_MANIFEST_JPEG: &str = "earth_apollo17.jpg"; diff --git a/sdk/src/manifest.rs b/sdk/src/manifest.rs index 89705023c..9b1c03934 100644 --- a/sdk/src/manifest.rs +++ b/sdk/src/manifest.rs @@ -1552,12 +1552,13 @@ pub(crate) mod tests { use c2pa_crypto::raw_signature::SigningAlg; #[cfg(feature = "file_io")] use c2pa_status_tracker::{DetailedStatusTracker, StatusTracker}; - #[cfg(feature = "file_io")] - use tempfile::tempdir; - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::*; - #[cfg(target_arch = "wasm32")] + #[cfg(feature = "file_io")] + use crate::utils::io_utils::tempdirectory; + + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); #[allow(unused_imports)] @@ -1644,7 +1645,7 @@ pub(crate) mod tests { } // copy an image to use as our target - let dir = tempdir().expect("temp dir"); + let dir = tempdirectory().expect("temp dir"); let test_output = dir.path().join("wc_embed_test.jpg"); //embed a claim generated from this manifest @@ -1671,7 +1672,7 @@ pub(crate) mod tests { fn ws_bad_assertion() { // copy an image to use as our target for embedding let ap = fixture_path(TEST_SMALL_JPEG); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let test_output = temp_dir_path(&temp_dir, "ws_bad_assertion.jpg"); std::fs::copy(ap, test_output).expect("copy"); @@ -1701,7 +1702,7 @@ pub(crate) mod tests { fn ws_valid_labeled_assertion() { // copy an image to use as our target for embedding let ap = fixture_path(TEST_SMALL_JPEG); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let test_output = temp_dir_path(&temp_dir, "ws_bad_assertion.jpg"); std::fs::copy(ap, test_output).expect("copy"); @@ -1795,7 +1796,7 @@ pub(crate) mod tests { fn test_redaction() { const ASSERTION_LABEL: &str = "stds.schema-org.CreativeWork"; - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); let output2 = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); @@ -1870,7 +1871,7 @@ pub(crate) mod tests { #[cfg(feature = "file_io")] #[allow(deprecated)] fn test_action_assertion_redaction_error() { - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let parent_output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); // Create parent with a c2pa_action type assertion. @@ -1936,10 +1937,11 @@ pub(crate) mod tests { } #[cfg(all(feature = "file_io", feature = "openssl_sign"))] - #[actix::test] + #[cfg_attr(not(target_arch = "wasm32"), actix::test)] + #[cfg_attr(target_os = "wasi", wstd::test)] #[allow(deprecated)] async fn test_embed_async_sign() { - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); let async_signer = async_test_signer(SigningAlg::Ps256); @@ -1957,10 +1959,11 @@ pub(crate) mod tests { } #[cfg(all(feature = "file_io", feature = "openssl_sign"))] - #[actix::test] + #[cfg_attr(not(target_arch = "wasm32"), actix::test)] + #[cfg_attr(target_os = "wasi", wstd::test)] #[allow(deprecated)] async fn test_embed_remote_sign() { - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); let remote_signer = temp_remote_signer(); @@ -1981,7 +1984,7 @@ pub(crate) mod tests { #[test] #[allow(deprecated)] fn test_embed_user_label() { - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); let my_guid = static_test_uuid(); let signer = test_signer(SigningAlg::Ps256); @@ -2003,7 +2006,7 @@ pub(crate) mod tests { #[test] #[allow(deprecated)] fn test_embed_sidecar_user_label() { - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); let sidecar = output.with_extension("c2pa"); let fp = format!("file:/{}", sidecar.to_str().unwrap()); @@ -2027,9 +2030,13 @@ pub(crate) mod tests { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] #[allow(deprecated)] #[cfg_attr(not(any(target_arch = "wasm32", feature = "openssl_sign")), ignore)] + #[cfg_attr(target_os = "wasi", wstd::test)] async fn test_embed_jpeg_stream_wasm() { use crate::assertions::User; let image = include_bytes!("../tests/fixtures/earth_apollo17.jpg"); @@ -2068,9 +2075,13 @@ pub(crate) mod tests { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] #[allow(deprecated)] #[cfg_attr(not(any(target_arch = "wasm32", feature = "openssl_sign")), ignore)] + #[cfg_attr(target_os = "wasi", wstd::test)] async fn test_embed_png_stream_wasm() { use crate::assertions::User; let image = include_bytes!("../tests/fixtures/libpng-test.png"); @@ -2102,9 +2113,13 @@ pub(crate) mod tests { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] #[allow(deprecated)] #[cfg_attr(not(any(target_arch = "wasm32", feature = "openssl_sign")), ignore)] + #[cfg_attr(target_os = "wasi", wstd::test)] async fn test_embed_webp_stream_wasm() { use crate::assertions::User; let image = include_bytes!("../tests/fixtures/mars.webp"); @@ -2173,8 +2188,15 @@ pub(crate) mod tests { //println!("{manifest_store}");main } - #[cfg_attr(feature = "openssl_sign", actix::test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr( + all(not(target_arch = "wasm32"), feature = "openssl_sign"), + actix::test + )] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] + #[cfg_attr(target_os = "wasi", wstd::test)] #[cfg(any( target_arch = "wasm32", all(feature = "openssl_sign", feature = "file_io") @@ -2219,11 +2241,12 @@ pub(crate) mod tests { } #[cfg(feature = "file_io")] - #[actix::test] + #[cfg_attr(not(target_arch = "wasm32"), actix::test)] + #[cfg_attr(target_os = "wasi", wstd::test)] #[allow(deprecated)] /// Verify that an ingredient with error is reported on the ingredient and not on the manifest_store async fn test_embed_with_ingredient_error() { - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); let signer = test_signer(SigningAlg::Ps256); @@ -2256,7 +2279,7 @@ pub(crate) mod tests { #[test] #[allow(deprecated)] fn test_embed_sidecar_with_parent_manifest() { - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let source = fixture_path("XCA.jpg"); let output = temp_dir.path().join("XCAplus.jpg"); let sidecar = output.with_extension("c2pa"); @@ -2287,7 +2310,7 @@ pub(crate) mod tests { #[test] #[allow(deprecated)] fn test_embed_user_thumbnail() { - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); let signer = test_signer(SigningAlg::Ps256); @@ -2554,15 +2577,22 @@ pub(crate) mod tests { // println!("{manifest_store}"); } + // WASI cannot read files in the target directory #[test] - #[cfg(feature = "file_io")] + #[cfg(all(feature = "file_io", not(target_arch = "wasm32")))] fn from_json_with_files() { let mut manifest = Manifest::from_json(MANIFEST_JSON).unwrap(); + #[cfg(target_os = "wasi")] + let mut path = std::path::PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("tests/fixtures"); // the path we want to read files from manifest.with_base_path(path).expect("with_files"); // convert the manifest to a store let store = manifest.to_store().expect("to store"); + #[cfg(target_os = "wasi")] + let mut resource_path = std::path::PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut resource_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); resource_path.push("../target/tmp/manifest"); let m2 = Manifest::from_store( @@ -2580,10 +2610,13 @@ pub(crate) mod tests { #[test] #[allow(deprecated)] fn test_embed_from_json() { + #[cfg(target_os = "wasi")] + let mut fixtures = std::path::PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut fixtures = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); fixtures.push("tests/fixtures"); // the path we want to read files from - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); let signer = test_signer(SigningAlg::Ps256); @@ -2607,10 +2640,13 @@ pub(crate) mod tests { fn test_embed_webp_from_json() { use crate::utils::test::TEST_WEBP; + #[cfg(target_os = "wasi")] + let mut fixtures = std::path::PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut fixtures = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); fixtures.push("tests/fixtures"); // the path we want to read files from - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_WEBP); let signer = test_signer(SigningAlg::Ps256); @@ -2632,10 +2668,13 @@ pub(crate) mod tests { #[cfg(feature = "file_io")] #[allow(deprecated)] fn test_create_file_based_ingredient() { + #[cfg(target_os = "wasi")] + let mut fixtures = std::path::PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut fixtures = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); fixtures.push("tests/fixtures"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); let mut manifest = Manifest::new("claim_generator"); @@ -2664,7 +2703,7 @@ pub(crate) mod tests { let mut fixtures = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); fixtures.push("tests/fixtures"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let output = temp_fixture_path(&temp_dir, TEST_SMALL_JPEG); let mut manifest = Manifest::new("claim_generator"); @@ -2734,7 +2773,7 @@ pub(crate) mod tests { .data_hash_placeholder(signer.reserve_size(), "jpeg") .unwrap(); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "boxhash-out.jpg"); let mut output_file = std::fs::OpenOptions::new() .read(true) @@ -2778,7 +2817,8 @@ pub(crate) mod tests { } #[cfg(all(feature = "file_io", feature = "openssl_sign"))] - #[actix::test] + #[cfg_attr(not(target_arch = "wasm32"), actix::test)] + #[cfg_attr(target_os = "wasi", wstd::test)] #[allow(deprecated)] async fn test_data_hash_embeddable_manifest_remote_signed() { let ap = fixture_path("cloud.jpg"); @@ -2792,7 +2832,7 @@ pub(crate) mod tests { .data_hash_placeholder(signer.reserve_size(), "jpeg") .unwrap(); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "boxhash-out.jpg"); let mut output_file = std::fs::OpenOptions::new() .read(true) diff --git a/sdk/src/manifest_store.rs b/sdk/src/manifest_store.rs index 15d2882d3..cd86be18b 100644 --- a/sdk/src/manifest_store.rs +++ b/sdk/src/manifest_store.rs @@ -601,18 +601,21 @@ mod tests { #![allow(clippy::unwrap_used)] use c2pa_status_tracker::OneShotStatusTracker; - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::*; use super::*; use crate::utils::test::create_test_store; - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); // #[cfg_attr(not(target_arch = "wasm32"), test)] // #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] #[test] fn manifest_report() { let store = create_test_store().expect("creating test store"); @@ -651,7 +654,11 @@ mod tests { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] + #[cfg_attr(target_os = "wasi", wstd::test)] #[cfg(feature = "v1_api")] #[allow(deprecated)] async fn manifest_report_image_async() { @@ -691,7 +698,11 @@ mod tests { } #[cfg_attr(not(target_arch = "wasm32"), actix::test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr( + all(target_arch = "wasm32", not(target_os = "wasi")), + wasm_bindgen_test + )] + #[cfg_attr(target_os = "wasi", wstd::test)] #[allow(deprecated)] #[cfg(feature = "v1_api")] async fn manifest_report_from_manifest_and_asset_bytes_async() { @@ -710,9 +721,9 @@ mod tests { println!("{manifest_store}"); } + // WASI cannot read files in the target directory #[test] - #[cfg(feature = "file_io")] - #[cfg(feature = "v1_api")] + #[cfg(all(feature = "file_io", feature = "v1_api", not(target_arch = "wasm32")))] #[allow(deprecated)] fn manifest_report_from_file_with_resources() { let manifest_store = ManifestStore::from_file_with_resources( diff --git a/sdk/src/reader.rs b/sdk/src/reader.rs index fa650a884..109fca326 100644 --- a/sdk/src/reader.rs +++ b/sdk/src/reader.rs @@ -520,10 +520,14 @@ pub mod tests { #[cfg(feature = "file_io")] /// Test that the reader can validate a file with nested assertion errors fn test_reader_to_folder() -> Result<()> { + use crate::utils::{io_utils::tempdirectory, test::temp_dir_path}; + let reader = Reader::from_file("tests/fixtures/CACAE-uri-CA.jpg")?; assert_eq!(reader.validation_status(), None); - reader.to_folder("../target/reader_folder")?; - assert!(std::path::Path::new("../target/reader_folder/manifest.json").exists()); + let temp_dir = tempdirectory().unwrap(); + reader.to_folder(temp_dir.path())?; + let path = temp_dir_path(&temp_dir, "manifest.json"); + assert!(path.exists()); Ok(()) } } diff --git a/sdk/src/resource_store.rs b/sdk/src/resource_store.rs index 0774b1b82..1aa0304ae 100644 --- a/sdk/src/resource_store.rs +++ b/sdk/src/resource_store.rs @@ -39,7 +39,10 @@ use crate::{ /// resources based on the `serialize_resources` flag. /// (Serialization is disabled by default.) pub(crate) fn skip_serializing_resources(_: &ResourceStore) -> bool { - !cfg!(feature = "serialize_thumbnails") || cfg!(test) || cfg!(not(target_arch = "wasm32")) + //TODO: Why is this disabled for wasm32? + !cfg!(feature = "serialize_thumbnails") + || cfg!(test) + || cfg!(not(all(target_arch = "wasm32", not(target_os = "wasi")))) } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] diff --git a/sdk/src/settings.rs b/sdk/src/settings.rs index 1f932e3a9..df30a8b7a 100644 --- a/sdk/src/settings.rs +++ b/sdk/src/settings.rs @@ -412,6 +412,8 @@ pub mod tests { use std::sync::Mutex; use super::*; + #[cfg(feature = "file_io")] + use crate::utils::io_utils::tempdirectory; // prevent tests from polluting the results of each other because of Rust unit test concurrency static PROTECT: Mutex = Mutex::new(1); // prevent tests from polluting the results of each other @@ -542,7 +544,7 @@ pub mod tests { fn test_save_load() { let _protect = PROTECT.lock().unwrap(); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let op = crate::utils::test::temp_dir_path(&temp_dir, "sdk_config.json"); save_settings_as_json(&op).unwrap(); @@ -560,7 +562,7 @@ pub mod tests { fn test_save_load_from_string() { let _protect = PROTECT.lock().unwrap(); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let op = crate::utils::test::temp_dir_path(&temp_dir, "sdk_config.json"); save_settings_as_json(&op).unwrap(); diff --git a/sdk/src/store.rs b/sdk/src/store.rs index a6f8ae239..6af9f855f 100644 --- a/sdk/src/store.rs +++ b/sdk/src/store.rs @@ -32,11 +32,6 @@ use log::error; #[cfg(feature = "v1_api")] use crate::jumbf_io::save_jumbf_to_memory; -#[cfg(feature = "file_io")] -use crate::jumbf_io::{ - get_file_extension, get_supported_file_extension, load_jumbf_from_file, object_locations, - remove_jumbf_from_file, save_jumbf_to_file, -}; use crate::{ assertion::{ Assertion, AssertionBase, AssertionData, AssertionDecodeError, AssertionDecodeErrorCause, @@ -77,6 +72,14 @@ use crate::{ utils::{hash_utils::HashRange, io_utils::stream_len, patch::patch_bytes}, validation_status, AsyncSigner, RemoteSigner, Signer, }; +#[cfg(feature = "file_io")] +use crate::{ + jumbf_io::{ + get_file_extension, get_supported_file_extension, load_jumbf_from_file, object_locations, + remove_jumbf_from_file, save_jumbf_to_file, + }, + utils::io_utils::tempdirectory, +}; const MANIFEST_STORE_EXT: &str = "c2pa"; // file extension for external manifests @@ -2588,7 +2591,8 @@ impl Store { dest_path: &Path, ) -> Result> { // set up temp dir, contents auto deleted - let td = tempfile::TempDir::new()?; + + let td = tempdirectory()?; let temp_path = td.path(); let temp_file = temp_path.join( dest_path @@ -2642,7 +2646,7 @@ impl Store { dest_path: &Path, ) -> Result> { // set up temp dir, contents auto deleted - let td = tempfile::TempDir::new()?; + let td = tempdirectory()?; let temp_path = td.path(); let temp_file = temp_path.join( dest_path @@ -2698,7 +2702,7 @@ impl Store { dest_path: &Path, ) -> Result> { // set up temp dir, contents auto deleted - let td = tempfile::TempDir::new()?; + let td = tempdirectory()?; let temp_path = td.path(); let temp_file = temp_path.join( dest_path @@ -3225,7 +3229,7 @@ impl Store { } // fetch remote manifest if possible - #[cfg(feature = "fetch_remote_manifests")] + #[cfg(all(feature = "fetch_remote_manifests", not(target_os = "wasi")))] fn fetch_remote_manifest(url: &str) -> Result> { use conv::ValueFrom; use ureq::Error as uError; @@ -3272,6 +3276,83 @@ impl Store { } } + // fetch remote manifest if possible + #[cfg(all(feature = "fetch_remote_manifests", target_os = "wasi"))] + fn fetch_remote_manifest(url: &str) -> Result> { + use url::Url; + use wasi::http::{ + outgoing_handler, + types::{Fields, OutgoingRequest, Scheme}, + }; + + //const MANIFEST_CONTENT_TYPE: &str = "application/x-c2pa-manifest-store"; // todo verify once these are served + const DEFAULT_MANIFEST_RESPONSE_SIZE: usize = 10 * 1024 * 1024; // 10 MB + let parsed_url = Url::parse(url) + .map_err(|e| Error::RemoteManifestFetch(format!("invalid URL: {}", e)))?; + let authority = parsed_url.authority(); + let path_with_query = parsed_url[url::Position::AfterPort..].to_string(); + let scheme = match parsed_url.scheme() { + "http" => Scheme::Http, + "https" => Scheme::Https, + _ => { + return Err(Error::RemoteManifestFetch( + "unsupported URL scheme".to_string(), + )) + } + }; + + let request = OutgoingRequest::new(Fields::new()); + request.set_path_with_query(Some(&path_with_query)).unwrap(); + request.set_authority(Some(&authority)).unwrap(); + request.set_scheme(Some(&scheme)).unwrap(); + match outgoing_handler::handle(request, None) { + Ok(resp) => { + resp.subscribe().block(); + let response = resp + .get() + .ok_or(Error::RemoteManifestFetch( + "HTTP request response missing".to_string(), + ))? + .map_err(|_| { + Error::RemoteManifestFetch( + "HTTP request response requested more than once".to_string(), + ) + })? + .map_err(|_| Error::RemoteManifestFetch("HTTP request failed".to_string()))?; + if response.status() == 200 { + let content_length: usize = response + .headers() + .get("Content-Length") + .first() + .and_then(|val| if val.is_empty() { None } else { Some(val) }) + .and_then(|val| std::str::from_utf8(val).ok()) + .and_then(|str_parsed_header| str_parsed_header.parse().ok()) + .unwrap_or(DEFAULT_MANIFEST_RESPONSE_SIZE); + let body = { + let mut buf = Vec::with_capacity(content_length); + let response_body = response + .consume() + .expect("failed to get incoming request body"); + let mut stream = response_body + .stream() + .expect("failed to get response body stream"); + stream + .read_to_end(&mut buf) + .expect("failed to read response body"); + buf + }; + Ok(body) + } else { + Err(Error::RemoteManifestFetch(format!( + "fetch failed: code: {}", + response.status(), + ))) + } + } + Err(e) => Err(Error::RemoteManifestFetch(e.to_string())), + } + } + /// Handles remote manifests when file_io/fetch_remote_manifests feature is enabled fn handle_remote_manifest(ext_ref: &str) -> Result> { // verify provenance path is remote url @@ -3722,7 +3803,6 @@ pub mod tests { use memchr::memmem; use serde::Serialize; use sha2::{Digest, Sha256}; - use tempfile::tempdir; use super::*; use crate::{ @@ -3771,7 +3851,7 @@ pub mod tests { fn test_jumbf_generation() { // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "test-image.jpg"); // Create claims store. @@ -3886,7 +3966,7 @@ pub mod tests { use crate::ClaimGeneratorInfo; let ap = fixture_path("earth_apollo17.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "test-image.jpg"); // Create claims store. @@ -4002,7 +4082,7 @@ pub mod tests { fn test_unknown_asset_type_generation() { // test adding to actual image let ap = fixture_path("unsupported_type.txt"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "unsupported_type.txt"); // Create claims store. @@ -4083,7 +4163,7 @@ pub mod tests { fn test_detects_unverifiable_signature() { // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "test-image-unverified.jpg"); let mut store = Store::new(); @@ -4111,7 +4191,7 @@ pub mod tests { // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "test-image-expired-cert.jpg"); let mut store = Store::new(); @@ -4149,7 +4229,7 @@ pub mod tests { // test adding to actual image let ap = fixture_path("prerelease.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "replacement_test.jpg"); // grab jumbf from original @@ -4168,13 +4248,14 @@ pub mod tests { assert_eq!(memmem::find(&buf, &original_jumbf[0..1024]), None); } - #[actix::test] + #[cfg_attr(not(target_arch = "wasm32"), actix::test)] + #[cfg_attr(target_os = "wasi", wstd::test)] async fn test_jumbf_generation_async() { let signer = async_test_signer(SigningAlg::Ps256); // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "test-async.jpg"); // Create claims store. @@ -4234,11 +4315,12 @@ pub mod tests { assert!(errors.is_empty()); } - #[actix::test] + #[cfg_attr(not(target_arch = "wasm32"), actix::test)] + #[cfg_attr(target_os = "wasi", wstd::test)] async fn test_jumbf_generation_remote() { // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "test-async.jpg"); // Create claims store. @@ -4277,7 +4359,7 @@ pub mod tests { fn test_png_jumbf_generation() { // test adding to actual image let ap = fixture_path("libpng-test.png"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "libpng-test-c2pa.png"); // Create claims store. @@ -4373,7 +4455,7 @@ pub mod tests { #[cfg(feature = "file_io")] fn test_arw_jumbf_generation() { let ap = fixture_path("sample1.arw"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "ssample1.arw"); // Create claims store. @@ -4446,7 +4528,7 @@ pub mod tests { #[cfg(feature = "file_io")] fn test_nef_jumbf_generation() { let ap = fixture_path("sample1.nef"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "ssample1.nef"); // Create claims store. @@ -4520,7 +4602,7 @@ pub mod tests { #[cfg(feature = "file_io")] fn test_wav_jumbf_generation() { let ap = fixture_path("sample1.wav"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "ssample1.wav"); // Create claims store. @@ -4594,7 +4676,7 @@ pub mod tests { #[cfg(feature = "file_io")] fn test_avi_jumbf_generation() { let ap = fixture_path("test.avi"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "test.avi"); // Create claims store. @@ -4668,7 +4750,7 @@ pub mod tests { #[cfg(feature = "file_io")] fn test_webp_jumbf_generation() { let ap = fixture_path("sample1.webp"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "sample1.webp"); // Create claims store. @@ -4742,7 +4824,7 @@ pub mod tests { #[cfg(feature = "file_io")] fn test_heic() { let ap = fixture_path("sample1.heic"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "sample1.heic"); // Create claims store. @@ -4786,7 +4868,7 @@ pub mod tests { #[cfg(feature = "file_io")] fn test_avif() { let ap = fixture_path("sample1.avif"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "sample1.avif"); // Create claims store. @@ -4830,7 +4912,7 @@ pub mod tests { #[cfg(feature = "file_io")] fn test_heif() { let ap = fixture_path("sample1.heif"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "sample1.heif"); // Create claims store. @@ -4970,7 +5052,7 @@ pub mod tests { // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "earth_apollo17.jpg"); // get default store with default claim @@ -5008,7 +5090,7 @@ pub mod tests { // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "earth_apollo17.jpg"); // get default store with default claim @@ -5045,7 +5127,7 @@ pub mod tests { search_bytes: &[u8], replace_bytes: &[u8], ) -> impl StatusTracker { - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let path = temp_fixture_path(&temp_dir, fixture_name); patch_file(&path, search_bytes, replace_bytes).expect("patch_file"); let mut report = DetailedStatusTracker::default(); @@ -5063,7 +5145,7 @@ pub mod tests { // test adding to actual image let ap = fixture_path("earth_apollo17.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "update_manifest.jpg"); // get default store with default claim @@ -5225,7 +5307,7 @@ pub mod tests { fn test_bmff_jumbf_generation() { // test adding to actual image let ap = fixture_path("video1.mp4"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "video1.mp4"); // Create claims store. @@ -5311,7 +5393,7 @@ pub mod tests { fn test_external_manifest_sidecar() { // test adding to actual image let ap = fixture_path("libpng-test.png"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "libpng-test-c2pa.png"); let sidecar = op.with_extension(MANIFEST_STORE_EXT); @@ -5350,7 +5432,7 @@ pub mod tests { // test adding to actual image let ap = fixture_path(file_name); let extension = ap.extension().unwrap().to_str().unwrap(); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let mut op = temp_dir_path(&temp_dir, file_name); op.set_extension(extension); @@ -5419,7 +5501,7 @@ pub mod tests { fn test_user_guid_external_manifest_embedded() { // test adding to actual image let ap = fixture_path("libpng-test.png"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "libpng-test-c2pa.png"); let sidecar = op.with_extension(MANIFEST_STORE_EXT); @@ -5471,7 +5553,7 @@ pub mod tests { fn test_external_manifest_from_memory() { // test adding to actual image let ap = fixture_path("libpng-test.png"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "libpng-test-c2pa.png"); let sidecar = op.with_extension(MANIFEST_STORE_EXT); @@ -5527,7 +5609,8 @@ pub mod tests { } } - #[actix::test] + #[cfg_attr(not(target_arch = "wasm32"), actix::test)] + #[cfg_attr(target_os = "wasi", wstd::test)] async fn test_jumbf_generation_stream() { let file_buffer = include_bytes!("../tests/fixtures/earth_apollo17.jpg").to_vec(); // convert buffer to cursor with Read/Write/Seek capability @@ -5575,7 +5658,7 @@ pub mod tests { fn test_tiff_jumbf_generation() { // test adding to actual image let ap = fixture_path("TUSCANY.TIF"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "TUSCANY-OUTPUT.TIF"); // Create claims store. @@ -5641,7 +5724,8 @@ pub mod tests { } } - #[actix::test] + #[cfg_attr(not(target_arch = "wasm32"), actix::test)] + #[cfg_attr(target_os = "wasi", wstd::test)] #[cfg(feature = "file_io")] async fn test_boxhash_embeddable_manifest_async() { // test adding to actual image @@ -5705,7 +5789,7 @@ pub mod tests { out_stream.write_all(&after_buf).unwrap(); // save to output file - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "boxhash-out.jpg"); let mut output_file = std::fs::OpenOptions::new() .read(true) @@ -5790,7 +5874,7 @@ pub mod tests { out_stream.write_all(&after_buf).unwrap(); // save to output file - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "boxhash-out.jpg"); let mut output_file = std::fs::OpenOptions::new() .read(true) @@ -5808,7 +5892,8 @@ pub mod tests { assert!(errors.is_empty()); } - #[actix::test] + #[cfg_attr(not(target_arch = "wasm32"), actix::test)] + #[cfg_attr(target_os = "wasi", wstd::test)] #[cfg(feature = "file_io")] async fn test_datahash_embeddable_manifest_async() { // test adding to actual image @@ -5832,7 +5917,7 @@ pub mod tests { .get_data_hashed_manifest_placeholder(signer.reserve_size(), "jpeg") .unwrap(); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "boxhash-out.jpg"); let mut output_file = std::fs::OpenOptions::new() .read(true) @@ -5901,7 +5986,7 @@ pub mod tests { .get_data_hashed_manifest_placeholder(Signer::reserve_size(&signer), "jpeg") .unwrap(); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "boxhash-out.jpg"); let mut output_file = std::fs::OpenOptions::new() .read(true) @@ -5972,7 +6057,7 @@ pub mod tests { .get_data_hashed_manifest_placeholder(Signer::reserve_size(&signer), "jpeg") .unwrap(); - let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir = tempdirectory().unwrap(); let output = temp_dir_path(&temp_dir, "boxhash-out.jpg"); let mut output_file = std::fs::OpenOptions::new() .read(true) @@ -6067,7 +6152,7 @@ pub mod tests { // test adding to actual image let ap = fixture_path("C.jpg"); - let temp_dir = tempdir().expect("temp dir"); + let temp_dir = tempdirectory().expect("temp dir"); let op = temp_dir_path(&temp_dir, "C-placed.jpg"); // Create claims store. @@ -6260,7 +6345,8 @@ pub mod tests { // std::fs::write("target/test.jpg", result).unwrap(); } - #[actix::test] + #[cfg_attr(not(target_arch = "wasm32"), actix::test)] + #[cfg_attr(target_os = "wasi", wstd::test)] #[cfg(feature = "openssl_sign")] async fn test_async_dynamic_assertions() { use async_trait::async_trait; @@ -6320,7 +6406,8 @@ pub mod tests { } } - #[async_trait::async_trait] + #[cfg_attr(not(target_arch = "wasm32"), async_trait)] + #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] impl crate::AsyncSigner for DynamicSigner { async fn sign(&self, data: Vec) -> crate::error::Result> { self.0.sign(data).await @@ -6401,7 +6488,7 @@ pub mod tests { fn test_fragmented_jumbf_generation() { // test adding to actual image - let tempdir = tempdir().expect("temp dir"); + let tempdir = tempdirectory().expect("temp dir"); let output_path = tempdir.into_path(); // search folders for init segments diff --git a/sdk/src/utils/io_utils.rs b/sdk/src/utils/io_utils.rs index 4e89c4268..ed2a4e3cc 100644 --- a/sdk/src/utils/io_utils.rs +++ b/sdk/src/utils/io_utils.rs @@ -11,7 +11,13 @@ // specific language governing permissions and limitations under // each license. -use std::io::{Read, Seek, SeekFrom, Write}; +use std::{ + ffi::OsStr, + io::{Read, Seek, SeekFrom, Write}, +}; + +#[allow(unused)] // different code path for WASI +use tempfile::{tempdir, Builder, NamedTempFile, TempDir}; use crate::{Error, Result}; @@ -141,6 +147,34 @@ impl ReaderUtils for R { } } +pub(crate) fn tempfile_builder + Sized>(prefix: T) -> Result { + #[cfg(all(target_os = "wasi", target_env = "p1"))] + return Error::NotImplemented("tempfile_builder requires wasip2 or later".to_string()); + + #[cfg(all(target_os = "wasi", not(target_env = "p1")))] + return Builder::new() + .prefix(&prefix) + .rand_bytes(5) + .tempfile_in("/") + .map_err(Error::IoError); + + #[cfg(not(target_os = "wasi"))] + return Builder::new() + .prefix(&prefix) + .rand_bytes(5) + .tempfile() + .map_err(Error::IoError); +} + +#[allow(dead_code)] // used in tests +pub(crate) fn tempdirectory() -> Result { + #[cfg(target_os = "wasi")] + return TempDir::new_in("/").map_err(Error::IoError); + + #[cfg(not(target_os = "wasi"))] + return tempdir().map_err(Error::IoError); +} + #[cfg(test)] mod tests { #![allow(clippy::expect_used)] diff --git a/sdk/src/utils/test.rs b/sdk/src/utils/test.rs index 80a95e02c..511dd94f0 100644 --- a/sdk/src/utils/test.rs +++ b/sdk/src/utils/test.rs @@ -21,10 +21,8 @@ use std::{ }; use async_trait::async_trait; -#[cfg(any(feature = "openssl_sign", target_arch = "wasm32"))] -use c2pa_crypto::cose::TimeStampStorage; use c2pa_crypto::{ - cose::CertificateTrustPolicy, + cose::{CertificateTrustPolicy, TimeStampStorage}, raw_signature::{AsyncRawSigner, RawSignerError, SigningAlg}, time_stamp::{AsyncTimeStampProvider, TimeStampError}, }; @@ -190,6 +188,11 @@ pub fn create_test_store() -> Result { /// returns a path to a file in the fixtures folder pub fn fixture_path(file_name: &str) -> PathBuf { + // File paths are relative to directory specified in dir argument. + // This assumes `wasmtime --dir .` + #[cfg(target_os = "wasi")] + let mut path = PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("tests/fixtures"); path.push(file_name); @@ -386,107 +389,6 @@ impl crate::signer::RemoteSigner for TempRemoteSigner { } } -/* todo: This test should be replaced by a rust_native signer if desired to sign from wasm -#[cfg(target_arch = "wasm32")] -struct WebCryptoSigner { - signing_alg: SigningAlg, - signing_alg_name: String, - certs: Vec>, - key: Vec, -} - -#[cfg(target_arch = "wasm32")] -impl WebCryptoSigner { - pub fn new(alg: &str, cert: &str, key: &str) -> Self { - static START_CERTIFICATE: &str = "-----BEGIN CERTIFICATE-----"; - static END_CERTIFICATE: &str = "-----END CERTIFICATE-----"; - static START_KEY: &str = "-----BEGIN PRIVATE KEY-----"; - static END_KEY: &str = "-----END PRIVATE KEY-----"; - - let mut name = alg.to_owned().to_uppercase(); - name.insert(2, '-'); - - let key = key - .replace("\n", "") - .replace(START_KEY, "") - .replace(END_KEY, ""); - let key = c2pa_crypto::base64::decode(&key).unwrap(); - - let certs = cert - .replace("\n", "") - .replace(START_CERTIFICATE, "") - .split(END_CERTIFICATE) - .map(|x| c2pa_crypto::base64::decode(x).unwrap()) - .collect(); - - Self { - signing_alg: alg.parse().unwrap(), - signing_alg_name: name, - certs, - key, - } - } -} - -#[cfg(target_arch = "wasm32")] -#[async_trait::async_trait(?Send)] -impl AsyncSigner for WebCryptoSigner { - fn alg(&self) -> SigningAlg { - self.signing_alg - } - - fn certs(&self) -> Result>> { - Ok(self.certs.clone()) - } - - async fn sign(&self, claim_bytes: Vec) -> crate::error::Result> { - use c2pa_crypto::raw_signature::webcrypto::WindowOrWorker; - use js_sys::{Array, Object, Reflect, Uint8Array}; - use wasm_bindgen_futures::JsFuture; - use web_sys::CryptoKey; - let context = WindowOrWorker::new().unwrap(); - let crypto = context.subtle_crypto().unwrap(); - - let mut data = claim_bytes.clone(); - let promise = crypto - .digest_with_str_and_u8_array("SHA-256", &mut data) - .unwrap(); - let result = JsFuture::from(promise).await.unwrap(); - let mut digest = Uint8Array::new(&result).to_vec(); - - let key = Uint8Array::new_with_length(self.key.len() as u32); - key.copy_from(&self.key); - let usages = Array::new(); - usages.push(&"sign".into()); - let alg = Object::new(); - Reflect::set(&alg, &"name".into(), &"ECDSA".into()).unwrap(); - Reflect::set(&alg, &"namedCurve".into(), &"P-256".into()).unwrap(); - - let promise = crypto - .import_key_with_object("pkcs8", &key, &alg, true, &usages) - .unwrap(); - let key: CryptoKey = JsFuture::from(promise).await.unwrap().into(); - - let alg = Object::new(); - Reflect::set(&alg, &"name".into(), &"ECDSA".into()).unwrap(); - Reflect::set(&alg, &"hash".into(), &"SHA-256".into()).unwrap(); - let promise = crypto - .sign_with_object_and_u8_array(&alg, &key, &mut digest) - .unwrap(); - let result = JsFuture::from(promise).await.unwrap(); - Ok(Uint8Array::new(&result).to_vec()) - } - - fn reserve_size(&self) -> usize { - 10000 - } - - async fn send_timestamp_request(&self, _: &[u8]) -> Option>> { - None - } -} -*/ - /// Create a [`RemoteSigner`] instance that can be used for testing purposes. /// /// # Returns diff --git a/sdk/tests/common/mod.rs b/sdk/tests/common/mod.rs index ddc2bb371..f79cb6076 100644 --- a/sdk/tests/common/mod.rs +++ b/sdk/tests/common/mod.rs @@ -22,6 +22,8 @@ use std::{ use c2pa::{format_from_path, Reader, Result}; pub use compare_readers::compare_readers; +#[allow(unused)] // different code path for WASI +use tempfile::{tempdir, TempDir}; #[allow(unused)] pub use test_signer::test_signer; @@ -110,3 +112,12 @@ pub fn check_validation_status(reader: &Reader, code: &str) { panic!("Expected to find validation status"); } } + +#[allow(unused)] +pub fn tempdirectory() -> Result { + #[cfg(target_os = "wasi")] + return TempDir::new_in("/").map_err(c2pa::Error::IoError); + + #[cfg(not(target_os = "wasi"))] + return tempdir().map_err(c2pa::Error::IoError); +} diff --git a/sdk/tests/integration.rs b/sdk/tests/integration.rs index 0603c840e..2746964fd 100644 --- a/sdk/tests/integration.rs +++ b/sdk/tests/integration.rs @@ -15,7 +15,7 @@ // Isolate from wasm by wrapping in module. #[cfg(feature = "file_io")] mod integration_1 { - use std::path::PathBuf; + use std::{io, path::PathBuf}; use c2pa::{ assertions::{c2pa_action, Action, Actions}, @@ -24,7 +24,8 @@ mod integration_1 { Builder, ClaimGeneratorInfo, Ingredient, Reader, Result, Signer, }; use c2pa_crypto::raw_signature::SigningAlg; - use tempfile::tempdir; + #[allow(unused)] // different code path for WASI + use tempfile::{tempdir, TempDir}; //const GENERATOR: &str = "app"; @@ -35,14 +36,28 @@ mod integration_1 { let _protect = PROTECT.lock().unwrap(); // sign and embed into the target file + #[cfg(target_os = "wasi")] + let mut signcert_path = PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut signcert_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); signcert_path.push("tests/fixtures/certs/ps256.pub"); + #[cfg(target_os = "wasi")] + let mut pkey_path = PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut pkey_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); pkey_path.push("tests/fixtures/certs/ps256.pem"); create_signer::from_files(signcert_path, pkey_path, SigningAlg::Ps256, None) .expect("get_signer_from_files") } + fn tempdirectory() -> io::Result { + #[cfg(target_os = "wasi")] + return TempDir::new_in("/"); + + #[cfg(not(target_os = "wasi"))] + return tempdir(); + } + fn configure_trust( trust_anchors: Option, allowed_list: Option, @@ -92,10 +107,16 @@ mod integration_1 { #[cfg(feature = "file_io")] fn test_embed_manifest() -> Result<()> { // set up parent and destination paths - let dir = tempdir()?; + let dir = tempdirectory()?; let output_path = dir.path().join("test_file.jpg"); + #[cfg(target_os = "wasi")] + let mut parent_path = PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut parent_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); parent_path.push("tests/fixtures/earth_apollo17.jpg"); + #[cfg(target_os = "wasi")] + let mut ingredient_path = PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut ingredient_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); ingredient_path.push("tests/fixtures/libpng-test.png"); @@ -174,9 +195,12 @@ mod integration_1 { #[cfg(feature = "file_io")] fn test_embed_json_manifest() -> Result<()> { // set up parent and destination paths - let dir = tempdir()?; + let dir = tempdirectory()?; let output_path = dir.path().join("test_file.jpg"); + #[cfg(target_os = "wasi")] + let mut fixture_path = PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut fixture_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); fixture_path.push("tests/fixtures"); @@ -186,9 +210,15 @@ mod integration_1 { manifest_path.push("manifest.json"); let json = std::fs::read_to_string(manifest_path)?; + // + // WASI does not support canonicalize(), the path is canonical to begin with + #[cfg(target_os = "wasi")] + let base_path = fixture_path; + #[cfg(not(target_os = "wasi"))] + let base_path = fixture_path.canonicalize()?; let mut builder = Builder::from_json(&json)?; - builder.base_path = Some(fixture_path.canonicalize()?); + builder.base_path = Some(base_path); // sign and embed into the target file let signer = get_temp_signer(); @@ -214,9 +244,12 @@ mod integration_1 { #[cfg(feature = "file_io")] fn test_embed_bmff_manifest() -> Result<()> { // set up parent and destination paths - let dir = tempdir()?; + let dir = tempdirectory()?; let output_path = dir.path().join("test_bmff.heic"); + #[cfg(target_os = "wasi")] + let mut fixture_path = PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut fixture_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); fixture_path.push("tests/fixtures"); @@ -227,8 +260,14 @@ mod integration_1 { let json = std::fs::read_to_string(manifest_path)?; + // WASI does not support canonicalize(), the path is canonical to begin with + #[cfg(target_os = "wasi")] + let base_path = fixture_path; + #[cfg(not(target_os = "wasi"))] + let base_path = fixture_path.canonicalize()?; + let mut builder = Builder::from_json(&json)?; - builder.base_path = Some(fixture_path.canonicalize()?); + builder.base_path = Some(base_path); // sign and embed into the target file let signer = get_temp_signer(); @@ -302,9 +341,12 @@ mod integration_1 { // set up parent and destination paths use std::io::Seek; - let dir = tempdir()?; + let dir = tempdirectory()?; let output_path = dir.path().join("test_file.jpg"); + #[cfg(target_os = "wasi")] + let mut fixture_path = PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut fixture_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); fixture_path.push("tests/fixtures"); let mut manifest_path = fixture_path.clone(); @@ -315,7 +357,12 @@ mod integration_1 { let json = std::fs::read_to_string(manifest_path)?; let mut manifest = Manifest::from_json(&json)?; - manifest.with_base_path(fixture_path.canonicalize()?)?; + // WASI does not support canonicalize(), but the path is canonical to begin with + #[cfg(target_os = "wasi")] + let base_path = fixture_path; + #[cfg(not(target_os = "wasi"))] + let base_path = fixture_path.canonicalize()?; + manifest.with_base_path(base_path)?; // sign and embed into the target file let signer = get_temp_signer(); @@ -370,9 +417,12 @@ mod integration_1 { // set up parent and destination paths use std::io::Seek; - let dir = tempdir()?; + let dir = tempdirectory()?; let output_path = dir.path().join("video1.mp4"); + #[cfg(target_os = "wasi")] + let mut fixture_path = PathBuf::from("/"); + #[cfg(not(target_os = "wasi"))] let mut fixture_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); fixture_path.push("tests/fixtures"); let mut manifest_path = fixture_path.clone(); @@ -383,7 +433,12 @@ mod integration_1 { let json = std::fs::read_to_string(manifest_path)?; let mut manifest = Manifest::from_json(&json)?; - manifest.with_base_path(fixture_path.canonicalize()?)?; + // WASI does not support canonicalize(), but the path is canonical to begin with + #[cfg(target_os = "wasi")] + let base_path = fixture_path; + #[cfg(not(target_os = "wasi"))] + let base_path = fixture_path.canonicalize()?; + manifest.with_base_path(base_path)?; // sign and embed into the target file let signer = get_temp_signer(); diff --git a/sdk/tests/test_builder.rs b/sdk/tests/test_builder.rs index 5616c6863..9f801b095 100644 --- a/sdk/tests/test_builder.rs +++ b/sdk/tests/test_builder.rs @@ -21,7 +21,7 @@ mod common; use common::{compare_stream_to_known_good, fixtures_path, test_signer}; #[test] -#[cfg_attr(not(any(target_arch = "wasm32", feature = "openssl")), ignore)] +#[cfg(all(feature = "add_thumbnails", feature = "file_io"))] fn test_builder_ca_jpg() -> Result<()> { let manifest_def = std::fs::read_to_string(fixtures_path("simple_manifest.json"))?; let mut builder = Builder::from_json(&manifest_def)?; @@ -61,11 +61,11 @@ fn test_builder_riff() -> Result<()> { #[test] #[cfg(feature = "file_io")] fn test_builder_fragmented() -> Result<()> { - use tempfile::tempdir; + use common::tempdirectory; let manifest_def = include_str!("fixtures/simple_manifest.json"); let mut builder = Builder::from_json(manifest_def)?; - let tempdir = tempdir().expect("temp dir"); + let tempdir = tempdirectory().expect("temp dir"); let output_path = tempdir.into_path(); let mut init_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); init_path.push("tests/fixtures/bunny/**/BigBuckBunny_2s_init.mp4"); diff --git a/sdk/tests/v2_api_integration.rs b/sdk/tests/v2_api_integration.rs index 39189bd57..1b0cbff49 100644 --- a/sdk/tests/v2_api_integration.rs +++ b/sdk/tests/v2_api_integration.rs @@ -13,7 +13,6 @@ /// Complete functional integration test with acquisitions and ingredients. // Isolate from wasm by wrapping in module. -#[cfg(not(target_arch = "wasm32"))] // wasm doesn't support ed25519 yet mod integration_v2 { use std::io::{Cursor, Seek}; @@ -148,10 +147,13 @@ mod integration_v2 { dest }; - // write dest to file for debugging - let debug_path = format!("{}/../target/v2_test.jpg", env!("CARGO_MANIFEST_DIR")); - std::fs::write(debug_path, dest.get_ref())?; - dest.rewind()?; + #[cfg(not(target_os = "wasi"))] + { + // write dest to file for debugging + let debug_path = format!("{}/../target/v2_test.jpg", env!("CARGO_MANIFEST_DIR")); + std::fs::write(debug_path, dest.get_ref())?; + dest.rewind()?; + } let reader = Reader::from_stream(format, &mut dest)?;