Project import generated by Copybara. GitOrigin-RevId: 26b71fbfe58e7f60e045cec3e0f306e615590605 Change-Id: I0b6c07e747e5dd4e843f470951295cc9e04224c2
diff --git a/BUILD b/BUILD index d26eb23..db6ef52 100644 --- a/BUILD +++ b/BUILD
@@ -1,3 +1,4 @@ + # Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/common/Cargo.lock b/common/Cargo.lock index 758eb2d..496db0d 100644 --- a/common/Cargo.lock +++ b/common/Cargo.lock
@@ -34,47 +34,48 @@ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -82,9 +83,9 @@ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] name = "arbitrary" @@ -94,9 +95,9 @@ [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bit-set" @@ -163,12 +164,13 @@ [[package]] name = "cc" -version = "1.0.94" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -281,9 +283,9 @@ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "combine" @@ -466,9 +468,9 @@ [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "file-header" @@ -491,9 +493,9 @@ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -585,6 +587,12 @@ ] [[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] name = "itertools" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -635,9 +643,9 @@ [[package]] name = "jobserver" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -662,9 +670,9 @@ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "libfuzzer-sys" @@ -719,9 +727,9 @@ [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -757,9 +765,9 @@ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -849,9 +857,9 @@ [[package]] name = "prettyplease" -version = "0.2.19" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", "syn", @@ -859,9 +867,9 @@ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -1020,9 +1028,9 @@ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags", "errno", @@ -1045,9 +1053,9 @@ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -1066,18 +1074,18 @@ [[package]] name = "serde" -version = "1.0.198" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.198" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", @@ -1124,9 +1132,9 @@ [[package]] name = "syn" -version = "2.0.60" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -1147,18 +1155,18 @@ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", @@ -1306,11 +1314,11 @@ [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]]
diff --git a/nearby/presence/CMakeLists.txt b/nearby/CMakeLists.txt similarity index 92% rename from nearby/presence/CMakeLists.txt rename to nearby/CMakeLists.txt index bb099de..240cc3c 100644 --- a/nearby/presence/CMakeLists.txt +++ b/nearby/CMakeLists.txt
@@ -14,12 +14,12 @@ cmake_minimum_required(VERSION 3.14) -project(NearbyPresenceProtocol) +project(Nearby) set(CMAKE_CXX_STANDARD 20) -set(BETO_CORE_ROOT ${CMAKE_SOURCE_DIR}/../..) -set(NEARBY_ROOT ${CMAKE_SOURCE_DIR}/..) +set(BETO_CORE_ROOT ${CMAKE_SOURCE_DIR}/..) +set(NEARBY_ROOT ${CMAKE_SOURCE_DIR}) set(THIRD_PARTY_DIR ${BETO_CORE_ROOT}/third_party) set(CMAKE_C_FLAGS_DEBUG "-DDEBUG") @@ -104,5 +104,6 @@ ) endif () -add_subdirectory(np_cpp_ffi) -add_subdirectory(ldt_np_adv_ffi/c) +add_subdirectory(presence/np_cpp_ffi) +add_subdirectory(presence/ldt_np_adv_ffi/c) +add_subdirectory(connections/ukey2/ukey2_c_ffi/cpp/)
diff --git a/nearby/Cargo.lock b/nearby/Cargo.lock index e50e7b7..6eb2999 100644 --- a/nearby/Cargo.lock +++ b/nearby/Cargo.lock
@@ -21,9 +21,9 @@ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -61,9 +61,9 @@ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -91,47 +91,48 @@ [[package]] name = "anstream" -version = "0.6.12" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -139,9 +140,18 @@ [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +dependencies = [ + "derive_arbitrary", +] [[package]] name = "array_ref" @@ -164,9 +174,9 @@ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "base16ct" @@ -194,9 +204,9 @@ [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "blake2" @@ -238,9 +248,9 @@ [[package]] name = "bstr" -version = "1.6.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", "serde", @@ -252,10 +262,10 @@ dependencies = [ "anyhow", "chrono", - "clap 4.5.1", - "cmd-runner", + "clap 4.5.4", + "cmd_runner", "crossbeam", - "env_logger", + "env_logger 0.10.2", "file-header", "glob", "globset", @@ -268,26 +278,26 @@ "tempfile", "thiserror", "walkdir", - "which", + "xshell", ] [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cast" @@ -311,7 +321,7 @@ checksum = "da6bc11b07529f16944307272d5bd9b22530bc7d05751717c9d416586cedab49" dependencies = [ "clap 3.2.25", - "heck", + "heck 0.4.1", "indexmap", "log", "proc-macro2", @@ -325,9 +335,14 @@ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" +dependencies = [ + "jobserver", + "libc", + "once_cell", +] [[package]] name = "cesu8" @@ -343,21 +358,23 @@ [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", + "js-sys", "num-traits", - "windows-targets 0.52.3", + "wasm-bindgen", + "windows-targets 0.52.5", ] [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -366,15 +383,15 @@ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", "half", @@ -407,9 +424,9 @@ [[package]] name = "clap" -version = "4.5.1" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -417,26 +434,26 @@ [[package]] name = "clap_builder" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", "clap_lex 0.7.0", - "strsim 0.11.0", + "strsim 0.11.1", ] [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.61", ] [[package]] @@ -455,25 +472,31 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] -name = "cmd-runner" +name = "cmd_runner" version = "0.1.0" dependencies = [ "anyhow", + "chrono", + "clap 4.5.4", + "file-header", + "globset", + "log", "owo-colors", "shell-escape", + "xshell", ] [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "combine" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "memchr", @@ -481,30 +504,30 @@ [[package]] name = "const-oid" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -518,10 +541,10 @@ "anes", "cast", "ciborium", - "clap 4.5.1", + "clap 4.5.4", "criterion-plot", "is-terminal", - "itertools", + "itertools 0.10.5", "num-traits", "once_cell", "oorandom", @@ -542,16 +565,15 @@ checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] name = "crossbeam" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" dependencies = [ - "cfg-if", "crossbeam-channel", "crossbeam-deque", "crossbeam-epoch", @@ -561,65 +583,61 @@ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", - "rand_core 0.6.4", + "rand_core", "subtle", "zeroize", ] @@ -631,7 +649,7 @@ checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core 0.6.4", + "rand_core", "typenum", ] @@ -686,7 +704,7 @@ "p256", "rand", "rand_chacha", - "rand_core 0.6.4", + "rand_core", "sec1", "sha2", "subtle", @@ -716,6 +734,16 @@ ] [[package]] +name = "crypto_provider_test-fuzz" +version = "0.0.0" +dependencies = [ + "crypto_provider", + "crypto_provider_default", + "derive_fuzztest", + "libfuzzer-sys", +] + +[[package]] name = "ctr" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -726,9 +754,9 @@ [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ "cfg-if", "cpufeatures", @@ -743,26 +771,55 @@ [[package]] name = "curve25519-dalek-derive" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.61", ] [[package]] name = "der" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", ] [[package]] +name = "derive_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", +] + +[[package]] +name = "derive_fuzztest" +version = "0.1.0" +dependencies = [ + "arbitrary", + "derive_fuzztest_macro", + "quickcheck", +] + +[[package]] +name = "derive_fuzztest_macro" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", +] + +[[package]] name = "diff" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -781,9 +838,9 @@ [[package]] name = "ed25519" -version = "2.2.1" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb04eee5d9d907f29e80ee6b0e78f7e2c82342c63e3580d8c4f69d9d5aad963" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", "signature", @@ -797,7 +854,7 @@ dependencies = [ "curve25519-dalek", "ed25519", - "rand_core 0.6.4", + "rand_core", "serde", "sha2", "subtle", @@ -806,15 +863,15 @@ [[package]] name = "either" -version = "1.9.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -823,7 +880,7 @@ "generic-array", "group", "hkdf", - "rand_core 0.6.4", + "rand_core", "sec1", "subtle", "zeroize", @@ -831,6 +888,16 @@ [[package]] name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" @@ -854,9 +921,9 @@ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "ff" @@ -864,15 +931,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "rand_core 0.6.4", + "rand_core", "subtle", ] [[package]] name = "fiat-crypto" -version = "0.2.2" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a481586acf778f1b1455424c343f71124b048ffa5f4fc3f8f6ae9dc432dcb3c7" +checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e" [[package]] name = "file-header" @@ -889,21 +956,15 @@ [[package]] name = "flate2" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", ] [[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] name = "generic-array" version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -916,9 +977,9 @@ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -927,9 +988,9 @@ [[package]] name = "ghash" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", "polyval", @@ -943,15 +1004,15 @@ [[package]] name = "globset" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aca8bbd8e0707c1887a8bbb7e6b40e228f251ff5d62c8220a4a7a53c73aff006" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata", + "regex-syntax", ] [[package]] @@ -961,22 +1022,24 @@ checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core", "subtle", ] [[package]] name = "half" -version = "1.8.2" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] [[package]] name = "handle_map" version = "0.1.0" dependencies = [ - "criterion", - "lazy_static", "lock_adapter", ] @@ -1007,6 +1070,12 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] name = "hermit-abi" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1017,9 +1086,9 @@ [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1035,9 +1104,9 @@ [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac", ] @@ -1052,6 +1121,15 @@ ] [[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1059,16 +1137,16 @@ [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -1102,16 +1180,22 @@ [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.2", - "rustix", - "windows-sys 0.48.0", + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.52.0", ] [[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] name = "itertools" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1121,20 +1205,19 @@ ] [[package]] -name = "itoa" -version = "1.0.9" +name = "itertools" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] [[package]] -name = "java-locator" -version = "0.1.5" +name = "itoa" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90003f2fd9c52f212c21d8520f1128da0080bad6fff16b68fe6e7f2f0c3780c2" -dependencies = [ - "glob", - "lazy_static", -] +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jni" @@ -1145,9 +1228,7 @@ "cesu8", "cfg-if", "combine", - "java-locator", "jni-sys", - "libloading", "log", "thiserror", "walkdir", @@ -1161,10 +1242,19 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] -name = "js-sys" -version = "0.3.64" +name = "jobserver" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -1186,7 +1276,7 @@ "anyhow", "base64", "blake2", - "clap 4.5.1", + "clap 4.5.4", "criterion", "crypto_provider", "crypto_provider_default", @@ -1206,6 +1296,32 @@ ] [[package]] +name = "ldt-fuzz" +version = "0.1.0" +dependencies = [ + "arbitrary", + "crypto_provider_rustcrypto", + "derive_fuzztest", + "ldt", + "libfuzzer-sys", + "xts_aes", +] + +[[package]] +name = "ldt-np-adv-fuzz" +version = "0.1.0" +dependencies = [ + "arbitrary", + "crypto_provider_rustcrypto", + "derive_fuzztest", + "ldt", + "ldt_np_adv", + "libfuzzer-sys", + "np_hkdf", + "xts_aes", +] + +[[package]] name = "ldt_np_adv" version = "0.1.0" dependencies = [ @@ -1225,6 +1341,7 @@ "rand_pcg", "serde_json", "test_helper", + "test_vector_hkdf", "xts_aes", ] @@ -1265,25 +1382,26 @@ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] -name = "libloading" -version = "0.7.4" +name = "libfuzzer-sys" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" dependencies = [ - "cfg-if", - "winapi", + "arbitrary", + "cc", + "once_cell", ] [[package]] name = "license" -version = "3.2.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778718185117620a06e95d2b1e57d50166b1d6bfad93c8abfc1b3344c863ad8c" +checksum = "3bba2f02ee1d13cd4bea565658939cd851d70e391f34f7c27b45b2077df3a2e4" dependencies = [ "reword", "serde", @@ -1305,9 +1423,9 @@ [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1315,24 +1433,15 @@ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "minimal-lexical" @@ -1342,9 +1451,9 @@ [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] @@ -1383,6 +1492,7 @@ "strum", "strum_macros", "test_helper", + "test_vector_hkdf", "tinyvec", "xts_aes", ] @@ -1394,6 +1504,7 @@ "array_view", "crypto_provider", "np_adv", + "np_hkdf", "sink", ] @@ -1430,6 +1541,8 @@ "np_adv", "np_adv_dynamic", "np_hkdf", + "strum", + "strum_macros", ] [[package]] @@ -1446,54 +1559,56 @@ "rand_ext", "serde_json", "test_helper", + "test_vector_hkdf", "xts_aes", ] [[package]] -name = "num-bigint" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +name = "np_java_ffi" +version = "0.1.0" dependencies = [ - "autocfg", + "crypto_provider_default", + "handle_map", + "jni", + "np_adv", + "np_ffi_core", + "pourover", + "pourover_macro", +] + +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ "num-integer", "num-traits", ] [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.2", - "libc", -] - -[[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" @@ -1503,15 +1618,15 @@ [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "os_str_bytes" -version = "6.5.1" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "owo-colors" @@ -1541,9 +1656,9 @@ [[package]] name = "platforms" -version = "3.0.2" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" [[package]] name = "plotters" @@ -1575,9 +1690,9 @@ [[package]] name = "polyval" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", @@ -1597,16 +1712,10 @@ name = "pourover_macro" version = "0.1.0" dependencies = [ - "pourover_macro_core", -] - -[[package]] -name = "pourover_macro_core" -version = "0.1.0" -dependencies = [ + "nom", "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.61", ] [[package]] @@ -1617,18 +1726,18 @@ [[package]] name = "primeorder" -version = "0.13.2" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ "elliptic-curve", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -1685,10 +1794,21 @@ ] [[package]] -name = "quote" -version = "1.0.35" +name = "quickcheck" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" +dependencies = [ + "env_logger 0.8.4", + "log", + "rand", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1701,7 +1821,7 @@ dependencies = [ "libc", "rand_chacha", - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -1711,17 +1831,11 @@ checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", + "rand_core", ] [[package]] name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - -[[package]] -name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" @@ -1730,14 +1844,6 @@ ] [[package]] -name = "rand_core_05_adapter" -version = "0.1.0" -dependencies = [ - "rand", - "rand_core 0.5.1", -] - -[[package]] name = "rand_ext" version = "0.1.0" dependencies = [ @@ -1753,14 +1859,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" dependencies = [ - "rand_core 0.6.4", + "rand_core", ] [[package]] name = "rayon" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -1768,21 +1874,19 @@ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "regex" -version = "1.10.2" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -1792,9 +1896,9 @@ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -1803,15 +1907,15 @@ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "relative-path" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "reword" @@ -1845,7 +1949,7 @@ "regex", "relative-path", "rustc_version", - "syn 2.0.50", + "syn 2.0.61", "unicode-ident", ] @@ -1858,7 +1962,7 @@ "quote", "rand", "rustc_version", - "syn 2.0.50", + "syn 2.0.61", ] [[package]] @@ -1872,11 +1976,11 @@ [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -1885,15 +1989,15 @@ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -1925,35 +2029,35 @@ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.61", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", @@ -1979,9 +2083,12 @@ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core", +] [[package]] name = "sink" @@ -2007,9 +2114,9 @@ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -2023,9 +2130,9 @@ [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" @@ -2039,11 +2146,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", - "syn 2.0.50", + "syn 2.0.61", ] [[package]] @@ -2065,9 +2172,9 @@ [[package]] name = "syn" -version = "2.0.50" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -2076,9 +2183,9 @@ [[package]] name = "tempfile" -version = "3.10.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", @@ -2088,9 +2195,9 @@ [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -2100,33 +2207,42 @@ version = "0.1.0" dependencies = [ "hex", + "itertools 0.12.1", "serde_json", ] [[package]] +name = "test_vector_hkdf" +version = "0.1.0" +dependencies = [ + "crypto_provider", + "crypto_provider_default", +] + +[[package]] name = "textwrap" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.61", ] [[package]] @@ -2156,9 +2272,9 @@ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ukey2_c_ffi" @@ -2172,7 +2288,6 @@ "rand", "rand_chacha", "ukey2_connections", - "ukey2_rs", ] [[package]] @@ -2191,6 +2306,19 @@ ] [[package]] +name = "ukey2_connections-fuzz" +version = "0.1.0" +dependencies = [ + "arbitrary", + "crypto_provider_rustcrypto", + "derive_fuzztest", + "libfuzzer-sys", + "rand_chacha", + "ukey2_connections", + "ukey2_rs", +] + +[[package]] name = "ukey2_jni" version = "0.1.0" dependencies = [ @@ -2203,7 +2331,6 @@ "rand", "rand_chacha", "ukey2_connections", - "ukey2_rs", ] [[package]] @@ -2232,23 +2359,22 @@ name = "ukey2_shell" version = "0.1.0" dependencies = [ - "clap 4.5.1", + "clap 4.5.4", "crypto_provider_rustcrypto", "ukey2_connections", - "ukey2_rs", ] [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "universal-hash" @@ -2274,9 +2400,9 @@ [[package]] name = "walkdir" -version = "2.3.3" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -2290,9 +2416,9 @@ [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2300,24 +2426,24 @@ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.61", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2325,28 +2451,28 @@ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.61", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -2354,13 +2480,14 @@ [[package]] name = "which" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", - "libc", + "home", "once_cell", + "rustix", ] [[package]] @@ -2381,11 +2508,11 @@ [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2395,12 +2522,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.52.5", ] [[package]] @@ -2414,20 +2541,11 @@ [[package]] name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.1", -] - -[[package]] -name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.3", + "windows-targets 0.52.5", ] [[package]] @@ -2447,32 +2565,18 @@ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", -] - -[[package]] -name = "windows-targets" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" -dependencies = [ - "windows_aarch64_gnullvm 0.52.3", - "windows_aarch64_msvc 0.52.3", - "windows_i686_gnu 0.52.3", - "windows_i686_msvc 0.52.3", - "windows_x86_64_gnu 0.52.3", - "windows_x86_64_gnullvm 0.52.3", - "windows_x86_64_msvc 0.52.3", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -2483,15 +2587,9 @@ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -2501,15 +2599,9 @@ [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -2519,15 +2611,15 @@ [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" [[package]] -name = "windows_i686_gnu" -version = "0.52.3" +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -2537,15 +2629,9 @@ [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -2555,15 +2641,9 @@ [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -2573,15 +2653,9 @@ [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -2591,15 +2665,9 @@ [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "wycheproof" @@ -2615,12 +2683,40 @@ [[package]] name = "x25519-dalek" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ "curve25519-dalek", - "rand_core 0.6.4", + "rand_core", +] + +[[package]] +name = "xshell" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db0ab86eae739efd1b054a8d3d16041914030ac4e01cd1dca0cf252fd8b6437" +dependencies = [ + "xshell-macros", +] + +[[package]] +name = "xshell-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d422e8e38ec76e2f06ee439ccc765e9c6a9638b9e7c9f2e8255e4d41e8bd852" + +[[package]] +name = "xts-aes-fuzz" +version = "0.0.0" +dependencies = [ + "arbitrary", + "crypto_provider", + "crypto_provider_rustcrypto", + "derive_fuzztest", + "ldt_tbc", + "libfuzzer-sys", + "xts_aes", ] [[package]] @@ -2656,6 +2752,6 @@ [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
diff --git a/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt b/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt index a8b7b9d..61f19ee 100644 --- a/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt +++ b/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt
@@ -14,14 +14,8 @@ cmake_minimum_required(VERSION 3.14) -project(Ukey2) - -enable_testing() - include_directories( ${CMAKE_SOURCE_DIR}/ukey2_c_ffi/cpp/) - -include(GoogleTest) include(ExternalProject) set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/target/tmp) @@ -30,30 +24,10 @@ DOWNLOAD_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND cargo build COMMAND cargo build --release --lib - BINARY_DIR "${CMAKE_SOURCE_DIR}/ukey2_c_ffi" + BINARY_DIR "${NEARBY_ROOT}/connections/ukey2/ukey2_c_ffi" INSTALL_COMMAND "") -# required for designated initializers on MSVC -set(CMAKE_CXX_STANDARD 20) - -if(UNIX) - add_compile_options(-Wall -Wextra -Wimplicit-fallthrough -Wextra-semi - -Wno-missing-field-initializers -Wno-unused-parameter -Wno-psabi - -Wshadow - -Wsign-compare) -elseif(MSVC) - add_compile_options(-W4 -MD) -endif() - -include(FetchContent) -FetchContent_Declare( - googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.12.1 -) -FetchContent_MakeAvailable(googletest) - -add_executable(ffi_test +add_executable(ukey2_ffi_test ukey2_test.cc ukey2_glue.cc ukey2_ffi.h @@ -63,24 +37,24 @@ if(UNIX) target_link_libraries( - ffi_test - "${CMAKE_SOURCE_DIR}/../../../../target/release/${ukey2_c_ffi_FILENAME}" + ukey2_ffi_test + "${NEARBY_ROOT}/target/release/${ukey2_c_ffi_FILENAME}" GTest::gtest_main dl pthread ) elseif(MSVC) # MSVC requires linking to a static lib, which rust kindly generates target_link_libraries( - ffi_test - "${CMAKE_SOURCE_DIR}/../../../../target/release/${ukey2_c_ffi_FILENAME}${CMAKE_STATIC_LIBRARY_SUFFIX}" + ukey2_ffi_test + "${NEARBY_ROOT}/target/release/${ukey2_c_ffi_FILENAME}${CMAKE_STATIC_LIBRARY_SUFFIX}" GTest::gtest_main ) # MSVC requires that the dynamic lib be visible to the binary, and copying to the binary dir is an easy way to do that - get_target_property(ffi_test_BINARY_DIR ffi_test BINARY_DIR) + get_target_property(ukey2_ffi_test_BINARY_DIR ukey2_ffi_test BINARY_DIR) add_custom_command( - TARGET ffi_test POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/../../../../target/release/${ukey2_c_ffi_FILENAME}" "${ffi_test_BINARY_DIR}/." + TARGET ukey2_ffi_test POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${NEARBY_ROOT}/target/release/${ukey2_c_ffi_FILENAME}" "${ukey2_ffi_test_BINARY_DIR}/." ) endif() -gtest_discover_tests(ffi_test) +gtest_discover_tests(ukey2_ffi_test)
diff --git a/nearby/presence/ldt_np_adv_ffi/c/CMakeLists.txt b/nearby/presence/ldt_np_adv_ffi/c/CMakeLists.txt index 476b228..db16cc9 100644 --- a/nearby/presence/ldt_np_adv_ffi/c/CMakeLists.txt +++ b/nearby/presence/ldt_np_adv_ffi/c/CMakeLists.txt
@@ -32,7 +32,7 @@ BINARY_DIR "${NEARBY_ROOT}/target/" INSTALL_COMMAND "") -include_directories(${CMAKE_SOURCE_DIR}/ldt_np_adv_ffi/c/include/) +include_directories(${NEARBY_ROOT}/presence/ldt_np_adv_ffi/c/include/) add_subdirectory(sample)
diff --git a/nearby/presence/ldt_np_adv_ffi/c/tests/CMakeLists.txt b/nearby/presence/ldt_np_adv_ffi/c/tests/CMakeLists.txt index a4cbc24..8bd42b7 100644 --- a/nearby/presence/ldt_np_adv_ffi/c/tests/CMakeLists.txt +++ b/nearby/presence/ldt_np_adv_ffi/c/tests/CMakeLists.txt
@@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -file(COPY ${CMAKE_SOURCE_DIR}/ldt_np_adv/resources/test/np_adv_test_vectors.json +file(COPY ${NEARBY_ROOT}/presence/ldt_np_adv/resources/test/np_adv_test_vectors.json DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) add_executable(
diff --git a/nearby/presence/np_adv/Cargo.toml b/nearby/presence/np_adv/Cargo.toml index 5a72ecd..6670192 100644 --- a/nearby/presence/np_adv/Cargo.toml +++ b/nearby/presence/np_adv/Cargo.toml
@@ -23,7 +23,7 @@ tinyvec.workspace = true [features] -default = [] +default = ["alloc"] devtools = [] testing = [] alloc = ["crypto_provider/alloc"]
diff --git a/nearby/presence/np_c_ffi/include/c/np_c_ffi.h b/nearby/presence/np_c_ffi/include/c/np_c_ffi.h index 0eb9ecd..d84a49a 100644 --- a/nearby/presence/np_c_ffi/include/c/np_c_ffi.h +++ b/nearby/presence/np_c_ffi/include/c/np_c_ffi.h
@@ -1179,14 +1179,6 @@ */ typedef struct { uint64_t handle_id; -} np_ffi_V0AdvertisementBuilderHandle; - -/** - * A handle to a builder for V0 advertisements. - */ -typedef struct { - np_ffi_AdvertisementBuilderKind kind; - np_ffi_V0AdvertisementBuilderHandle handle; } np_ffi_V0AdvertisementBuilder; /**
diff --git a/nearby/presence/np_c_ffi/include/cpp/np_cpp_ffi_types.h b/nearby/presence/np_c_ffi/include/cpp/np_cpp_ffi_types.h index ba3ed34..0206f80 100644 --- a/nearby/presence/np_c_ffi/include/cpp/np_cpp_ffi_types.h +++ b/nearby/presence/np_c_ffi/include/cpp/np_cpp_ffi_types.h
@@ -869,14 +869,8 @@ }; /// A `#[repr(C)]` handle to a value of type `V0AdvertisementBuilderInternals` -struct V0AdvertisementBuilderHandle { - uint64_t handle_id; -}; - -/// A handle to a builder for V0 advertisements. struct V0AdvertisementBuilder { - AdvertisementBuilderKind kind; - V0AdvertisementBuilderHandle handle; + uint64_t handle_id; }; /// The result of attempting to serialize the contents
diff --git a/nearby/presence/np_c_ffi/src/serialize/v0.rs b/nearby/presence/np_c_ffi/src/serialize/v0.rs index 867c33b..e1d99ea 100644 --- a/nearby/presence/np_c_ffi/src/serialize/v0.rs +++ b/nearby/presence/np_c_ffi/src/serialize/v0.rs
@@ -52,7 +52,7 @@ pub extern "C" fn np_ffi_deallocate_v0_advertisement_builder( adv_builder: V0AdvertisementBuilder, ) -> DeallocateResult { - adv_builder.deallocate() + adv_builder.deallocate_handle() } /// Creates a new V0 advertisement builder for a public advertisement.
diff --git a/nearby/presence/np_cpp_ffi/CMakeLists.txt b/nearby/presence/np_cpp_ffi/CMakeLists.txt index 7071bbd..b2bef4a 100644 --- a/nearby/presence/np_cpp_ffi/CMakeLists.txt +++ b/nearby/presence/np_cpp_ffi/CMakeLists.txt
@@ -20,10 +20,10 @@ target_include_directories(nearby_protocol PUBLIC include/ - ${CMAKE_SOURCE_DIR}/np_c_ffi/include/cpp/) + ${NEARBY_ROOT}/presence/np_c_ffi/include/cpp/) target_include_directories(nearby_protocol PRIVATE - ${CMAKE_SOURCE_DIR}/np_c_ffi/include/cpp/internal/) + ${NEARBY_ROOT}/presence/np_c_ffi/include/cpp/internal/) add_subdirectory(sample)
diff --git a/nearby/presence/np_cpp_ffi/tests/v0_unencrypted_deserialization_tests.cc b/nearby/presence/np_cpp_ffi/tests/v0_unencrypted_deserialization_tests.cc index 42819d6..59d6b69 100644 --- a/nearby/presence/np_cpp_ffi/tests/v0_unencrypted_deserialization_tests.cc +++ b/nearby/presence/np_cpp_ffi/tests/v0_unencrypted_deserialization_tests.cc
@@ -135,7 +135,7 @@ ASSERT_EQ(de.GetKind(), nearby_protocol::V0DataElementKind::Actions); auto actions = de.AsActions(); - ASSERT_EQ(actions.GetAsU32(), 0x40400000); + ASSERT_EQ(actions.GetAsU32(), 0x40400000U); ASSERT_TRUE(actions.HasAction(nearby_protocol::ActionType::CrossDevSdk)); ASSERT_TRUE(actions.HasAction(nearby_protocol::ActionType::NearbyShare));
diff --git a/nearby/presence/np_ffi_core/src/common.rs b/nearby/presence/np_ffi_core/src/common.rs index 592e1cd..da7cb5c 100644 --- a/nearby/presence/np_ffi_core/src/common.rs +++ b/nearby/presence/np_ffi_core/src/common.rs
@@ -208,6 +208,12 @@ } } +impl<const N: usize> From<[u8; N]> for FixedSizeArray<N> { + fn from(arr: [u8; N]) -> Self { + Self(arr) + } +} + impl<const N: usize> ByteBuffer<N> { /// Constructs a byte-buffer from a Rust-side-derived /// ArrayView, which is assumed to be trusted to be
diff --git a/nearby/presence/np_ffi_core/src/deserialize.rs b/nearby/presence/np_ffi_core/src/deserialize.rs index dffa8d1..b5e9c91 100644 --- a/nearby/presence/np_ffi_core/src/deserialize.rs +++ b/nearby/presence/np_ffi_core/src/deserialize.rs
@@ -284,6 +284,12 @@ } } + /// Unwraps the buffer of decrypted bytes. This is for Rust usage. This takes ownership of the + /// handle and deallocates it. + pub fn take_buffer(self) -> Result<Box<[u8]>, HandleNotPresentError> { + self.deallocate().map(|internals| internals.decrypted_bytes) + } + /// Frees the underlying decrypted metadata buffer. This takes ownership of the handle. pub fn deallocate_metadata(self) -> DeallocateResult { self.deallocate().map(|_| ()).into()
diff --git a/nearby/presence/np_ffi_core/src/deserialize/v1.rs b/nearby/presence/np_ffi_core/src/deserialize/v1.rs index af54fec..6007975 100644 --- a/nearby/presence/np_ffi_core/src/deserialize/v1.rs +++ b/nearby/presence/np_ffi_core/src/deserialize/v1.rs
@@ -209,6 +209,36 @@ }; section.get_de(de_index) } + + /// Gets identity details for the legible section at the given index. Similar to + /// `get_section().get_identity_details()` but will only lock the HandleMap once. This function + /// uses this handle but does not take ownership of it. + pub fn get_section_identity_details( + &self, + legible_section_index: u8, + ) -> GetV1IdentityDetailsResult { + let Ok(sections) = self.get() else { + return GetV1IdentityDetailsResult::Error; + }; + let Some(section) = sections.get_section_internals(legible_section_index) else { + return GetV1IdentityDetailsResult::Error; + }; + section.get_identity_details() + } + + /// Decrypts metadata for the legible section at the given index. Similar to + /// `get_section().decrypt_metadata()` but will only lock the HandleMap once. This function + /// uses this handle but does not take ownership of it. The caller is given owenership of the + /// handle in the result if present. + pub fn decrypt_section_metadata(&self, legible_section_index: u8) -> DecryptMetadataResult { + let Ok(sections) = self.get() else { + return DecryptMetadataResult::Error; + }; + let Some(section) = sections.get_section_internals(legible_section_index) else { + return DecryptMetadataResult::Error; + }; + section.decrypt_metadata() + } } /// Discriminant for `GetV1SectionResult`
diff --git a/nearby/presence/np_ffi_core/src/serialize/v0.rs b/nearby/presence/np_ffi_core/src/serialize/v0.rs index 736925b..e1b8103 100644 --- a/nearby/presence/np_ffi_core/src/serialize/v0.rs +++ b/nearby/presence/np_ffi_core/src/serialize/v0.rs
@@ -15,31 +15,31 @@ use crate::common::*; use crate::credentials::V0BroadcastCredential; -use crate::serialize::AdvertisementBuilderKind; use crate::utils::FfiEnum; use crate::v0::V0DataElement; use crypto_provider_default::CryptoProviderImpl; use handle_map::{declare_handle_map, HandleLike, HandleMapFullError}; use np_adv_dynamic::legacy::BoxedAdvConstructionError; -/// A handle to a builder for V0 advertisements. -#[derive(Clone, Copy)] +/// A `#[repr(C)]` handle to a value of type `V0AdvertisementBuilderInternals` #[repr(C)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct V0AdvertisementBuilder { - kind: AdvertisementBuilderKind, - handle: V0AdvertisementBuilderHandle, + handle_id: u64, } -impl V0AdvertisementBuilder { - /// Gets the kind of advertisement builder (public/encrypted). - pub fn kind(&self) -> AdvertisementBuilderKind { - self.kind - } +declare_handle_map!( + advertisement_builder, + crate::common::default_handle_map_dimensions(), + super::V0AdvertisementBuilder, + super::V0AdvertisementBuilderInternals +); +impl V0AdvertisementBuilder { /// Attempts to add the given data element to the V0 advertisement builder behind this handle. /// This function does not take ownership of the handle. pub fn add_de(&self, de: V0DataElement) -> Result<AddV0DEResult, InvalidStackDataStructure> { - match self.handle.get_mut() { + match self.get_mut() { Ok(mut adv_builder_write_guard) => adv_builder_write_guard.add_de(de), Err(_) => Ok(AddV0DEResult::InvalidAdvertisementBuilderHandle), } @@ -47,15 +47,15 @@ /// Attempts to serialize the contents of the advertisement builder behind this handle to /// bytes. This function takes ownership of the handle. pub fn into_advertisement(self) -> SerializeV0AdvertisementResult { - match self.handle.deallocate() { + match self.deallocate() { Ok(adv_builder) => adv_builder.into_advertisement(), Err(_) => SerializeV0AdvertisementResult::InvalidAdvertisementBuilderHandle, } } /// Attempts to deallocate the V0 advertisement builder behind this handle. This function takes /// ownership of the handle. - pub fn deallocate(self) -> DeallocateResult { - self.handle.deallocate().map(|_| ()).into() + pub fn deallocate_handle(self) -> DeallocateResult { + self.deallocate().map(|_| ()).into() } } @@ -113,9 +113,7 @@ /// Creates a new V0 advertisement builder for a public advertisement. The caller is given /// ownership of the created handle. pub fn create_v0_public_advertisement_builder() -> CreateV0AdvertisementBuilderResult { - V0AdvertisementBuilderHandle::allocate(V0AdvertisementBuilderInternals::new_public) - .map(|handle| V0AdvertisementBuilder { kind: AdvertisementBuilderKind::Public, handle }) - .into() + V0AdvertisementBuilder::allocate(V0AdvertisementBuilderInternals::new_public).into() } /// Creates a new V0 advertisement builder for an encrypted advertisement. The caller is given @@ -124,10 +122,9 @@ broadcast_cred: V0BroadcastCredential, salt: FixedSizeArray<2>, ) -> CreateV0AdvertisementBuilderResult { - V0AdvertisementBuilderHandle::allocate(move || { + V0AdvertisementBuilder::allocate(move || { V0AdvertisementBuilderInternals::new_ldt(broadcast_cred, salt.into_array()) }) - .map(|handle| V0AdvertisementBuilder { kind: AdvertisementBuilderKind::Encrypted, handle }) .into() } @@ -186,6 +183,7 @@ pub(crate) fn new_public() -> Self { Self::new(np_adv::legacy::serialize::UnencryptedEncoder.into()) } + pub(crate) fn new_ldt(broadcast_cred: V0BroadcastCredential, salt: [u8; 2]) -> Self { // TODO: What do about salts? Need to prevent re-use fo the same salt, // but have no current rich representation of used salts... @@ -194,11 +192,13 @@ let identity = np_adv::legacy::serialize::LdtEncoder::new(salt, &internal_broadcast_cred); Self::new(identity.into()) } + fn new(encoder: np_adv_dynamic::legacy::BoxedEncoder<CryptoProviderImpl>) -> Self { let adv_builder = np_adv_dynamic::legacy::BoxedAdvBuilder::<CryptoProviderImpl>::new(encoder); Self { adv_builder } } + fn add_de(&mut self, de: V0DataElement) -> Result<AddV0DEResult, InvalidStackDataStructure> { let to_boxed = np_adv_dynamic::legacy::ToBoxedSerializeDataElement::try_from(de)?; use np_adv::legacy::serialize::AddDataElementError; @@ -213,6 +213,7 @@ )) => Ok(AddV0DEResult::InsufficientAdvertisementSpace), } } + fn into_advertisement(self) -> SerializeV0AdvertisementResult { self.adv_builder .into_advertisement() @@ -230,20 +231,6 @@ } } -/// A `#[repr(C)]` handle to a value of type `V0AdvertisementBuilderInternals` -#[repr(C)] -#[derive(Clone, Copy, PartialEq, Eq)] -struct V0AdvertisementBuilderHandle { - handle_id: u64, -} - -declare_handle_map!( - advertisement_builder, - crate::common::default_handle_map_dimensions(), - super::V0AdvertisementBuilderHandle, - super::V0AdvertisementBuilderInternals -); - /// Result code for the operation of adding a DE to a V0 /// advertisement builder. #[derive(Clone, Copy)]
diff --git a/nearby/presence/np_java_ffi/build.gradle.kts b/nearby/presence/np_java_ffi/build.gradle.kts index 69d73c4..c502cdb 100644 --- a/nearby/presence/np_java_ffi/build.gradle.kts +++ b/nearby/presence/np_java_ffi/build.gradle.kts
@@ -50,5 +50,10 @@ tasks.test { useJUnitPlatform() - jvmArgs = mutableListOf("-Djava.library.path=$projectDir/../../target/debug") + jvmArgs = mutableListOf( + // libnp_java_ffi.so + "-Djava.library.path=$projectDir/../../target/debug", + // ByteBuddy agent for mocks + "-XX:+EnableDynamicAgentLoading" + ) }
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializeResult.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializeResult.java index 865df41..c0dc922 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializeResult.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializeResult.java
@@ -20,6 +20,7 @@ import androidx.annotation.IntDef; import androidx.annotation.Nullable; +import com.google.android.nearby.presence.rust.credential.CredentialBook; import java.lang.annotation.Retention; /** @@ -30,7 +31,8 @@ * reasons. That condition is reported on the advertisement object itself since a V1 advertisement * may be partially legible (some sections are legible, not all). */ -public final class DeserializeResult implements AutoCloseable { +public final class DeserializeResult<M extends CredentialBook.MatchedMetadata> + implements AutoCloseable { @IntDef({ Kind.UNKNOWN_ERROR, @@ -92,11 +94,11 @@ * @return the contained V0 advertisement or {@code null} if not present */ @Nullable - public DeserializedV0Advertisement getAsV0() { + public DeserializedV0Advertisement<M> getAsV0() { if (this.kind != Kind.V0_ADVERTISEMENT) { return null; } - return (DeserializedV0Advertisement) this.advertisement; + return (DeserializedV0Advertisement<M>) this.advertisement; } /** @@ -105,7 +107,7 @@ * @return the contained V1 advertisement or {@code null} if not present */ @Nullable - public DeserializedV1Advertisement getAsV1() { + public DeserializedV1Advertisement<M> getAsV1() { if (this.kind != Kind.V1_ADVERTISEMENT) { return null; }
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV0Advertisement.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV0Advertisement.java index e4a0688..cb557c5 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV0Advertisement.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV0Advertisement.java
@@ -17,6 +17,7 @@ package com.google.android.nearby.presence.rust; import androidx.annotation.Nullable; +import com.google.android.nearby.presence.rust.credential.CredentialBook; import java.util.Iterator; /** @@ -24,8 +25,8 @@ * handle. If this class is closed then the underlying handle will be closed too. Methods on this * class should not be called if {@link #close()} has already been called. */ -public final class DeserializedV0Advertisement extends DeserializedAdvertisement { - +public final class DeserializedV0Advertisement<M extends CredentialBook.MatchedMetadata> + extends DeserializedAdvertisement { public static boolean isLegibleIdentity(@IdentityKind int identity) { return identity > 0; } @@ -33,6 +34,7 @@ private final int numDataElements; private final @Nullable V0Payload payload; private final @IdentityKind int identity; + private final CredentialBook<M> credentialBook; /** Create an illegible instance with the given error identity. */ /* package */ DeserializedV0Advertisement(@IdentityKind int illegibleIdentity) { @@ -43,14 +45,19 @@ this.numDataElements = 0; this.payload = null; this.identity = illegibleIdentity; + this.credentialBook = null; } /** Create a legible instance with the given information. */ /* package */ DeserializedV0Advertisement( - int numDataElements, V0Payload payload, @IdentityKind int identity) { + int numDataElements, + V0Payload payload, + @IdentityKind int identity, + CredentialBook<M> credentialBook) { this.numDataElements = numDataElements; this.payload = payload; this.identity = identity; + this.credentialBook = credentialBook; } /** @@ -59,8 +66,11 @@ * on the native side. */ /* package */ DeserializedV0Advertisement( - int numDataElements, long payload, @IdentityKind int identity) { - this(numDataElements, new V0Payload(payload), identity); + int numDataElements, + long payload, + @IdentityKind int identity, + CredentialBook<M> credentialBook) { + this(numDataElements, new V0Payload(payload), identity, credentialBook); } /** Check if this advertisement is legible */ @@ -122,6 +132,56 @@ } } + /** + * Gets the identity token for the credential this advertisement was deserialized with. This will + * return {@code null} if this advertisement is not an encrypted advertisement. + */ + @Nullable + public byte[] getIdentityToken() { + ensureLegible("get identity token"); + + V0Payload.IdentityDetails details = payload.getIdentityDetails(); + return (details != null) ? details.getIdentityToken() : null; + } + + /** + * Gets the salt this advertisement was encrypted with. This will return {@code null} if this + * advertisement is not an encrypted advertisement. + */ + @Nullable + public byte[] getSalt() { + ensureLegible("get salt"); + + V0Payload.IdentityDetails details = payload.getIdentityDetails(); + return (details != null) ? details.getSalt() : null; + } + + /** + * Gets the metadata matched to the credential this advertisement was deserialized with. This will + * return {@code null} if this advertisement is not an encrypted advertisement. + */ + @Nullable + public M getMatchedMetadata() { + ensureLegible("get matched metadata"); + + V0Payload.IdentityDetails details = payload.getIdentityDetails(); + if (details == null) { + return null; + } + + return credentialBook.getMatchedMetadata(details.getCredentialId()); + } + + /** + * Gets the metadata matched to the credential this advertisement was deserialized with. This will + * return {@code null} if this advertisement is not an encrypted advertisement or the metadata was + * not able to be decrypted. + */ + @Nullable + public byte[] getDecryptedMetadata() { + return payload.getDecryptedMetadata(); + } + /** Iterator instance for data elements in DeserializedV0Advertisement. */ private static final class DataElementIterator implements Iterator<V0DataElement> { private final V0Payload payload;
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV1Advertisement.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV1Advertisement.java index d1ecdcd..8f4c3a3 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV1Advertisement.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV1Advertisement.java
@@ -16,6 +16,7 @@ package com.google.android.nearby.presence.rust; +import com.google.android.nearby.presence.rust.credential.CredentialBook; import java.util.Iterator; /** @@ -23,18 +24,24 @@ * LegibleV1Sections} handle. If this class is closed then the underlying handle will be closed too. * Methods on this class should not be called if {@link #close()} has already been called. */ -public final class DeserializedV1Advertisement extends DeserializedAdvertisement { +public final class DeserializedV1Advertisement<M extends CredentialBook.MatchedMetadata> + extends DeserializedAdvertisement { private final int numLegibleSections; private final int numUndecryptableSections; private final LegibleV1Sections legibleSections; + private final CredentialBook<M> credentialBook; /** Create a legible instance with the given information. */ /* package */ DeserializedV1Advertisement( - int numLegibleSections, int numUndecryptableSections, LegibleV1Sections legibleSections) { + int numLegibleSections, + int numUndecryptableSections, + LegibleV1Sections legibleSections, + CredentialBook<M> credentialBook) { this.numLegibleSections = numLegibleSections; this.numUndecryptableSections = numUndecryptableSections; this.legibleSections = legibleSections; + this.credentialBook = credentialBook; } /** Get the number of legible sections in this advertisement */ @@ -55,25 +62,29 @@ * @throws IndexOutOfBoundsException if the index is invalid * @return The section at {@code index} */ - public DeserializedV1Section getSection(int index) { - return legibleSections.getSection(index); + public DeserializedV1Section<M> getSection(int index) { + return legibleSections.getSection(index, credentialBook); } /** Get an iterable of this advertisement's legible sections. */ public Iterable<DeserializedV1Section> getSections() { - return () -> new SectionIterator(numLegibleSections, legibleSections); + return () -> new SectionIterator(numLegibleSections, legibleSections, credentialBook); } /** Iterator instance for sections in DeserializedV1Advertisement. */ - private static final class SectionIterator implements Iterator<DeserializedV1Section> { + private static final class SectionIterator<M extends CredentialBook.MatchedMetadata> + implements Iterator<DeserializedV1Section> { private final LegibleV1Sections legibleSections; private final int numSections; + private final CredentialBook<M> credentialBook; private int position = 0; - public SectionIterator(int numSections, LegibleV1Sections legibleSections) { + public SectionIterator( + int numSections, LegibleV1Sections legibleSections, CredentialBook<M> credentialBook) { this.numSections = numSections; this.legibleSections = legibleSections; + this.credentialBook = credentialBook; } @Override @@ -83,7 +94,7 @@ @Override public DeserializedV1Section next() { - return legibleSections.getSection(position++); + return legibleSections.getSection(position++, credentialBook); } }
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV1Section.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV1Section.java index 1667366..d320963 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV1Section.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/DeserializedV1Section.java
@@ -16,23 +16,40 @@ package com.google.android.nearby.presence.rust; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import androidx.annotation.IntDef; +import androidx.annotation.Nullable; +import com.google.android.nearby.presence.rust.credential.CredentialBook; +import java.lang.annotation.Retention; import java.util.Iterator; -public final class DeserializedV1Section { +public final class DeserializedV1Section<M extends CredentialBook.MatchedMetadata> { + + @IntDef({VerificationMode.MIC, VerificationMode.SIGNATURE}) + @Retention(SOURCE) + public @interface VerificationMode { + public static final int MIC = 0; + public static final int SIGNATURE = 1; + } + private final LegibleV1Sections legibleSections; private final int legibleSectionsIndex; private final int numDataElements; private final @IdentityKind int identityTag; + private final CredentialBook<M> credentialBook; /* package */ DeserializedV1Section( LegibleV1Sections legibleSections, int legibleSectionsIndex, int numDataElements, - @IdentityKind int identityTag) { + @IdentityKind int identityTag, + CredentialBook<M> credentialBook) { this.legibleSections = legibleSections; this.legibleSectionsIndex = legibleSectionsIndex; this.numDataElements = numDataElements; this.identityTag = identityTag; + this.credentialBook = credentialBook; } /** Gets the identity kind for this section. */ @@ -68,6 +85,53 @@ } } + /** + * Gets the identity token for the credential this advertisement was deserialized with. This will + * return {@code null} if this advertisement is not an encrypted advertisement. + */ + @Nullable + public byte[] getIdentityToken() { + LegibleV1Sections.IdentityDetails details = + legibleSections.getSectionIdentityDetails(legibleSectionsIndex); + return (details != null) ? details.getIdentityToken() : null; + } + + /** + * Gets the verification mode for this advertisement. This will return {@code null} if this + * advertisement is not an encrypted advertisement. + */ + @Nullable + @VerificationMode + public Integer getVerificationMode() { + LegibleV1Sections.IdentityDetails details = + legibleSections.getSectionIdentityDetails(legibleSectionsIndex); + return (details != null) ? details.getVerificationMode() : null; + } + + /** + * Gets the metadata matched to the credential this advertisement was deserialized with. This will + * return {@code null} if this advertisement is not an encrypted advertisement. + */ + @Nullable + public M getMatchedMetadata() { + LegibleV1Sections.IdentityDetails details = + legibleSections.getSectionIdentityDetails(legibleSectionsIndex); + if (details == null) { + return null; + } + return credentialBook.getMatchedMetadata(details.getCredentialId()); + } + + /** + * Gets the metadata matched to the credential this advertisement was deserialized with. This will + * return {@code null} if this advertisement is not an encrypted advertisement or the metadata was + * not able to be decrypted. + */ + @Nullable + public byte[] getDecryptedMetadata() { + return legibleSections.getSectionDecryptedMetadata(legibleSectionsIndex); + } + private static final class DataElementIterator implements Iterator<V1DataElement> { private final LegibleV1Sections legibleSections; private final int legibleSectionsIndex;
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/Handle.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/Handle.java index a200358..537098b 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/Handle.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/Handle.java
@@ -27,7 +27,7 @@ public abstract class Handle { /** Thrown when an invalid handle is used */ - public static final class InvalidHandleException extends Exception { + public static final class InvalidHandleException extends RuntimeException { public InvalidHandleException() { super("The given handle is no longer valid"); }
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/LegibleV1Sections.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/LegibleV1Sections.java index 5175ce6..4a089c6 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/LegibleV1Sections.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/LegibleV1Sections.java
@@ -16,8 +16,12 @@ package com.google.android.nearby.presence.rust; +import static com.google.android.nearby.presence.rust.DeserializedV1Section.VerificationMode; + import androidx.annotation.Nullable; +import com.google.android.nearby.presence.rust.credential.CredentialBook; import java.lang.ref.Cleaner; +import java.util.Arrays; /** Internal handle for a V1 deserialized advertisement. */ public final class LegibleV1Sections extends OwnedHandle { @@ -26,6 +30,38 @@ System.loadLibrary(NpAdv.LIBRARY_NAME); } + /** Internal data class to pass identity data back from native code. */ + public static final class IdentityDetails { + @VerificationMode private final int verificationMode; + + /** + * @see com.google.android.nearby.presence.rust.credential.CredentialBook.Builder + */ + private final int credentialId; + + private final byte[] identityToken; + + public IdentityDetails( + @VerificationMode int verificationMode, int credentialId, byte[] identityToken) { + this.verificationMode = verificationMode; + this.credentialId = credentialId; + this.identityToken = Arrays.copyOf(identityToken, identityToken.length); + } + + @VerificationMode + public int getVerificationMode() { + return verificationMode; + } + + public int getCredentialId() { + return credentialId; + } + + public byte[] getIdentityToken() { + return identityToken; + } + } + /** * Create a LegibleV1Sections handle from the raw handle id. This will use the default cleaner * form {@code NpAdv#getCleaner()}. This is expected to be called from native code. @@ -46,12 +82,13 @@ * @throws IndexOutOfBoundsException if the given index is out of range for this advertisement * @return The section at that index */ - public DeserializedV1Section getSection(int index) { - DeserializedV1Section section = nativeGetSection(index); + public <M extends CredentialBook.MatchedMetadata> DeserializedV1Section<M> getSection( + int index, CredentialBook<M> credentialBook) { + DeserializedV1Section section = nativeGetSection(index, credentialBook); if (section == null) { throw new IndexOutOfBoundsException(); } - return section; + return (DeserializedV1Section<M>) section; } /** @@ -71,10 +108,26 @@ } @Nullable - private native DeserializedV1Section nativeGetSection(int index); + public IdentityDetails getSectionIdentityDetails(int sectionIndex) { + return nativeGetSectionIdentityDetails(sectionIndex); + } + + @Nullable + public byte[] getSectionDecryptedMetadata(int sectionIndex) { + return nativeGetSectionDecryptedMetadata(sectionIndex); + } + + @Nullable + private native DeserializedV1Section nativeGetSection(int index, CredentialBook credentialBook); @Nullable private native V1DataElement nativeGetSectionDataElement(int sectionIndex, int deIndex); + @Nullable + private native IdentityDetails nativeGetSectionIdentityDetails(int sectionIndex); + + @Nullable + private native byte[] nativeGetSectionDecryptedMetadata(int sectionIndex); + private static native void deallocate(long handleId); }
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/NpAdv.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/NpAdv.java index 21abb89..a349ebc 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/NpAdv.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/NpAdv.java
@@ -29,7 +29,10 @@ * <h3>Supported Features:</h3> * * <ul> + * <li>Create credential books: {@link CredentialBook#builder()} * <li>Deserialize advertisements: {@link #deserializeAdvertisement} + * <li>Serialize advertisements: {@link + * com.google.android.nearby.presence.rust.V0AdvertisementBuilder} * </ul> */ public final class NpAdv { @@ -50,9 +53,9 @@ * @return A result containing the advertisement if it was able to be deserialized. */ public static <M extends CredentialBook.MatchedMetadata> - DeserializeResult deserializeAdvertisement( + DeserializeResult<M> deserializeAdvertisement( byte[] serviceData, CredentialBook<M> credentialBook) { - DeserializeResult result = nativeDeserializeAdvertisement(serviceData, credentialBook.getId()); + DeserializeResult result = nativeDeserializeAdvertisement(serviceData, credentialBook); if (result == null) { result = new DeserializeResult(DeserializeResult.Kind.UNKNOWN_ERROR); } @@ -87,5 +90,5 @@ @Nullable private static native DeserializeResult nativeDeserializeAdvertisement( - byte[] serviceData, long credentialBook); + byte[] serviceData, CredentialBook credentialBook); }
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/SerializationException.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/SerializationException.java new file mode 100644 index 0000000..4fa4f4f --- /dev/null +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/SerializationException.java
@@ -0,0 +1,57 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.nearby.presence.rust; + +/** Base class for exceptions that can occur during serialization. */ +public abstract class SerializationException extends Exception { + + private SerializationException(String message) { + super(message); + } + + public static final class InvalidDataElementException extends RuntimeException { + public InvalidDataElementException(String reason) { + super(String.format("Data element is invalid: %s", reason)); + } + } + + public static final class InsufficientSpaceException extends SerializationException { + public InsufficientSpaceException() { + super("There isn't enough space remaining in the advertisement"); + } + } + + public static final class LdtEncryptionException extends SerializationException { + public LdtEncryptionException() { + super( + "Serializing the advertisement to bytes failed because the data in the advertisement" + + " wasn't of an appropriate size for LDT encryption to succeed."); + } + } + + /** + * Advertisement has an invalid length. This means it's empty; the length requirement is {@code + * length >= 1 byte}. + */ + public static final class UnencryptedSizeException extends SerializationException { + public UnencryptedSizeException() { + super( + "Serializing an unencrypted adv failed because the adv data didn't meet the length" + + " requirements."); + } + } +}
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/V0AdvertisementBuilder.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/V0AdvertisementBuilder.java new file mode 100644 index 0000000..e597303 --- /dev/null +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/V0AdvertisementBuilder.java
@@ -0,0 +1,136 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.nearby.presence.rust; + +import com.google.android.nearby.presence.rust.SerializationException.InsufficientSpaceException; +import com.google.android.nearby.presence.rust.SerializationException.InvalidDataElementException; +import com.google.android.nearby.presence.rust.credential.V0BroadcastCredential; +import java.lang.ref.Cleaner; + +/** + * A builder for V0 advertisements. Create a new instance with {@link #newPublic()} for a public + * advertisement or {@link #newEncrypted()} for an encrypted advertisement. + */ +public final class V0AdvertisementBuilder implements AutoCloseable { + + /** Create a builder for a public advertisement. */ + public static V0AdvertisementBuilder newPublic() { + return newPublic(NpAdv.getCleaner()); + } + + /** Create a builder for an encrypted advertisement. */ + public static V0AdvertisementBuilder newEncrypted(V0BroadcastCredential credential, byte[] salt) { + return newEncrypted(NpAdv.getCleaner(), credential, salt); + } + + /** Create a builder for a public advertisement with a specific Cleaner. */ + public static V0AdvertisementBuilder newPublic(Cleaner cleaner) { + return new V0AdvertisementBuilder(new V0BuilderHandle(cleaner)); + } + + /** Create a builder for an encrypted advertisement with a specific Cleaner. */ + public static V0AdvertisementBuilder newEncrypted( + Cleaner cleaner, V0BroadcastCredential credential, byte[] salt) { + return new V0AdvertisementBuilder(new V0BuilderHandle(cleaner, credential, salt)); + } + + private final V0BuilderHandle builder; + + private V0AdvertisementBuilder(V0BuilderHandle builder) { + this.builder = builder; + } + + /** + * Add a data element to the advertisement. If it cannot be added an exception will be thrown. A + * thrown exception will not invalidate this builder. + * + * @throws InvalidDataElementException when the given data element is not valid (e.g. TX power out + * of range) + * @throws InsufficientSpaceException when the data element will not fit in the remaining space. + */ + public void addDataElement(V0DataElement dataElement) throws InsufficientSpaceException { + builder.addDataElement(dataElement); + } + + /** + * Build this advertisement into a byte buffer. This will consume the builder when called. + * + * @throws LdtEncryptionException when the advertisement cannot be encrypted. + * @throws UnencryptedSizeException when the advertisement is empty. + */ + public byte[] build() + throws SerializationException.LdtEncryptionException, + SerializationException.UnencryptedSizeException { + return builder.build(); + } + + @Override + public void close() { + builder.close(); + } + + /** Internal builder handle object. */ + private static final class V0BuilderHandle extends OwnedHandle { + static { + System.loadLibrary(NpAdv.LIBRARY_NAME); + } + + public V0BuilderHandle(Cleaner cleaner) { + super(allocatePublic(), cleaner, V0BuilderHandle::deallocate); + } + + public V0BuilderHandle(Cleaner cleaner, V0BroadcastCredential credential, byte[] salt) { + super(allocatePrivate(credential, salt), cleaner, V0BuilderHandle::deallocate); + } + + public void addDataElement(V0DataElement dataElement) { + // Call the appropriate native add call based on the data element type. + dataElement.visit( + new V0DataElement.Visitor() { + public void visitTxPower(V0DataElement.TxPower txPower) { + nativeAddTxPowerDataElement(txPower); + } + + public void visitV0Actions(V0DataElement.V0Actions v0Actions) { + nativeAddV0ActionsDataElement(v0Actions); + } + }); + } + + public byte[] build() + throws SerializationException.LdtEncryptionException, + SerializationException.UnencryptedSizeException { + // `nativeBuild` takes ownership so we leak the Java side here. + leak(); + return nativeBuild(); + } + + private static native long allocatePublic(); + + private static native long allocatePrivate(V0BroadcastCredential credential, byte[] salt); + + private native void nativeAddTxPowerDataElement(V0DataElement.TxPower txPower); + + private native void nativeAddV0ActionsDataElement(V0DataElement.V0Actions v0Actions); + + private native byte[] nativeBuild() + throws SerializationException.LdtEncryptionException, + SerializationException.UnencryptedSizeException; + + private static native void deallocate(long handleId); + } +}
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/V0DataElement.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/V0DataElement.java index 4575f5a..c2c6325 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/V0DataElement.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/V0DataElement.java
@@ -86,7 +86,21 @@ private final @IdentityKind int identityKind; private final int actionBits; - public V0Actions(@IdentityKind int identityKind, int actionBits) { + /** + * Create an actions data element. + * + * @throws IllegalArgumentException when {@code identityKind} is not {@link + * IdentityKind#PLAINTEXT} or {@link IdentityKind#DECRYPTED}, or an {@code actions} value is + * not a valid {@link V0ActionType}. + * @throws IllegalStateException when an action is not a valid action for the given identity + * kind. + */ + public V0Actions(@IdentityKind int identityKind, @V0ActionType int... actions) { + this(identityKind, nativeMergeActions(identityKind, actions)); + } + + /** Used by native code. */ + V0Actions(@IdentityKind int identityKind, int actionBits) { this.identityKind = identityKind; this.actionBits = actionBits; } @@ -109,6 +123,10 @@ v.visitV0Actions(this); } - private static native boolean nativeHasAction(int identityKind, int actionBits, int action); + private static native boolean nativeHasAction( + @IdentityKind int identityKind, int actionBits, @V0ActionType int action); + + private static native int nativeMergeActions( + @IdentityKind int identityKind, @V0ActionType int[] actions); } }
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/V0Payload.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/V0Payload.java index 722f37c..e6abea8 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/V0Payload.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/V0Payload.java
@@ -18,6 +18,7 @@ import androidx.annotation.Nullable; import java.lang.ref.Cleaner; +import java.util.Arrays; /** * Internal handle type for deserialized V0 advertisements. It provides access to the native data @@ -29,6 +30,35 @@ System.loadLibrary(NpAdv.LIBRARY_NAME); } + /** Internal data class to pass identity data back from native code. */ + public static final class IdentityDetails { + /** + * @see com.google.android.nearby.presence.rust.credential.CredentialBook.Builder + */ + private final int credentialId; + + private final byte[] identityToken; + private final byte[] salt; + + public IdentityDetails(int credentialId, byte[] identityToken, byte[] salt) { + this.credentialId = credentialId; + this.identityToken = Arrays.copyOf(identityToken, identityToken.length); + this.salt = Arrays.copyOf(salt, salt.length); + } + + public int getCredentialId() { + return credentialId; + } + + public byte[] getIdentityToken() { + return identityToken; + } + + public byte[] getSalt() { + return salt; + } + } + /** * Create a V0Payload handle from the raw handle id. This will use the default cleaner form {@code * NpAdv#getCleaner()}. This is expected to be called from native code. @@ -58,7 +88,23 @@ } @Nullable + public IdentityDetails getIdentityDetails() { + return nativeGetIdentityDetails(this.handleId); + } + + @Nullable + public byte[] getDecryptedMetadata() { + return nativeGetDecryptedMetadata(this.handleId); + } + + @Nullable private static native V0DataElement nativeGetDataElement(long handleId, int index); + @Nullable + private static native IdentityDetails nativeGetIdentityDetails(long handleId); + + @Nullable + private static native byte[] nativeGetDecryptedMetadata(long handleId); + private static native void deallocate(long handleId); }
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/CredentialBook.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/CredentialBook.java index cdcc50b..953c6e9 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/CredentialBook.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/CredentialBook.java
@@ -16,6 +16,7 @@ package com.google.android.nearby.presence.rust.credential; +import androidx.annotation.Nullable; import com.google.android.nearby.presence.rust.NpAdv; import com.google.android.nearby.presence.rust.OwnedHandle; import java.lang.ref.Cleaner; @@ -57,13 +58,23 @@ } } - /** Builder for {@code CredentialBook} */ + /** + * Builder for {@code CredentialBook}. This manages passing credentials into the slab and tracking + * the associated metadata for each credential. + * + * <p>Credential ids will be assigned in order starting at {@code 0}. This allows them to be + * mapped to their metadata object using an array. This lookup is implemented in {@link + * CredentialBook#getMatchedMetadata()} for internal use. Clients of the library should use the + * {@code getMatchedMetadata()} method on their {@code DeserializedAdvertisement} instance. + */ public static final class Builder<M extends MatchedMetadata> { private Cleaner cleaner; private CredentialSlab slab; - // Each credential should be given an id of its metadata index so that this array is an - // id-to-metadata map. + /** + * Each credential should be given an id of its metadata index so that this array is an + * id-to-metadata map. + */ private ArrayList<M> matchDataList; /** @@ -134,6 +145,18 @@ this.matchData = matchData; } + /** + * Lookup the matched metadata given its credential id. This is meant for internal use. This will + * return {@code null} if the credential id is not valid. + */ + @Nullable + public M getMatchedMetadata(int credentialId) { + if (credentialId < 0 || credentialId >= matchData.size()) { + return null; + } + return matchData.get(credentialId); + } + private static native long allocate(long slabHandleId); private static native void deallocate(long handleId);
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/Utils.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/Utils.java index c38bbcf..4f070e4 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/Utils.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/Utils.java
@@ -22,13 +22,13 @@ final class Utils { /** - * Create a copy of a 32-byte array of key data. Will throw {@code IllegalArgumentException} if - * the array is not exactly 32 bytes. + * Create a copy of a {@code n}-byte array of data. Will throw {@code IllegalArgumentException} if + * the array is not exactly {@code n} bytes. */ - public static byte[] copyKeyBytes(byte[] key) { - if (key.length != 32) { + public static byte[] copyBytes(byte[] key, int n) { + if (key.length != n) { throw new IllegalArgumentException( - String.format("Expected key length to be 32 bytes, got %s bytes", key.length)); + String.format("Expected key length to be %s bytes, got %s bytes", n, key.length)); } return Arrays.copyOf(key, key.length); }
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V0BroadcastCredential.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V0BroadcastCredential.java new file mode 100644 index 0000000..9e8474b --- /dev/null +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V0BroadcastCredential.java
@@ -0,0 +1,34 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.nearby.presence.rust.credential; + +import static com.google.android.nearby.presence.rust.credential.Utils.copyBytes; + +/** A V0 broadcast credential in a format that is ready to be passed to native code. */ +public final class V0BroadcastCredential { + private final byte[] keySeed; + private final byte[] identityToken; + + /** + * Create the credential. {@code keySeed} is exactly 32 bytes. {@code identityToken} is exactly 14 + * bytes + */ + public V0BroadcastCredential(byte[] keySeed, byte[] identityToken) { + this.keySeed = copyBytes(keySeed, 32); + this.identityToken = copyBytes(identityToken, 14); + } +}
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V0DiscoveryCredential.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V0DiscoveryCredential.java index be8734b..522b7d8 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V0DiscoveryCredential.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V0DiscoveryCredential.java
@@ -16,7 +16,7 @@ package com.google.android.nearby.presence.rust.credential; -import static com.google.android.nearby.presence.rust.credential.Utils.copyKeyBytes; +import static com.google.android.nearby.presence.rust.credential.Utils.copyBytes; /** A V0 discovery credential in a format that is ready to be passed to native code. */ public final class V0DiscoveryCredential { @@ -25,7 +25,7 @@ /** Create the credential. Each array is exactly 32 bytes. */ public V0DiscoveryCredential(byte[] keySeed, byte[] identityTokenHmac) { - this.keySeed = copyKeyBytes(keySeed); - this.identityTokenHmac = copyKeyBytes(identityTokenHmac); + this.keySeed = copyBytes(keySeed, 32); + this.identityTokenHmac = copyBytes(identityTokenHmac, 32); } }
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V1BroadcastCredential.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V1BroadcastCredential.java new file mode 100644 index 0000000..5c2547a --- /dev/null +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V1BroadcastCredential.java
@@ -0,0 +1,36 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.nearby.presence.rust.credential; + +import static com.google.android.nearby.presence.rust.credential.Utils.copyBytes; + +/** A V1 broadcast credential in a format that is ready to be passed to native code. */ +public final class V1BroadcastCredential { + private final byte[] keySeed; + private final byte[] identityToken; + private final byte[] privateKey; + + /** + * Create the credential. {@code keySeed} and {@code privateKey} are exactly 32 bytes. {@code + * identityToken} is exactly 16 bytes + */ + public V1BroadcastCredential(byte[] keySeed, byte[] identityToken, byte[] privateKey) { + this.keySeed = copyBytes(keySeed, 32); + this.identityToken = copyBytes(identityToken, 16); + this.privateKey = copyBytes(privateKey, 32); + } +}
diff --git a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V1DiscoveryCredential.java b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V1DiscoveryCredential.java index c2afefa..2fbf608 100644 --- a/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V1DiscoveryCredential.java +++ b/nearby/presence/np_java_ffi/java/com/google/android/nearby/presence/rust/credential/V1DiscoveryCredential.java
@@ -16,7 +16,7 @@ package com.google.android.nearby.presence.rust.credential; -import static com.google.android.nearby.presence.rust.credential.Utils.copyKeyBytes; +import static com.google.android.nearby.presence.rust.credential.Utils.copyBytes; /** A V1 discovery credential in a format that is ready to be passed to native code. */ public final class V1DiscoveryCredential { @@ -33,12 +33,12 @@ byte[] expectedMicExtendedSaltIdentityTokenHmac, byte[] expectedSignatureIdentityTokenHmac, byte[] pubKey) { - this.keySeed = copyKeyBytes(keySeed); + this.keySeed = copyBytes(keySeed, 32); this.expectedMicShortSaltIdentityTokenHmac = - copyKeyBytes(expectedMicShortSaltIdentityTokenHmac); + copyBytes(expectedMicShortSaltIdentityTokenHmac, 32); this.expectedMicExtendedSaltIdentityTokenHmac = - copyKeyBytes(expectedMicExtendedSaltIdentityTokenHmac); - this.expectedSignatureIdentityTokenHmac = copyKeyBytes(expectedSignatureIdentityTokenHmac); - this.pubKey = copyKeyBytes(pubKey); + copyBytes(expectedMicExtendedSaltIdentityTokenHmac, 32); + this.expectedSignatureIdentityTokenHmac = copyBytes(expectedSignatureIdentityTokenHmac, 32); + this.pubKey = copyBytes(pubKey, 32); } }
diff --git a/nearby/presence/np_java_ffi/src/class.rs b/nearby/presence/np_java_ffi/src/class.rs index 9c07137..ea53df7 100644 --- a/nearby/presence/np_java_ffi/src/class.rs +++ b/nearby/presence/np_java_ffi/src/class.rs
@@ -42,21 +42,32 @@ mod legible_v1_sections; mod np_adv; mod owned_handle; +mod serialization_exception; +mod v0_advertisement_builder; +mod v0_broadcast_credential; mod v0_discovery_credential; mod v0_payload; +mod v1_broadcast_credential; mod v1_discovery_credential; pub mod v0_data_element; pub mod v1_data_element; +pub use credential_book::CredentialBook; pub use deserialization_exception::{InvalidFormatException, InvalidHeaderException}; pub use deserialize_result::{DeserializeResult, DeserializeResultError}; pub use deserialized_v0_advertisement::{DeserializedV0Advertisement, V0AdvertisementError}; pub use deserialized_v1_advertisement::DeserializedV1Advertisement; -pub use deserialized_v1_section::DeserializedV1Section; +pub use deserialized_v1_section::{DeserializedV1Section, VerificationMode}; pub use handle::InvalidHandleException; pub use identity_kind::IdentityKind; pub use legible_v1_sections::LegibleV1Sections; pub use owned_handle::NoSpaceLeftException; +pub use serialization_exception::{ + InsufficientSpaceException, InvalidDataElementException, LdtEncryptionException, + UnencryptedSizeException, +}; +pub use v0_broadcast_credential::V0BroadcastCredential; pub use v0_discovery_credential::V0DiscoveryCredential; +pub use v1_broadcast_credential::V1BroadcastCredential; pub use v1_discovery_credential::V1DiscoveryCredential;
diff --git a/nearby/presence/np_java_ffi/src/class/credential_book.rs b/nearby/presence/np_java_ffi/src/class/credential_book.rs index ea371da..f213f8d 100644 --- a/nearby/presence/np_java_ffi/src/class/credential_book.rs +++ b/nearby/presence/np_java_ffi/src/class/credential_book.rs
@@ -12,15 +12,46 @@ // See the License for the specific language governing permissions and // limitations under the License. -use jni::{objects::JClass, sys::jlong, JNIEnv}; +use jni::{ + objects::{JClass, JObject}, + sys::jlong, + JNIEnv, +}; use crate::class::{InvalidHandleException, NoSpaceLeftException}; use handle_map::{Handle, HandleLike}; use np_ffi_core::credentials::{ create_credential_book_from_slab, deallocate_credential_book, CreateCredentialBookResult, - CredentialBook, CredentialSlab, + CredentialBook as CredentialBookHandle, CredentialSlab, }; -use pourover::jni_method; +use pourover::{desc::ClassDesc, jni_method}; + +static CREDENTIAL_BOOK_CLASS: ClassDesc = + ClassDesc::new("com/google/android/nearby/presence/rust/credential/CredentialBook"); + +/// Rust representation of `class CredentialBook`. +#[repr(transparent)] +pub struct CredentialBook<Obj>(pub Obj); + +impl<'local, Obj: AsRef<JObject<'local>>> CredentialBook<Obj> { + /// Get the raw handle id + pub fn get_id<'env>(&self, env: &mut JNIEnv<'env>) -> jni::errors::Result<jlong> { + pourover::call_method!(env, &CREDENTIAL_BOOK_CLASS, "getId", "()J", self.as_obj(),) + } + + /// Get the associated Rust handle from this Java handle object + pub fn get_handle<'env>( + &self, + env: &mut JNIEnv<'env>, + ) -> jni::errors::Result<CredentialBookHandle> { + self.get_id(env).map(|id| Handle::from_id(id as u64)).map(CredentialBookHandle::from_handle) + } + + /// Get a reference to the inner `jni` crate [`JObject`]. + pub fn as_obj(&self) -> &JObject<'local> { + self.0.as_ref() + } +} #[jni_method( package = "com.google.android.nearby.presence.rust.credential", @@ -60,6 +91,7 @@ handle_id: jlong, ) { // Swallow errors here since there's nothing meaningful to do. - let _ = - deallocate_credential_book(CredentialBook::from_handle(Handle::from_id(handle_id as u64))); + let _ = deallocate_credential_book(CredentialBookHandle::from_handle(Handle::from_id( + handle_id as u64, + ))); }
diff --git a/nearby/presence/np_java_ffi/src/class/deserialized_v0_advertisement.rs b/nearby/presence/np_java_ffi/src/class/deserialized_v0_advertisement.rs index 1d91ae9..ba47ff7 100644 --- a/nearby/presence/np_java_ffi/src/class/deserialized_v0_advertisement.rs +++ b/nearby/presence/np_java_ffi/src/class/deserialized_v0_advertisement.rs
@@ -20,7 +20,7 @@ use np_ffi_core::deserialize::v0::{DeserializedV0IdentityKind, V0Payload}; use pourover::desc::ClassDesc; -use crate::class::IdentityKind; +use crate::class::{CredentialBook, IdentityKind}; static DESERIALIZED_V0_ADVERTISEMENT_CLASS: ClassDesc = ClassDesc::new("com/google/android/nearby/presence/rust/DeserializedV0Advertisement"); @@ -35,30 +35,32 @@ env: &mut JNIEnv<'local>, error: V0AdvertisementError, ) -> jni::errors::Result<Self> { - let error = IdentityKind::error_for_v0(env, error)?; + let error = IdentityKind::from(error).to_java(env)?; pourover::call_constructor!(env, &DESERIALIZED_V0_ADVERTISEMENT_CLASS, "(I)V", error) .map(Self) } /// Create a legible advertisment. - pub fn construct( + pub fn construct<'book>( env: &mut JNIEnv<'local>, num_des: u8, v0_payload: V0Payload, identity: DeserializedV0IdentityKind, + credential_book: CredentialBook<impl AsRef<JObject<'book>>>, ) -> jni::errors::Result<Self> { let num_des = jint::from(num_des); let payload_handle = v0_payload.get_as_handle().get_id() as jlong; - let identity = IdentityKind::value_for_v0(env, identity)?; + let identity = IdentityKind::from(identity).to_java(env)?; pourover::call_constructor!( env, &DESERIALIZED_V0_ADVERTISEMENT_CLASS, - "(IJI)V", + "(IJILcom/google/android/nearby/presence/rust/credential/CredentialBook;)V", num_des, payload_handle, - identity + identity, + credential_book.as_obj() ) .map(Self) }
diff --git a/nearby/presence/np_java_ffi/src/class/deserialized_v1_advertisement.rs b/nearby/presence/np_java_ffi/src/class/deserialized_v1_advertisement.rs index e537052..3b0af45 100644 --- a/nearby/presence/np_java_ffi/src/class/deserialized_v1_advertisement.rs +++ b/nearby/presence/np_java_ffi/src/class/deserialized_v1_advertisement.rs
@@ -15,6 +15,8 @@ use jni::{objects::JObject, sys::jint, JNIEnv}; use pourover::desc::ClassDesc; +use crate::class::CredentialBook; + static DESERIALIZED_V1_ADVERTISEMENT_CLASS: ClassDesc = ClassDesc::new("com/google/android/nearby/presence/rust/DeserializedV1Advertisement"); @@ -24,19 +26,21 @@ impl<'local> DeserializedV1Advertisement<JObject<'local>> { /// Create a new advertisement. - pub fn construct( + pub fn construct<'sections, 'book>( env: &mut JNIEnv<'local>, num_legible_sections: jint, num_undecryptable_sections: jint, - legible_sections: super::LegibleV1Sections<impl AsRef<JObject<'local>>>, + legible_sections: super::LegibleV1Sections<impl AsRef<JObject<'sections>>>, + credential_book: CredentialBook<impl AsRef<JObject<'book>>>, ) -> jni::errors::Result<Self> { pourover::call_constructor!( env, &DESERIALIZED_V1_ADVERTISEMENT_CLASS, - "(IILcom/google/android/nearby/presence/rust/LegibleV1Sections;)V", + "(IILcom/google/android/nearby/presence/rust/LegibleV1Sections;Lcom/google/android/nearby/presence/rust/credential/CredentialBook;)V", num_legible_sections, num_undecryptable_sections, - legible_sections.as_obj() + legible_sections.as_obj(), + credential_book.as_obj(), ) .map(Self) }
diff --git a/nearby/presence/np_java_ffi/src/class/deserialized_v1_section.rs b/nearby/presence/np_java_ffi/src/class/deserialized_v1_section.rs index b3f6dba..3b6b5ac 100644 --- a/nearby/presence/np_java_ffi/src/class/deserialized_v1_section.rs +++ b/nearby/presence/np_java_ffi/src/class/deserialized_v1_section.rs
@@ -13,10 +13,11 @@ // limitations under the License. use jni::{objects::JObject, sys::jint, JNIEnv}; -use np_ffi_core::deserialize::v1::DeserializedV1IdentityKind; -use pourover::desc::ClassDesc; +use np_ffi_core::{deserialize::v1::DeserializedV1IdentityKind, v1::V1VerificationMode}; +use pourover::desc::{ClassDesc, StaticFieldDesc}; +use std::sync::RwLock; -use crate::class::{IdentityKind, LegibleV1Sections}; +use crate::class::{CredentialBook, IdentityKind, LegibleV1Sections}; static DESERIALIZED_V1_SECTION_CLASS: ClassDesc = ClassDesc::new("com/google/android/nearby/presence/rust/DeserializedV1Section"); @@ -27,24 +28,93 @@ impl<'local> DeserializedV1Section<JObject<'local>> { /// Create a new deserialized section - pub fn construct<'a>( + pub fn construct<'handle, 'book>( env: &mut JNIEnv<'local>, - legible_sections_handle: LegibleV1Sections<impl AsRef<JObject<'a>>>, + legible_sections_handle: LegibleV1Sections<impl AsRef<JObject<'handle>>>, legible_section_index: u8, num_des: u8, identity_kind: DeserializedV1IdentityKind, + credential_book: CredentialBook<impl AsRef<JObject<'book>>>, ) -> jni::errors::Result<Self> { - let identity = IdentityKind::value_for_v1(env, identity_kind)?; + let identity = IdentityKind::from(identity_kind).to_java(env)?; pourover::call_constructor!( env, &DESERIALIZED_V1_SECTION_CLASS, - "(Lcom/google/android/nearby/presence/rust/LegibleV1Sections;III)V", + "(Lcom/google/android/nearby/presence/rust/LegibleV1Sections;IIILcom/google/android/nearby/presence/rust/credential/CredentialBook;)V", legible_sections_handle.as_obj(), jint::from(legible_section_index), jint::from(num_des), - identity + identity, + credential_book.as_obj() ) .map(Self) } } + +static VERIFICATION_MODE_CLASS: ClassDesc = ClassDesc::new( + "com/google/android/nearby/presence/rust/DeserializedV1Section$VerificationMode", +); + +/// Rust representation of `@VerificationMode`. These are `jints` on the Java side, so this type can't +/// be instantiated. +pub enum VerificationMode {} + +impl VerificationMode { + /// Convert a Rust verification mode enum to the Java `jint` representation. + pub fn value_for<'local>( + env: &mut JNIEnv<'local>, + mode: V1VerificationMode, + ) -> jni::errors::Result<jint> { + match mode { + V1VerificationMode::Mic => Self::mic(env), + V1VerificationMode::Signature => Self::signature(env), + } + } + + /// Fetch the `SIGNATURE` constant + pub fn signature<'local>(env: &mut JNIEnv<'local>) -> jni::errors::Result<jint> { + static SIGNATURE: StaticFieldDesc = VERIFICATION_MODE_CLASS.static_field("SIGNATURE", "I"); + static VALUE: RwLock<Option<jint>> = RwLock::new(None); + Self::lookup_static_value(env, &SIGNATURE, &VALUE) + } + + /// Fetch the `MIC` constant + pub fn mic<'local>(env: &mut JNIEnv<'local>) -> jni::errors::Result<jint> { + static MIC: StaticFieldDesc = VERIFICATION_MODE_CLASS.static_field("MIC", "I"); + static VALUE: RwLock<Option<jint>> = RwLock::new(None); + Self::lookup_static_value(env, &MIC, &VALUE) + } + + /// Look up the given field and cache it in the given cache. The lookup will only be performed + /// once if successful. This uses `RwLock` instead of `OnceCell` since the fallible `OnceCell` + /// APIs are nightly only. + fn lookup_static_value<'local>( + env: &mut JNIEnv<'local>, + field: &StaticFieldDesc, + cache: &RwLock<Option<jint>>, + ) -> jni::errors::Result<jint> { + use jni::signature::{JavaType, Primitive}; + + // Read from cache + if let Some(value) = *cache.read().unwrap_or_else(|poison| poison.into_inner()) { + return Ok(value); + } + + // Get exclusive access to the cache for the lookup + let mut guard = cache.write().unwrap_or_else(|poison| poison.into_inner()); + + // In case of races, only lookup the value once + if let Some(value) = *guard { + return Ok(value); + } + + let value = env + .get_static_field_unchecked(field.cls(), field, JavaType::Primitive(Primitive::Int)) + .and_then(|ret| ret.i())?; + + *guard = Some(value); + + Ok(value) + } +}
diff --git a/nearby/presence/np_java_ffi/src/class/identity_kind.rs b/nearby/presence/np_java_ffi/src/class/identity_kind.rs index 8fce071..0ef415d 100644 --- a/nearby/presence/np_java_ffi/src/class/identity_kind.rs +++ b/nearby/presence/np_java_ffi/src/class/identity_kind.rs
@@ -26,13 +26,46 @@ static IDENTITY_KIND_CLASS: ClassDesc = ClassDesc::new("com/google/android/nearby/presence/rust/IdentityKind"); -/// Rust representation of `@IdentityKind`. These are `jints` on the Java side, so this type can't -/// be instantiated. -pub enum IdentityKind {} +/// Rust representation of `@interface IdentityKind`. +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum IdentityKind { + /// An illegible identity + NoMatchingCredentials, + /// A public identity + Plaintext, + /// An encrypted identity + Decrypted, +} impl IdentityKind { + /// Convert a Java `int` to the Rust version. Will return `None` if the given `value` is not + /// valid. + pub fn from_java<'local>( + env: &mut JNIEnv<'local>, + value: jint, + ) -> jni::errors::Result<Option<Self>> { + if value == Self::no_matching_credentials(env)? { + Ok(Some(Self::NoMatchingCredentials)) + } else if value == Self::plaintext(env)? { + Ok(Some(Self::Plaintext)) + } else if value == Self::decrypted(env)? { + Ok(Some(Self::Decrypted)) + } else { + Ok(None) + } + } + + /// Convert to a Java `int` value. + pub fn to_java<'local>(&self, env: &mut JNIEnv<'local>) -> jni::errors::Result<jint> { + match self { + Self::NoMatchingCredentials => Self::no_matching_credentials(env), + Self::Plaintext => Self::plaintext(env), + Self::Decrypted => Self::decrypted(env), + } + } + /// Fetch the `NO_MATCHING_CREDENTIALS` constant - pub fn no_matching_credentials<'local>(env: &mut JNIEnv<'local>) -> jni::errors::Result<jint> { + fn no_matching_credentials<'local>(env: &mut JNIEnv<'local>) -> jni::errors::Result<jint> { static NO_MATCHING_CREDENTIALS: StaticFieldDesc = IDENTITY_KIND_CLASS.static_field("NO_MATCHING_CREDENTIALS", "I"); static VALUE: RwLock<Option<jint>> = RwLock::new(None); @@ -40,14 +73,14 @@ } /// Fetch the `PLAINTEXT` constant - pub fn plaintext<'local>(env: &mut JNIEnv<'local>) -> jni::errors::Result<jint> { + fn plaintext<'local>(env: &mut JNIEnv<'local>) -> jni::errors::Result<jint> { static PLAINTEXT: StaticFieldDesc = IDENTITY_KIND_CLASS.static_field("PLAINTEXT", "I"); static VALUE: RwLock<Option<jint>> = RwLock::new(None); Self::lookup_static_value(env, &PLAINTEXT, &VALUE) } /// Fetch the `DECRYPTED` constant - pub fn decrypted<'local>(env: &mut JNIEnv<'local>) -> jni::errors::Result<jint> { + fn decrypted<'local>(env: &mut JNIEnv<'local>) -> jni::errors::Result<jint> { static DECRYPTED: StaticFieldDesc = IDENTITY_KIND_CLASS.static_field("DECRYPTED", "I"); static VALUE: RwLock<Option<jint>> = RwLock::new(None); Self::lookup_static_value(env, &DECRYPTED, &VALUE) @@ -82,36 +115,30 @@ Ok(value) } +} - /// Get the Java representation of [`V0AdvertisementError`]. - pub fn error_for_v0<'local>( - env: &mut JNIEnv<'local>, - identity: V0AdvertisementError, - ) -> jni::errors::Result<jint> { - match identity { - V0AdvertisementError::NoMatchingCredentials => Self::no_matching_credentials(env), +impl From<V0AdvertisementError> for IdentityKind { + fn from(err: V0AdvertisementError) -> Self { + match err { + V0AdvertisementError::NoMatchingCredentials => Self::NoMatchingCredentials, } } +} - /// Get the Java representation of [`DeserializedV0IdentityKind`]. - pub fn value_for_v0<'local>( - env: &mut JNIEnv<'local>, - identity: DeserializedV0IdentityKind, - ) -> jni::errors::Result<jint> { - match identity { - DeserializedV0IdentityKind::Plaintext => Self::plaintext(env), - DeserializedV0IdentityKind::Decrypted => Self::decrypted(env), +impl From<DeserializedV0IdentityKind> for IdentityKind { + fn from(kind: DeserializedV0IdentityKind) -> Self { + match kind { + DeserializedV0IdentityKind::Plaintext => Self::Plaintext, + DeserializedV0IdentityKind::Decrypted => Self::Decrypted, } } +} - /// Get the Java representation of [`DeserializedV1IdentityKind`]. - pub fn value_for_v1<'local>( - env: &mut JNIEnv<'local>, - identity: DeserializedV1IdentityKind, - ) -> jni::errors::Result<jint> { - match identity { - DeserializedV1IdentityKind::Plaintext => Self::plaintext(env), - DeserializedV1IdentityKind::Decrypted => Self::decrypted(env), +impl From<DeserializedV1IdentityKind> for IdentityKind { + fn from(kind: DeserializedV1IdentityKind) -> Self { + match kind { + DeserializedV1IdentityKind::Plaintext => Self::Plaintext, + DeserializedV1IdentityKind::Decrypted => Self::Decrypted, } } }
diff --git a/nearby/presence/np_java_ffi/src/class/legible_v1_sections.rs b/nearby/presence/np_java_ffi/src/class/legible_v1_sections.rs index 911c78d..6bc9225 100644 --- a/nearby/presence/np_java_ffi/src/class/legible_v1_sections.rs +++ b/nearby/presence/np_java_ffi/src/class/legible_v1_sections.rs
@@ -12,20 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. +use handle_map::{Handle, HandleLike}; use jni::{ objects::{JClass, JObject}, sys::{jint, jlong}, JNIEnv, }; - -use crate::class::{v1_data_element::Generic, DeserializedV1Section}; -use handle_map::{Handle, HandleLike}; -use np_ffi_core::deserialize::v1::{ - GetV1DEResult, GetV1SectionResult, LegibleV1Sections as LegibleSectionsHandle, V1DataElement, +use np_ffi_core::{ + deserialize::{ + v1::{ + DeserializedV1IdentityDetails, GetV1DEResult, GetV1IdentityDetailsResult, + GetV1SectionResult, LegibleV1Sections as LegibleSectionsHandle, V1DataElement, + }, + DecryptMetadataResult, + }, + v1::V1VerificationMode, }; use pourover::{desc::ClassDesc, jni_method}; -static LEGIBLE_V1_SECTIONS: ClassDesc = +use crate::class::{ + v1_data_element::Generic, CredentialBook, DeserializedV1Section, VerificationMode, +}; + +static LEGIBLE_V1_SECTIONS_CLASS: ClassDesc = ClassDesc::new("com/google/android/nearby/presence/rust/LegibleV1Sections"); /// Rust representation for `class LegibleV1Sections`. @@ -41,7 +50,7 @@ ) -> jni::errors::Result<Self> { let handle_id = handle.get_as_handle().get_id() as jlong; - pourover::call_constructor!(env, &LEGIBLE_V1_SECTIONS, "(J)V", handle_id,).map(Self) + pourover::call_constructor!(env, &LEGIBLE_V1_SECTIONS_CLASS, "(J)V", handle_id,).map(Self) } } @@ -65,17 +74,50 @@ &self, env: &mut JNIEnv<'env_local>, ) -> jni::errors::Result<jlong> { - use jni::signature::{Primitive, ReturnType}; - use pourover::desc::FieldDesc; + use LEGIBLE_V1_SECTIONS_CLASS as CLS; + pourover::call_method!(env, &CLS, "getId", "()J", self.as_obj()) + } +} - static HANDLE_ID_FIELD: FieldDesc = LEGIBLE_V1_SECTIONS.field("handleId", "J"); +static IDENTITY_DETAILS_CLASS: ClassDesc = + ClassDesc::new("com/google/android/nearby/presence/rust/LegibleV1Sections$IdentityDetails"); - env.get_field_unchecked( - self.0.as_ref(), - &HANDLE_ID_FIELD, - ReturnType::Primitive(Primitive::Long), +/// Rust representation for `class LegibleV1Sections.IdentityDetails`. +#[repr(transparent)] +pub struct IdentityDetails<Obj>(pub Obj); + +impl<'local> IdentityDetails<JObject<'local>> { + pub fn construct( + env: &mut JNIEnv<'local>, + details: DeserializedV1IdentityDetails, + ) -> jni::errors::Result<Self> { + Self::construct_from_parts( + env, + details.verification_mode(), + details.cred_id(), + details.identity_token(), ) - .and_then(|val| val.j()) + } + + pub fn construct_from_parts( + env: &mut JNIEnv<'local>, + verification_mode: V1VerificationMode, + credential_id: u32, + identity_token: [u8; 16], + ) -> jni::errors::Result<Self> { + let verification_mode = VerificationMode::value_for(env, verification_mode)?; + let credential_id = credential_id as jint; + let identity_token = env.byte_array_from_slice(&identity_token)?; + + pourover::call_constructor!( + env, + &IDENTITY_DETAILS_CLASS, + "(II[B)V", + verification_mode, + credential_id, + identity_token + ) + .map(Self) } } @@ -86,6 +128,7 @@ mut env: JNIEnv<'local>, legible_sections_obj: LegibleV1Sections<JObject<'local>>, index: jint, + credential_book: CredentialBook<JObject<'local>>, ) -> JObject<'local> { let Ok(legible_sections) = legible_sections_obj.as_rust_handle(&mut env) else { return JObject::null(); @@ -104,6 +147,7 @@ index, section.num_des(), section.identity_kind(), + credential_book, ) { Ok(section) => section.0, Err(_) => JObject::null(), @@ -149,6 +193,57 @@ } #[jni_method(package = "com.google.android.nearby.presence.rust", class = "LegibleV1Sections")] +extern "system" fn nativeGetSectionIdentityDetails<'local>( + mut env: JNIEnv<'local>, + legible_sections_obj: LegibleV1Sections<JObject<'local>>, + section_index: jint, +) -> JObject<'local> { + let Ok(legible_sections) = legible_sections_obj.as_rust_handle(&mut env) else { + return JObject::null(); + }; + let Ok(section_index) = u8::try_from(section_index) else { + return JObject::null(); + }; + + let GetV1IdentityDetailsResult::Success(details) = + legible_sections.get_section_identity_details(section_index) + else { + return JObject::null(); + }; + + IdentityDetails::construct(&mut env, details).map_or_else(|_err| JObject::null(), |obj| obj.0) +} + +#[jni_method(package = "com.google.android.nearby.presence.rust", class = "LegibleV1Sections")] +extern "system" fn nativeGetSectionDecryptedMetadata<'local>( + mut env: JNIEnv<'local>, + legible_sections_obj: LegibleV1Sections<JObject<'local>>, + section_index: jint, +) -> JObject<'local> { + let Ok(legible_sections) = legible_sections_obj.as_rust_handle(&mut env) else { + return JObject::null(); + }; + let Ok(section_index) = u8::try_from(section_index) else { + return JObject::null(); + }; + + let DecryptMetadataResult::Success(metadata) = + legible_sections.decrypt_section_metadata(section_index) + else { + return JObject::null(); + }; + + let Ok(buffer) = metadata.take_buffer() else { + return JObject::null(); + }; + let Ok(decrypted_metadata_array) = env.byte_array_from_slice(&buffer[..]) else { + return JObject::null(); + }; + + decrypted_metadata_array.into() +} + +#[jni_method(package = "com.google.android.nearby.presence.rust", class = "LegibleV1Sections")] extern "system" fn deallocate<'local>( _env: JNIEnv<'local>, _cls: JClass<'local>,
diff --git a/nearby/presence/np_java_ffi/src/class/np_adv.rs b/nearby/presence/np_java_ffi/src/class/np_adv.rs index 88513cc..24de9c0 100644 --- a/nearby/presence/np_java_ffi/src/class/np_adv.rs +++ b/nearby/presence/np_java_ffi/src/class/np_adv.rs
@@ -14,16 +14,15 @@ use jni::{ objects::{JByteArray, JClass, JObject}, - sys::{jint, jlong}, + sys::jint, JNIEnv, }; use crate::class::{ - DeserializeResult, DeserializeResultError, DeserializedV0Advertisement, + CredentialBook, DeserializeResult, DeserializeResultError, DeserializedV0Advertisement, DeserializedV1Advertisement, LegibleV1Sections, V0AdvertisementError, }; -use handle_map::Handle; -use np_ffi_core::{credentials::CredentialBook, deserialize::deserialize_advertisement_from_slice}; +use np_ffi_core::deserialize::deserialize_advertisement_from_slice; use pourover::{jni_method, ToUnsigned}; #[jni_method(package = "com.google.android.nearby.presence.rust", class = "NpAdv")] @@ -31,9 +30,11 @@ mut env: JNIEnv<'local>, _cls: JClass<'local>, service_data: JByteArray<'local>, - credential_book: jlong, + credential_book_obj: CredentialBook<JObject<'local>>, ) -> JObject<'local> { - let credential_book = CredentialBook::from_handle(Handle::from_id(credential_book as u64)); + let Ok(credential_book) = credential_book_obj.get_handle(&mut env) else { + return JObject::null(); + }; // Unpack the service data let mut service_data_buf = [0i8; 256]; @@ -74,6 +75,7 @@ adv.num_des(), adv.payload(), adv.identity_kind(), + credential_book_obj, ) .and_then(|adv| DeserializeResult::from_v0_advertisement(&mut env, adv)) .map(|obj| obj.0), @@ -85,6 +87,7 @@ jint::from(adv.num_legible_sections), jint::from(adv.num_undecryptable_sections), sections, + credential_book_obj, ) }) .and_then(|adv| DeserializeResult::from_v1_advertisement(&mut env, adv))
diff --git a/nearby/presence/np_java_ffi/src/class/serialization_exception.rs b/nearby/presence/np_java_ffi/src/class/serialization_exception.rs new file mode 100644 index 0000000..3e3235e --- /dev/null +++ b/nearby/presence/np_java_ffi/src/class/serialization_exception.rs
@@ -0,0 +1,139 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use jni::{ + objects::{JObject, JString, JThrowable}, + JNIEnv, +}; +use pourover::desc::ClassDesc; + +static INVALID_DATA_ELEMENT_EXCEPTION: ClassDesc = ClassDesc::new( + "com/google/android/nearby/presence/rust/SerializationException$InvalidDataElementException", +); + +/// Rust representation of `class SerializationException.InvalidDataElementException`. +#[repr(transparent)] +pub struct InvalidDataElementException<Obj>(pub Obj); + +impl<'local> InvalidDataElementException<JObject<'local>> { + /// Create a new instance. + pub fn construct<'s>( + env: &mut JNIEnv<'local>, + reason: &JString<'s>, + ) -> jni::errors::Result<Self> { + pourover::call_constructor!( + env, + &INVALID_DATA_ELEMENT_EXCEPTION, + "(Ljava/lang/String;)V", + reason + ) + .map(Self) + } + + /// Create a new instance and throw it. + pub fn throw_new<'s>( + env: &mut JNIEnv<'local>, + reason: &JString<'s>, + ) -> jni::errors::Result<()> { + Self::construct(env, reason)?.throw(env) + } +} + +impl<'local, Obj: AsRef<JObject<'local>>> InvalidDataElementException<Obj> { + /// Throw this exception. + pub fn throw<'env>(&self, env: &mut JNIEnv<'env>) -> jni::errors::Result<()> { + env.throw(<&JThrowable>::from(self.0.as_ref())) + } +} + +static INSUFFICIENT_SPACE_EXCEPTION: ClassDesc = ClassDesc::new( + "com/google/android/nearby/presence/rust/SerializationException$InsufficientSpaceException", +); + +/// Rust representation of `class SerializationException.InsufficientSpaceException`. +#[repr(transparent)] +pub struct InsufficientSpaceException<Obj>(pub Obj); + +impl<'local> InsufficientSpaceException<JObject<'local>> { + /// Create a new instance. + pub fn construct(env: &mut JNIEnv<'local>) -> jni::errors::Result<Self> { + pourover::call_constructor!(env, &INSUFFICIENT_SPACE_EXCEPTION, "()V",).map(Self) + } + + /// Create a new instance and throw it. + pub fn throw_new(env: &mut JNIEnv<'local>) -> jni::errors::Result<()> { + Self::construct(env)?.throw(env) + } +} + +impl<'local, Obj: AsRef<JObject<'local>>> InsufficientSpaceException<Obj> { + /// Throw this exception. + pub fn throw<'env>(&self, env: &mut JNIEnv<'env>) -> jni::errors::Result<()> { + env.throw(<&JThrowable>::from(self.0.as_ref())) + } +} + +static LDT_ENCRYPTION_EXCEPTION_CLASS: ClassDesc = ClassDesc::new( + "com/google/android/nearby/presence/rust/SerializationException$LdtEncryptionException", +); + +/// Rust representation of `class SerializationException.LdtEncryptionException`. +#[repr(transparent)] +pub struct LdtEncryptionException<Obj>(pub Obj); + +impl<'local> LdtEncryptionException<JObject<'local>> { + /// Create a new instance. + pub fn construct(env: &mut JNIEnv<'local>) -> jni::errors::Result<Self> { + pourover::call_constructor!(env, &LDT_ENCRYPTION_EXCEPTION_CLASS, "()V").map(Self) + } + + /// Create a new instance and throw it. + pub fn throw_new(env: &mut JNIEnv<'local>) -> jni::errors::Result<()> { + Self::construct(env)?.throw(env) + } +} + +impl<'local, Obj: AsRef<JObject<'local>>> LdtEncryptionException<Obj> { + /// Throw this exception. + pub fn throw<'env>(&self, env: &mut JNIEnv<'env>) -> jni::errors::Result<()> { + env.throw(<&JThrowable>::from(self.0.as_ref())) + } +} + +static UNENCRYPTED_SIZE_EXCEPTION_CLASS: ClassDesc = ClassDesc::new( + "com/google/android/nearby/presence/rust/SerializationException$UnencryptedSizeException", +); + +/// Rust representation of `class SerializationException.UnencryptedSizeException`. +#[repr(transparent)] +pub struct UnencryptedSizeException<Obj>(pub Obj); + +impl<'local> UnencryptedSizeException<JObject<'local>> { + /// Create a new instance. + pub fn construct(env: &mut JNIEnv<'local>) -> jni::errors::Result<Self> { + pourover::call_constructor!(env, &UNENCRYPTED_SIZE_EXCEPTION_CLASS, "()V").map(Self) + } + + /// Create a new instance and throw it. + pub fn throw_new(env: &mut JNIEnv<'local>) -> jni::errors::Result<()> { + Self::construct(env)?.throw(env) + } +} + +impl<'local, Obj: AsRef<JObject<'local>>> UnencryptedSizeException<Obj> { + /// Throw this exception. + pub fn throw<'env>(&self, env: &mut JNIEnv<'env>) -> jni::errors::Result<()> { + env.throw(<&JThrowable>::from(self.0.as_ref())) + } +}
diff --git a/nearby/presence/np_java_ffi/src/class/v0_advertisement_builder.rs b/nearby/presence/np_java_ffi/src/class/v0_advertisement_builder.rs new file mode 100644 index 0000000..1ba39b6 --- /dev/null +++ b/nearby/presence/np_java_ffi/src/class/v0_advertisement_builder.rs
@@ -0,0 +1,248 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use handle_map::{Handle, HandleLike}; +use jni::{ + objects::{JByteArray, JClass, JObject}, + sys::jlong, + JNIEnv, +}; +use np_ffi_core::{ + serialize::v0::{ + create_v0_encrypted_advertisement_builder, create_v0_public_advertisement_builder, + AddV0DEResult, CreateV0AdvertisementBuilderResult, SerializeV0AdvertisementResult, + V0AdvertisementBuilder, + }, + v0::{BuildTxPowerResult, V0DataElement}, +}; +use pourover::{desc::ClassDesc, jni_method}; + +use crate::class::{ + v0_data_element::{TxPower, V0Actions}, + InsufficientSpaceException, InvalidDataElementException, InvalidHandleException, + LdtEncryptionException, NoSpaceLeftException, UnencryptedSizeException, V0BroadcastCredential, +}; + +static V0_BUILDER_HANDLE_CLASS: ClassDesc = ClassDesc::new( + "com/google/android/nearby/presence/rust/V0AdvertisementBuilder$V0BuilderHandle", +); + +#[repr(transparent)] +pub struct V0BuilderHandle<Obj>(pub Obj); + +impl<'local, Obj: AsRef<JObject<'local>>> V0BuilderHandle<Obj> { + /// Get a reference to the inner `jni` crate [`JObject`]. + pub fn as_obj(&self) -> &JObject<'local> { + self.0.as_ref() + } + + /// Get the Rust [`HandleLike`] representation from this Java object. + pub fn as_rust_handle<'env>( + &self, + env: &mut JNIEnv<'env>, + ) -> jni::errors::Result<V0AdvertisementBuilder> { + let handle_id = self.get_handle_id(env)?; + Ok(V0AdvertisementBuilder::from_handle(Handle::from_id(handle_id as u64))) + } + + /// Get `long handleId` from the Java object + fn get_handle_id<'env_local>( + &self, + env: &mut JNIEnv<'env_local>, + ) -> jni::errors::Result<jlong> { + use V0_BUILDER_HANDLE_CLASS as CLS; + pourover::call_method!(env, &CLS, "getId", "()J", self.as_obj()) + } + + fn add_de<'env>( + &self, + env: &mut JNIEnv<'env>, + data_element: V0DataElement, + ) -> jni::errors::Result<()> { + let builder = self.as_rust_handle(env)?; + #[allow(clippy::expect_used)] + let res = builder.add_de(data_element).expect("valid data structure (created in Rust)"); + + match res { + AddV0DEResult::Success => {} + AddV0DEResult::InvalidAdvertisementBuilderHandle => { + InvalidHandleException::throw_new(env)?; + } + AddV0DEResult::InsufficientAdvertisementSpace => { + InsufficientSpaceException::throw_new(env)?; + } + AddV0DEResult::InvalidIdentityTypeForDataElement => { + let _ = env + .new_string("Mismatched identity kind for V0Actions data element") + .map(|string| env.auto_local(string)) + .and_then(|string| InvalidDataElementException::throw_new(env, &string)); + } + } + + Ok(()) + } +} + +#[jni_method( + package = "com.google.android.nearby.presence.rust", + class = "V0AdvertisementBuilder.V0BuilderHandle" +)] +extern "system" fn allocatePublic<'local>(mut env: JNIEnv<'local>, _cls: JClass<'local>) -> jlong { + match create_v0_public_advertisement_builder() { + CreateV0AdvertisementBuilderResult::Success(builder) => { + builder.get_as_handle().get_id() as jlong + } + CreateV0AdvertisementBuilderResult::NoSpaceLeft => { + let _ = NoSpaceLeftException::throw_new(&mut env); + 0 + } + } +} + +#[jni_method( + package = "com.google.android.nearby.presence.rust", + class = "V0AdvertisementBuilder.V0BuilderHandle" +)] +extern "system" fn allocatePrivate<'local>( + mut env: JNIEnv<'local>, + _cls: JClass<'local>, + credential: V0BroadcastCredential<JObject<'local>>, + salt_arr: JByteArray<'local>, +) -> jlong { + let Ok(credential) = credential.get_as_core(&mut env) else { + return 0; + }; + + let mut salt = [0; 2]; + if let Err(_jni_err) = env.get_byte_array_region(salt_arr, 0, &mut salt[..]) { + return 0; + } + let salt = salt.map(|byte| byte as u8).into(); + + match create_v0_encrypted_advertisement_builder(credential, salt) { + CreateV0AdvertisementBuilderResult::Success(builder) => { + builder.get_as_handle().get_id() as jlong + } + CreateV0AdvertisementBuilderResult::NoSpaceLeft => { + let _ = NoSpaceLeftException::throw_new(&mut env); + 0 + } + } +} + +#[jni_method( + package = "com.google.android.nearby.presence.rust", + class = "V0AdvertisementBuilder.V0BuilderHandle", + method_name = "nativeAddTxPowerDataElement" +)] +extern "system" fn add_tx_power_de<'local>( + mut env: JNIEnv<'local>, + this: V0BuilderHandle<JObject<'local>>, + tx_power: TxPower<JObject<'local>>, +) { + let tx_power = match tx_power.get_as_core(&mut env) { + Ok(BuildTxPowerResult::Success(tx_power)) => tx_power, + Ok(BuildTxPowerResult::OutOfRange) => { + let _ = env + .new_string("TX Power value out of range") + .map(|string| env.auto_local(string)) + .and_then(|string| InvalidDataElementException::throw_new(&mut env, &string)); + return; + } + Err(_jni_err) => { + // `crate jni` should have already thrown + return; + } + }; + let Ok(()) = this.add_de(&mut env, V0DataElement::TxPower(tx_power)) else { + // `crate jni` should have already thrown + return; + }; +} + +#[jni_method( + package = "com.google.android.nearby.presence.rust", + class = "V0AdvertisementBuilder.V0BuilderHandle", + method_name = "nativeAddV0ActionsDataElement" +)] +extern "system" fn add_v0_actions_de<'local>( + mut env: JNIEnv<'local>, + this: V0BuilderHandle<JObject<'local>>, + v0_actions: V0Actions<JObject<'local>>, +) { + let v0_actions = match v0_actions.get_as_core(&mut env) { + Ok(Some(v0_actions)) => v0_actions, + Ok(None) => { + let _ = env + .new_string("V0Actions is not valid") + .map(|string| env.auto_local(string)) + .and_then(|string| InvalidDataElementException::throw_new(&mut env, &string)); + return; + } + Err(_jni_err) => { + // `crate jni` should have already thrown + return; + } + }; + let Ok(()) = this.add_de(&mut env, V0DataElement::Actions(v0_actions)) else { + // `crate jni` should have already thrown + return; + }; +} + +#[jni_method( + package = "com.google.android.nearby.presence.rust", + class = "V0AdvertisementBuilder.V0BuilderHandle" +)] +extern "system" fn nativeBuild<'local>( + mut env: JNIEnv<'local>, + this: V0BuilderHandle<JObject<'local>>, +) -> JObject<'local> { + let Ok(builder) = this.as_rust_handle(&mut env) else { + return JObject::null(); + }; + + match builder.into_advertisement() { + SerializeV0AdvertisementResult::Success(bytes) => { + #[allow(clippy::expect_used)] + let adv_bytes = bytes.as_slice().expect("should never be malformed from core"); + env.byte_array_from_slice(adv_bytes).map_or(JObject::null(), JObject::from) + } + SerializeV0AdvertisementResult::InvalidAdvertisementBuilderHandle => { + let _ = InvalidHandleException::throw_new(&mut env); + JObject::null() + } + SerializeV0AdvertisementResult::LdtError => { + let _ = LdtEncryptionException::throw_new(&mut env); + JObject::null() + } + SerializeV0AdvertisementResult::UnencryptedError => { + let _ = UnencryptedSizeException::throw_new(&mut env); + JObject::null() + } + } +} + +#[jni_method( + package = "com.google.android.nearby.presence.rust", + class = "V0AdvertisementBuilder.V0BuilderHandle" +)] +extern "system" fn deallocate<'local>( + _env: JNIEnv<'local>, + _cls: JClass<'local>, + handle_id: jlong, +) { + let handle = V0AdvertisementBuilder::from_handle(Handle::from_id(handle_id as u64)); + let _ = handle.deallocate(); +}
diff --git a/nearby/presence/np_java_ffi/src/class/v0_broadcast_credential.rs b/nearby/presence/np_java_ffi/src/class/v0_broadcast_credential.rs new file mode 100644 index 0000000..2da6553 --- /dev/null +++ b/nearby/presence/np_java_ffi/src/class/v0_broadcast_credential.rs
@@ -0,0 +1,71 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use jni::{ + objects::{JByteArray, JObject}, + signature::ReturnType, + JNIEnv, +}; + +use np_ffi_core::credentials::V0BroadcastCredential as CoreV0BroadcastCredential; +use pourover::desc::{ClassDesc, FieldDesc}; + +static V0_DISCOVERY_CREDENTIAL_CLS: ClassDesc = + ClassDesc::new("com/google/android/nearby/presence/rust/credential/V0BroadcastCredential"); + +/// Rust representation of `class V0BroadcastCredential`. +#[repr(transparent)] +pub struct V0BroadcastCredential<Obj>(pub Obj); + +impl<'local, Obj: AsRef<JObject<'local>>> V0BroadcastCredential<Obj> { + /// Get an array field as a Rust array. + fn get_array<'env, const N: usize>( + &self, + env: &mut JNIEnv<'env>, + field: &FieldDesc, + ) -> jni::errors::Result<[u8; N]> { + let arr: JByteArray<'env> = + env.get_field_unchecked(self.0.as_ref(), field, ReturnType::Array)?.l()?.into(); + + let mut buf = [0; N]; + env.get_byte_array_region(arr, 0, &mut buf[..])?; + Ok(buf.map(|byte| byte as u8)) + } + + /// Get the key seed. + pub fn get_key_seed<'env>(&self, env: &mut JNIEnv<'env>) -> jni::errors::Result<[u8; 32]> { + static KEY_SEED: FieldDesc = V0_DISCOVERY_CREDENTIAL_CLS.field("keySeed", "[B"); + self.get_array(env, &KEY_SEED) + } + + /// Get the identity token. + pub fn get_identity_token<'env>( + &self, + env: &mut JNIEnv<'env>, + ) -> jni::errors::Result<[u8; 14]> { + static IDENTITY_TOKEN: FieldDesc = V0_DISCOVERY_CREDENTIAL_CLS.field("identityToken", "[B"); + self.get_array(env, &IDENTITY_TOKEN) + } + + /// Convert this to the `np_ffi_core` representation. + pub fn get_as_core<'env>( + &self, + env: &mut JNIEnv<'env>, + ) -> jni::errors::Result<CoreV0BroadcastCredential> { + Ok(CoreV0BroadcastCredential::new( + self.get_key_seed(env)?, + self.get_identity_token(env)?.into(), + )) + } +}
diff --git a/nearby/presence/np_java_ffi/src/class/v0_data_element.rs b/nearby/presence/np_java_ffi/src/class/v0_data_element.rs index 759a486..44f0636 100644 --- a/nearby/presence/np_java_ffi/src/class/v0_data_element.rs +++ b/nearby/presence/np_java_ffi/src/class/v0_data_element.rs
@@ -16,12 +16,15 @@ use crate::class::IdentityKind; use jni::{ - objects::{JClass, JObject}, + objects::{JClass, JIntArray, JObject}, signature::{Primitive, ReturnType}, sys::{jboolean, jint, JNI_FALSE, JNI_TRUE}, JNIEnv, }; -use np_ffi_core::{deserialize::v0::DeserializedV0IdentityKind, v0}; +use np_ffi_core::{ + common::InvalidStackDataStructure, deserialize::v0::DeserializedV0IdentityKind, + serialize::AdvertisementBuilderKind, v0, +}; use pourover::desc::{ClassDesc, FieldDesc}; static TX_POWER_CLASS: ClassDesc = @@ -61,6 +64,18 @@ ) .and_then(|ret| ret.i()) } + + /// Get the `np_ffi_core` representation of this data element. + pub fn get_as_core<'env>( + &self, + env: &mut JNIEnv<'env>, + ) -> jni::errors::Result<v0::BuildTxPowerResult> { + let power = self.get_tx_power(env)?; + let Ok(power) = i8::try_from(power) else { + return Ok(v0::BuildTxPowerResult::OutOfRange); + }; + Ok(v0::TxPower::build_from_signed_byte(power)) + } } static V0_ACTIONS_CLASS: ClassDesc = @@ -77,7 +92,7 @@ identity_kind: DeserializedV0IdentityKind, action_bits: jint, ) -> jni::errors::Result<Self> { - let identity_kind = IdentityKind::value_for_v0(env, identity_kind)?; + let identity_kind = IdentityKind::from(identity_kind).to_java(env)?; pourover::call_constructor!(env, &V0_ACTIONS_CLASS, "(II)V", identity_kind, action_bits) .map(Self) @@ -123,25 +138,36 @@ ) .and_then(|ret| ret.i()) } + + /// Get the `np_ffi_core` representation of this data element. This returns `None` if the Rust + /// representation would not be well formed. + pub fn get_as_core<'env>( + &self, + env: &mut JNIEnv<'env>, + ) -> jni::errors::Result<Option<v0::V0Actions>> { + let identity_kind = self.get_identity_kind(env)?; + let action_bits = self.get_action_bits(env)?; + construct_actions_from_parts(env, identity_kind, action_bits) + } } -/// Helper to build a [`V0Actions`][v0::V0Actions] instance from raw Java fields. -fn construct_actions_from_ints( +/// Helper to build a [`V0Actions`][v0::V0Actions] instance from raw Java fields. This will return +/// `None` if the given `identity_kind` is invalid. +fn construct_actions_from_parts( env: &mut JNIEnv<'_>, identity_kind: jint, action_bits: jint, -) -> Option<v0::V0Actions> { - let wrapper = if identity_kind == IdentityKind::plaintext(env).ok()? { - v0::V0Actions::Plaintext - } else if identity_kind == IdentityKind::decrypted(env).ok()? { - v0::V0Actions::Encrypted - } else { - return None; +) -> jni::errors::Result<Option<v0::V0Actions>> { + let opt_kind = IdentityKind::from_java(env, identity_kind)?; + + let wrapper = match opt_kind { + Some(IdentityKind::Plaintext) => v0::V0Actions::Plaintext, + Some(IdentityKind::Decrypted) => v0::V0Actions::Encrypted, + _ => return Ok(None), }; let bits = v0::V0ActionBits::from(action_bits as u32); - - Some(wrapper(bits)) + Ok(Some(wrapper(bits))) } #[pourover::jni_method( @@ -155,8 +181,18 @@ action_bits: jint, action: jint, ) -> jboolean { - let Some(actions) = construct_actions_from_ints(&mut env, identity_kind, action_bits) else { - return JNI_FALSE; + let actions = match construct_actions_from_parts(&mut env, identity_kind, action_bits) { + Ok(Some(actions)) => actions, + Ok(None) => { + let _ = env.throw_new( + "java/lang/IllegalStateException", + "V0Actions is not validly constructed", + ); + return JNI_FALSE; + } + Err(_jni_err) => { + return JNI_FALSE; + } }; let Ok(action) = u8::try_from(action).map_err(From::from).and_then(v0::ActionType::try_from) @@ -170,3 +206,82 @@ JNI_FALSE } } + +#[pourover::jni_method( + package = "com.google.android.nearby.presence.rust", + class = "V0DataElement.V0Actions" +)] +extern "system" fn nativeMergeActions<'local>( + mut env: JNIEnv<'local>, + _cls: JClass<'local>, + identity_kind: jint, + actions: JIntArray<'local>, +) -> jint { + let actions = { + let Ok(len) = env.get_array_length(&actions) else { + // `crate jni` should have already thrown + return 0; + }; + let Ok(len) = usize::try_from(len) else { + // Should never occur + return 0; + }; + let mut vec = vec![0; len]; + if env.get_int_array_region(&actions, 0, &mut vec[..]).is_err() { + // `crate jni` should have already thrown + return 0; + }; + vec + }; + + let mut parse_kind = + |identity_kind: jint| -> jni::errors::Result<Option<AdvertisementBuilderKind>> { + IdentityKind::from_java(&mut env, identity_kind).map(|opt_kind| { + opt_kind.and_then(|kind| match kind { + IdentityKind::Plaintext => Some(AdvertisementBuilderKind::Public), + IdentityKind::Decrypted => Some(AdvertisementBuilderKind::Encrypted), + _ => None, + }) + }) + }; + + let adv_kind = match parse_kind(identity_kind) { + Ok(Some(adv_kind)) => adv_kind, + Ok(None) => { + let _ = env.throw_new("java/lang/IllegalArgumentException", "Invalid identity kind"); + return 0; + } + Err(_jni_err) => return 0, + }; + + let mut v0_actions = v0::V0Actions::new_zeroed(adv_kind); + for action in actions { + let Ok(action_type) = + u8::try_from(action).map_err(Into::into).and_then(v0::ActionType::try_from) + else { + let _ = env.throw_new( + "java/lang/IllegalArgumentException", + format!("V0ActionType is invalid: {action}"), + ); + return 0; + }; + + v0_actions = match v0_actions.set_action(action_type, true) { + Ok(v0::SetV0ActionResult::Success(v0_actions)) => v0_actions, + Ok(v0::SetV0ActionResult::Error(_v0_actions)) => { + let _ = env.throw_new( + "java/lang/IllegalStateException", + "V0ActionType is not valid for this IdentityKind", + ); + return 0; + } + Err(InvalidStackDataStructure) => { + let _ = env + .throw_new("java/lang/IllegalStateException", "Memory has somehow corrupted"); + return 0; + } + }; + } + + 0 +}
diff --git a/nearby/presence/np_java_ffi/src/class/v0_payload.rs b/nearby/presence/np_java_ffi/src/class/v0_payload.rs index 9b5e05b..e962f5e 100644 --- a/nearby/presence/np_java_ffi/src/class/v0_payload.rs +++ b/nearby/presence/np_java_ffi/src/class/v0_payload.rs
@@ -19,9 +19,49 @@ sys::{jint, jlong}, JNIEnv, }; -use np_ffi_core::deserialize::v0::{DeserializedV0IdentityKind, V0Payload}; +use np_ffi_core::deserialize::{ + v0::{DeserializedV0IdentityDetails, DeserializedV0IdentityKind, V0Payload}, + DecryptMetadataResult, +}; use np_ffi_core::v0::V0Actions as CoreV0Actions; -use pourover::jni_method; +use pourover::{desc::ClassDesc, jni_method}; + +static IDENTITY_DETAILS_CLASS: ClassDesc = + ClassDesc::new("com/google/android/nearby/presence/rust/V0Payload$IdentityDetails"); + +#[repr(transparent)] +pub struct IdentityDetails<Obj>(pub Obj); + +impl<'local> IdentityDetails<JObject<'local>> { + pub fn construct( + env: &mut JNIEnv<'local>, + details: DeserializedV0IdentityDetails, + ) -> jni::errors::Result<Self> { + Self::construct_from_parts(env, details.cred_id(), details.identity_token(), details.salt()) + } + + /// Create an IdentityDetails instance + pub fn construct_from_parts( + env: &mut JNIEnv<'local>, + credential_id: u32, + identity_token: [u8; 14], + salt: [u8; 2], + ) -> jni::errors::Result<Self> { + let credential_id = credential_id as jint; + let identity_token = env.byte_array_from_slice(&identity_token)?; + let salt = env.byte_array_from_slice(&salt)?; + + pourover::call_constructor!( + env, + &IDENTITY_DETAILS_CLASS, + "(I[B[B)V", + credential_id, + identity_token, + salt + ) + .map(Self) + } +} #[jni_method(package = "com.google.android.nearby.presence.rust", class = "V0Payload")] extern "system" fn nativeGetDataElement<'local>( @@ -63,6 +103,44 @@ } #[jni_method(package = "com.google.android.nearby.presence.rust", class = "V0Payload")] +extern "system" fn nativeGetIdentityDetails<'local>( + mut env: JNIEnv<'local>, + _cls: JClass<'local>, + handle_id: jlong, +) -> JObject<'local> { + let v0_payload = V0Payload::from_handle(Handle::from_id(handle_id as u64)); + + use np_ffi_core::deserialize::v0::GetV0IdentityDetailsResult::*; + match v0_payload.get_identity_details() { + Success(details) => IdentityDetails::construct(&mut env, details) + .map_or_else(|_err| JObject::null(), |obj| obj.0), + Error => JObject::null(), + } +} + +#[jni_method(package = "com.google.android.nearby.presence.rust", class = "V0Payload")] +extern "system" fn nativeGetDecryptedMetadata<'local>( + env: JNIEnv<'local>, + _cls: JClass<'local>, + handle_id: jlong, +) -> JObject<'local> { + let v0_payload = V0Payload::from_handle(Handle::from_id(handle_id as u64)); + + let DecryptMetadataResult::Success(metadata) = v0_payload.decrypt_metadata() else { + return JObject::null(); + }; + + let Ok(buffer) = metadata.take_buffer() else { + return JObject::null(); + }; + let Ok(decrypted_metadata_array) = env.byte_array_from_slice(&buffer[..]) else { + return JObject::null(); + }; + + decrypted_metadata_array.into() +} + +#[jni_method(package = "com.google.android.nearby.presence.rust", class = "V0Payload")] extern "system" fn deallocate<'local>( _env: JNIEnv<'local>, _cls: JClass<'local>,
diff --git a/nearby/presence/np_java_ffi/src/class/v1_broadcast_credential.rs b/nearby/presence/np_java_ffi/src/class/v1_broadcast_credential.rs new file mode 100644 index 0000000..01fd30f --- /dev/null +++ b/nearby/presence/np_java_ffi/src/class/v1_broadcast_credential.rs
@@ -0,0 +1,78 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use jni::{ + objects::{JByteArray, JObject}, + signature::ReturnType, + JNIEnv, +}; + +use np_ffi_core::credentials::V1BroadcastCredential as CoreV1BroadcastCredential; +use pourover::desc::{ClassDesc, FieldDesc}; + +static V1_DISCOVERY_CREDENTIAL_CLS: ClassDesc = + ClassDesc::new("com/google/android/nearby/presence/rust/credential/V1BroadcastCredential"); + +/// Rust representation of `class V1BroadcastCredential`. +#[repr(transparent)] +pub struct V1BroadcastCredential<Obj>(pub Obj); + +impl<'local, Obj: AsRef<JObject<'local>>> V1BroadcastCredential<Obj> { + /// Get an array field as a Rust array. + fn get_array<'env, const N: usize>( + &self, + env: &mut JNIEnv<'env>, + field: &FieldDesc, + ) -> jni::errors::Result<[u8; N]> { + let arr: JByteArray<'env> = + env.get_field_unchecked(self.0.as_ref(), field, ReturnType::Array)?.l()?.into(); + + let mut buf = [0; N]; + env.get_byte_array_region(arr, 0, &mut buf[..])?; + Ok(buf.map(|byte| byte as u8)) + } + + /// Get the key seed. + pub fn get_key_seed<'env>(&self, env: &mut JNIEnv<'env>) -> jni::errors::Result<[u8; 32]> { + static KEY_SEED: FieldDesc = V1_DISCOVERY_CREDENTIAL_CLS.field("keySeed", "[B"); + self.get_array(env, &KEY_SEED) + } + + /// Get the identity token. + pub fn get_identity_token<'env>( + &self, + env: &mut JNIEnv<'env>, + ) -> jni::errors::Result<[u8; 16]> { + static IDENTITY_TOKEN: FieldDesc = V1_DISCOVERY_CREDENTIAL_CLS.field("identityToken", "[B"); + self.get_array(env, &IDENTITY_TOKEN) + } + + /// Get the private key. + pub fn get_private_key<'env>(&self, env: &mut JNIEnv<'env>) -> jni::errors::Result<[u8; 32]> { + static PRIVATE_KEY: FieldDesc = V1_DISCOVERY_CREDENTIAL_CLS.field("privateKey", "[B"); + self.get_array(env, &PRIVATE_KEY) + } + + /// Convert this to the `np_ffi_core` representation. + pub fn get_as_core<'env>( + &self, + env: &mut JNIEnv<'env>, + ) -> jni::errors::Result<CoreV1BroadcastCredential> { + Ok(CoreV1BroadcastCredential::new( + self.get_key_seed(env)?, + self.get_identity_token(env)?.into(), + self.get_private_key(env)?, + )) + } +}
diff --git a/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/DecryptTests.java b/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/DecryptTests.java new file mode 100644 index 0000000..f9a7ede --- /dev/null +++ b/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/DecryptTests.java
@@ -0,0 +1,89 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.nearby.presence.rust; + +import static com.google.android.nearby.presence.rust.TestData.*; +import static com.google.common.truth.Truth.assertThat; + +import com.google.android.nearby.presence.rust.credential.CredentialBook; +import org.junit.jupiter.api.Test; + +public class DecryptTests { + + public static final class TestMetadata implements CredentialBook.MatchedMetadata { + public byte[] plaintextMetadata; + public byte[] encryptedMetadata; + + public TestMetadata(byte[] plaintextMetadata, byte[] encryptedMetadata) { + this.plaintextMetadata = plaintextMetadata; + this.encryptedMetadata = encryptedMetadata; + } + + @Override + public byte[] getEncryptedMetadataBytes() { + return encryptedMetadata; + } + } + + public static final TestMetadata V0_METADATA = + new TestMetadata(ALICE_METADATA, V0_ENCRYPTED_ALICE_METADATA); + public static final TestMetadata V1_METADATA = + new TestMetadata(ALICE_METADATA, V1_ENCRYPTED_ALICE_METADATA); + + DeserializeResult<TestMetadata> parsePrivateAdv(byte[] bytes) { + try (CredentialBook<TestMetadata> book = + CredentialBook.<TestMetadata>builder() + .addDiscoveryCredential(V0_CRED, V0_METADATA) + .addDiscoveryCredential(V1_CRED, V1_METADATA) + .build()) { + return NpAdv.deserializeAdvertisement(bytes, book); + } + } + + @Test + void deserializeAdvertisement_v0_canParsePrivate() { + try (DeserializeResult result = parsePrivateAdv(V0_PRIVATE)) { + assertThat(result.getKind()).isEqualTo(DeserializeResult.Kind.V0_ADVERTISEMENT); + + DeserializedV0Advertisement adv = result.getAsV0(); + + assertThat(adv).isNotNull(); + assertThat(adv.isLegible()).isTrue(); + assertThat(adv.getIdentity()).isEqualTo(IdentityKind.DECRYPTED); + assertThat(adv.getMatchedMetadata()).isSameInstanceAs(V0_METADATA); + assertThat(adv.getDecryptedMetadata()).isEqualTo(ALICE_METADATA); + } + } + + @Test + void deserializeAdvertisement_v1_canParsePrivate() { + try (DeserializeResult result = parsePrivateAdv(V1_PRIVATE)) { + assertThat(result.getKind()).isEqualTo(DeserializeResult.Kind.V1_ADVERTISEMENT); + + DeserializedV1Advertisement adv = result.getAsV1(); + + assertThat(adv).isNotNull(); + assertThat(adv.getNumLegibleSections()).isEqualTo(1); + assertThat(adv.getNumUndecryptableSections()).isEqualTo(0); + + DeserializedV1Section section = adv.getSection(0); + assertThat(section.getIdentityKind()).isEqualTo(IdentityKind.DECRYPTED); + assertThat(section.getMatchedMetadata()).isSameInstanceAs(V1_METADATA); + assertThat(section.getDecryptedMetadata()).isEqualTo(ALICE_METADATA); + } + } +}
diff --git a/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/DeserializeTests.java b/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/DeserializeTests.java index d4f146e..7457edb 100644 --- a/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/DeserializeTests.java +++ b/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/DeserializeTests.java
@@ -16,6 +16,7 @@ package com.google.android.nearby.presence.rust; +import static com.google.android.nearby.presence.rust.DeserializedV1Section.VerificationMode; import static com.google.android.nearby.presence.rust.TestData.*; import static com.google.android.nearby.presence.rust.credential.CredentialBook.NoMetadata; import static com.google.common.truth.Truth.assertThat; @@ -53,6 +54,8 @@ assertThat(adv.isLegible()).isTrue(); assertThat(adv.getIdentity()).isEqualTo(IdentityKind.PLAINTEXT); assertThat(adv.getDataElementCount()).isEqualTo(2); + assertThat(adv.getMatchedMetadata()).isNull(); + assertThat(adv.getDecryptedMetadata()).isNull(); } } @@ -67,6 +70,8 @@ assertThat(adv.isLegible()).isTrue(); assertThat(adv.getIdentity()).isEqualTo(IdentityKind.PLAINTEXT); assertThat(adv.getDataElementCount()).isEqualTo(2); + assertThat(adv.getMatchedMetadata()).isNull(); + assertThat(adv.getDecryptedMetadata()).isNull(); } } @@ -82,6 +87,10 @@ assertThat(adv.getIdentity()).isEqualTo(IdentityKind.DECRYPTED); assertThat(adv.getDataElementCount()).isEqualTo(1); assertThat(adv.getDataElement(0)).isInstanceOf(V0DataElement.TxPower.class); + assertThat(adv.getIdentityToken()).isEqualTo(V0_IDENTITY_TOKEN); + assertThat(adv.getSalt()).asList().containsExactly((byte) 0x22, (byte) 0x22); + assertThat(adv.getMatchedMetadata()).isSameInstanceAs(NoMetadata.INSTANCE); + assertThat(adv.getDecryptedMetadata()).isNull(); } } @@ -152,6 +161,10 @@ DeserializedV1Section section = adv.getSection(0); assertThat(section.getIdentityKind()).isEqualTo(IdentityKind.DECRYPTED); assertThat(section.getDataElementCount()).isEqualTo(1); + assertThat(section.getIdentityToken()).isEqualTo(V1_IDENTITY_TOKEN); + assertThat(section.getVerificationMode()).isEqualTo(VerificationMode.SIGNATURE); + assertThat(section.getMatchedMetadata()).isSameInstanceAs(NoMetadata.INSTANCE); + assertThat(section.getDecryptedMetadata()).isNull(); } } @@ -178,6 +191,8 @@ assertThat(section).isNotNull(); assertThat(section.getIdentityKind()).isEqualTo(IdentityKind.PLAINTEXT); assertThat(section.getDataElementCount()).isEqualTo(1); + assertThat(section.getMatchedMetadata()).isNull(); + assertThat(section.getDecryptedMetadata()).isNull(); } }
diff --git a/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/SerializeTests.java b/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/SerializeTests.java new file mode 100644 index 0000000..b8e18fd --- /dev/null +++ b/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/SerializeTests.java
@@ -0,0 +1,183 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.nearby.presence.rust; + +import static com.google.android.nearby.presence.rust.TestData.*; +import static com.google.android.nearby.presence.rust.V0DataElement.TxPower; +import static com.google.android.nearby.presence.rust.V0DataElement.V0ActionType; +import static com.google.android.nearby.presence.rust.V0DataElement.V0Actions; +import static com.google.android.nearby.presence.rust.credential.CredentialBook.NoMetadata; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.google.android.nearby.presence.rust.credential.CredentialBook; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +public class SerializeTests { + + public static final TxPower TX_POWER = new TxPower(7); + public static final TxPower INVALID_TX_POWER = new TxPower(-777); + + public static final V0Actions PUBLIC_ACTIONS = + new V0Actions(IdentityKind.PLAINTEXT, V0ActionType.NEARBY_SHARE, V0ActionType.CROSS_DEV_SDK); + public static final V0Actions PRIVATE_ACTIONS = + new V0Actions(IdentityKind.DECRYPTED, V0ActionType.CALL_TRANSFER, V0ActionType.NEARBY_SHARE); + + public static final byte[] SALT = new byte[] {0x12, 0x34}; + + @Test + void serializeAdvertisement_v0_canSerialize() throws Exception { + try (V0AdvertisementBuilder builder = V0AdvertisementBuilder.newPublic()) { + builder.addDataElement(TX_POWER); + builder.addDataElement(PUBLIC_ACTIONS); + byte[] adv = builder.build(); + assertThat(adv).isNotNull(); + } + } + + @Test + void serializeAdvertisement_v0_canSerializePrivate() throws Exception { + try (V0AdvertisementBuilder builder = + V0AdvertisementBuilder.newEncrypted(V0_BROADCAST_CRED, SALT)) { + builder.addDataElement(TX_POWER); + builder.addDataElement(PRIVATE_ACTIONS); + byte[] adv = builder.build(); + assertThat(adv).isNotNull(); + } + } + + @Test + void serializeAdvertisement_v0_canRoundtrip() throws Exception { + try (V0AdvertisementBuilder builder = V0AdvertisementBuilder.newPublic(); + CredentialBook book = CredentialBook.empty()) { + builder.addDataElement(TX_POWER); + builder.addDataElement(PUBLIC_ACTIONS); + byte[] advBytes = builder.build(); + + DeserializeResult result = NpAdv.deserializeAdvertisement(advBytes, book); + DeserializedV0Advertisement adv = result.getAsV0(); + + assertThat(adv).isNotNull(); + assertThat(adv.getDataElementCount()).isEqualTo(2); + V0DataElement de0 = adv.getDataElement(0); + assertThat(de0).isInstanceOf(TxPower.class); + TxPower txPower = (TxPower) de0; + assertThat(txPower.getTxPower()).isEqualTo(TX_POWER.getTxPower()); + V0DataElement de1 = adv.getDataElement(1); + assertThat(de1).isInstanceOf(V0Actions.class); + V0Actions v0Actions = (V0Actions) de1; + assertThat(v0Actions.getIdentityKind()).isEqualTo(IdentityKind.PLAINTEXT); + assertThat(v0Actions.getActionBits()).isEqualTo(PUBLIC_ACTIONS.getActionBits()); + } + } + + @Test + void serializeAdvertisement_v0_canRoundtripPrivate() throws Exception { + try (V0AdvertisementBuilder builder = + V0AdvertisementBuilder.newEncrypted(V0_BROADCAST_CRED, SALT); + CredentialBook book = + CredentialBook.builder().addDiscoveryCredential(V0_CRED, NoMetadata.INSTANCE).build()) { + builder.addDataElement(TX_POWER); + builder.addDataElement(PRIVATE_ACTIONS); + byte[] advBytes = builder.build(); + + DeserializeResult result = NpAdv.deserializeAdvertisement(advBytes, book); + DeserializedV0Advertisement adv = result.getAsV0(); + + assertThat(adv).isNotNull(); + assertThat(adv.getDataElementCount()).isEqualTo(2); + V0DataElement de0 = adv.getDataElement(0); + assertThat(de0).isInstanceOf(TxPower.class); + TxPower txPower = (TxPower) de0; + assertThat(txPower.getTxPower()).isEqualTo(TX_POWER.getTxPower()); + V0DataElement de1 = adv.getDataElement(1); + assertThat(de1).isInstanceOf(V0Actions.class); + V0Actions v0Actions = (V0Actions) de1; + assertThat(v0Actions.getIdentityKind()).isEqualTo(IdentityKind.DECRYPTED); + assertThat(v0Actions.getActionBits()).isEqualTo(PRIVATE_ACTIONS.getActionBits()); + } + } + + @Test + void serializeAdvertisement_v0_emptyIsError() throws Exception { + try (V0AdvertisementBuilder builder = V0AdvertisementBuilder.newPublic()) { + assertThrows(SerializationException.UnencryptedSizeException.class, () -> builder.build()); + } + } + + @Test + void serializeAdvertisement_v0_fullIsError() throws Exception { + try (V0AdvertisementBuilder builder = V0AdvertisementBuilder.newPublic()) { + assertThrows( + SerializationException.InsufficientSpaceException.class, + () -> { + // Overfill the advertisement. Fixing b/311225033 will break this method. + for (int i = 0; i < 50; i++) { + builder.addDataElement(TX_POWER); + } + }); + } + } + + @Test + void serializeAdvertisement_v0_publicAdvPrivateActionsIsError() throws Exception { + try (V0AdvertisementBuilder builder = V0AdvertisementBuilder.newPublic()) { + assertThrows( + SerializationException.InvalidDataElementException.class, + () -> builder.addDataElement(PRIVATE_ACTIONS)); + } + } + + @Test + void serializeAdvertisement_v0_privateAdvPublicActionsIsError() throws Exception { + try (V0AdvertisementBuilder builder = + V0AdvertisementBuilder.newEncrypted(V0_BROADCAST_CRED, SALT)) { + assertThrows( + SerializationException.InvalidDataElementException.class, + () -> builder.addDataElement(PUBLIC_ACTIONS)); + } + } + + @Test + void serializeAdvertisement_v0_invalidTxPowerIsError() throws Exception { + try (V0AdvertisementBuilder builder = V0AdvertisementBuilder.newPublic()) { + assertThrows( + SerializationException.InvalidDataElementException.class, + () -> builder.addDataElement(INVALID_TX_POWER)); + } + } + + @Test + void serializeAdvertisement_v0_handleIsConsumedByBuild() throws Exception { + try (V0AdvertisementBuilder builder = V0AdvertisementBuilder.newPublic()) { + builder.addDataElement(TX_POWER); + byte[] adv = builder.build(); + assertThrows(Handle.InvalidHandleException.class, () -> builder.addDataElement(TX_POWER)); + assertThrows(Handle.InvalidHandleException.class, () -> builder.build()); + } + } + + @Test + @Disabled("b/311225033: Duplicate data element spec change not implemented") + void serializeAdvertisement_v0_deNotAddedTwice() throws Exception { + try (V0AdvertisementBuilder builder = V0AdvertisementBuilder.newPublic()) { + builder.addDataElement(TX_POWER); + assertThrows(Exception.class, () -> builder.addDataElement(TX_POWER)); + } + } +}
diff --git a/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/TestData.java b/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/TestData.java index 8ee26a1..122b2a9 100644 --- a/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/TestData.java +++ b/nearby/presence/np_java_ffi/test/com/google/android/nearby/presence/rust/TestData.java
@@ -16,6 +16,7 @@ package com.google.android.nearby.presence.rust; +import com.google.android.nearby.presence.rust.credential.V0BroadcastCredential; import com.google.android.nearby.presence.rust.credential.V0DiscoveryCredential; import com.google.android.nearby.presence.rust.credential.V1DiscoveryCredential; @@ -34,6 +35,173 @@ 0x15, 0x06, // tx power value 6 }; + public static final byte[] ALICE_METADATA = { + (byte) 0x7b, + (byte) 0x22, + (byte) 0x6e, + (byte) 0x61, + (byte) 0x6d, + (byte) 0x65, + (byte) 0x22, + (byte) 0x3a, + (byte) 0x22, + (byte) 0x41, + (byte) 0x6c, + (byte) 0x69, + (byte) 0x63, + (byte) 0x65, + (byte) 0x22, + (byte) 0x2c, + (byte) 0x22, + (byte) 0x65, + (byte) 0x6d, + (byte) 0x61, + (byte) 0x69, + (byte) 0x6c, + (byte) 0x22, + (byte) 0x3a, + (byte) 0x22, + (byte) 0x61, + (byte) 0x6c, + (byte) 0x69, + (byte) 0x63, + (byte) 0x65, + (byte) 0x40, + (byte) 0x67, + (byte) 0x6d, + (byte) 0x61, + (byte) 0x69, + (byte) 0x6c, + (byte) 0x2e, + (byte) 0x63, + (byte) 0x6f, + (byte) 0x6d, + (byte) 0x22, + (byte) 0x7d + }; + + public static final byte[] V0_ENCRYPTED_ALICE_METADATA = { + (byte) 0x8d, + (byte) 0xd4, + (byte) 0x7a, + (byte) 0x58, + (byte) 0x47, + (byte) 0x30, + (byte) 0x65, + (byte) 0x89, + (byte) 0x06, + (byte) 0x16, + (byte) 0x04, + (byte) 0xca, + (byte) 0x68, + (byte) 0xce, + (byte) 0xb4, + (byte) 0x18, + (byte) 0xa7, + (byte) 0x40, + (byte) 0xb8, + (byte) 0x36, + (byte) 0xb0, + (byte) 0x94, + (byte) 0xb4, + (byte) 0xc0, + (byte) 0x6c, + (byte) 0xaf, + (byte) 0x7c, + (byte) 0x4a, + (byte) 0x3b, + (byte) 0x68, + (byte) 0x28, + (byte) 0x54, + (byte) 0x8f, + (byte) 0x36, + (byte) 0xd5, + (byte) 0x68, + (byte) 0x12, + (byte) 0x6c, + (byte) 0xc2, + (byte) 0x63, + (byte) 0x31, + (byte) 0x4a, + (byte) 0x48, + (byte) 0xe4, + (byte) 0x3b, + (byte) 0xb3, + (byte) 0xcf, + (byte) 0xd4, + (byte) 0x10, + (byte) 0x49, + (byte) 0x59, + (byte) 0xe7, + (byte) 0x2b, + (byte) 0xde, + (byte) 0xeb, + (byte) 0x78, + (byte) 0x44, + (byte) 0x68 + }; + + public static final byte[] V1_ENCRYPTED_ALICE_METADATA = { + (byte) 0x0c, + (byte) 0x27, + (byte) 0x43, + (byte) 0x58, + (byte) 0xb8, + (byte) 0xb9, + (byte) 0x90, + (byte) 0x72, + (byte) 0xb1, + (byte) 0xe8, + (byte) 0xba, + (byte) 0x7d, + (byte) 0x8e, + (byte) 0xdb, + (byte) 0xac, + (byte) 0x7e, + (byte) 0x15, + (byte) 0xd5, + (byte) 0x05, + (byte) 0x30, + (byte) 0x4d, + (byte) 0xb7, + (byte) 0xe0, + (byte) 0xbd, + (byte) 0x8f, + (byte) 0xe9, + (byte) 0xab, + (byte) 0x48, + (byte) 0x66, + (byte) 0xac, + (byte) 0x2c, + (byte) 0x8a, + (byte) 0x24, + (byte) 0x0c, + (byte) 0x02, + (byte) 0xb4, + (byte) 0xd0, + (byte) 0xb7, + (byte) 0x10, + (byte) 0xd6, + (byte) 0x30, + (byte) 0x12, + (byte) 0xd6, + (byte) 0x98, + (byte) 0xdc, + (byte) 0x55, + (byte) 0xae, + (byte) 0xb0, + (byte) 0x9c, + (byte) 0x9a, + (byte) 0x7d, + (byte) 0x2e, + (byte) 0xcb, + (byte) 0xba, + (byte) 0xdd, + (byte) 0x7d, + (byte) 0x4e, + (byte) 0xd1 + }; + public static final byte[] V0_KEY_SEED = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, @@ -42,8 +210,6 @@ public static final byte[] V0_IDENTITY_TOKEN = { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, - 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, - 0x33, 0x33, 0x33, 0x33 }; public static final byte[] V0_IDENTITY_TOKEN_HMAC = { @@ -84,6 +250,9 @@ public static final V0DiscoveryCredential V0_CRED = new V0DiscoveryCredential(V0_KEY_SEED, V0_IDENTITY_TOKEN_HMAC); + public static final V0BroadcastCredential V0_BROADCAST_CRED = + new V0BroadcastCredential(V0_KEY_SEED, V0_IDENTITY_TOKEN); + public static final byte[] V0_PRIVATE = { 0x04, // adv header 0x22,
diff --git a/nearby/src/ffi.rs b/nearby/src/ffi.rs index ac0c585..3427747 100644 --- a/nearby/src/ffi.rs +++ b/nearby/src/ffi.rs
@@ -12,99 +12,110 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{crypto_ffi, CargoOptions}; +use crate::CargoOptions; use cmd_runner::{run_cmd_shell, run_cmd_shell_with_color, YellowStderr}; use std::{fs, path}; // wrapper for checking all ffi related things -pub fn check_ffi(root: &path::Path, cargo_options: &CargoOptions) -> anyhow::Result<()> { - crypto_ffi::check_boringssl(root, cargo_options)?; - check_np_ffi_cmake(root, cargo_options)?; - check_ldt_cmake(root, cargo_options)?; - +pub(crate) fn check_all_ffi( + root: &path::Path, + cargo_options: &CargoOptions, + boringssl_enabled: bool, +) -> anyhow::Result<()> { + check_np_ffi_cmake(root, cargo_options, boringssl_enabled)?; + check_ldt_cmake(root, cargo_options, boringssl_enabled)?; + check_ukey2_cmake(root, cargo_options, boringssl_enabled)?; Ok(()) } -pub fn check_np_ffi_cmake(root: &path::Path, cargo_options: &CargoOptions) -> anyhow::Result<()> { +pub(crate) fn check_np_ffi_cmake( + root: &path::Path, + cargo_options: &CargoOptions, + boringssl_enabled: bool, +) -> anyhow::Result<()> { log::info!("Checking CMake build and tests for np ffi c/c++ code"); - let build_dir = root.join("presence/cmake-build"); - fs::create_dir_all(&build_dir)?; - let locked_arg = if cargo_options.locked { "--locked" } else { "" }; + let features = + if boringssl_enabled { "--no-default-features --features boringssl" } else { "" }; + run_cmd_shell(root, format!("cargo build -p np_c_ffi {locked_arg} {features} --release"))?; + let build_dir = root.join("cmake-build"); + fs::create_dir_all(&build_dir)?; run_cmd_shell_with_color::<YellowStderr>( &build_dir, "cmake -G Ninja -DENABLE_TESTS=true -DCMAKE_BUILD_TYPE=Release -DENABLE_FUZZ=false ..", )?; - - // verify sample and benchmarks build - let np_ffi_crate_dir = root.to_path_buf().join("presence/np_c_ffi"); - run_cmd_shell(&np_ffi_crate_dir, format!("cargo build {locked_arg} --release"))?; run_cmd_shell_with_color::<YellowStderr>(&build_dir, "cmake --build . --target np_cpp_sample")?; run_cmd_shell_with_color::<YellowStderr>(&build_dir, "cmake --build . --target np_ffi_bench")?; - // Run tests with different crypto backends - let tests_dir = build_dir.join("np_cpp_ffi/tests"); - for build_config in [ - // test with default build settings (rustcrypto) - format!("build {locked_arg} --quiet --release"), - // test with boringssl - format!("build {locked_arg} --quiet --no-default-features --features=boringssl"), - ] { - let _ = run_cmd_shell_with_color::<YellowStderr>( - &build_dir, - "rm np_cpp_ffi/tests/np_ffi_tests", - ); - run_cmd_shell(&np_ffi_crate_dir, format!("cargo {}", build_config))?; - run_cmd_shell_with_color::<YellowStderr>( - &build_dir, - "cmake --build . --target np_ffi_tests", - )?; - run_cmd_shell_with_color::<YellowStderr>(&tests_dir, "ctest")?; - } - + // Force detection of updated static lib if previous version was already built + let test_dir = build_dir.join("presence/np_cpp_ffi/tests"); + let _ = run_cmd_shell_with_color::<YellowStderr>(&test_dir, "rm np_ffi_tests"); + run_cmd_shell_with_color::<YellowStderr>(&build_dir, "cmake --build . --target np_ffi_tests")?; + run_cmd_shell_with_color::<YellowStderr>(&test_dir, "ctest")?; Ok(()) } -pub fn check_ldt_cmake(root: &path::Path, cargo_options: &CargoOptions) -> anyhow::Result<()> { +pub(crate) fn check_ldt_cmake( + root: &path::Path, + cargo_options: &CargoOptions, + boringssl_enabled: bool, +) -> anyhow::Result<()> { log::info!("Checking CMake build and tests for ldt c/c++ code"); - let build_dir = root.join("presence/cmake-build"); - fs::create_dir_all(&build_dir)?; - let locked_arg = if cargo_options.locked { "--locked" } else { "" }; + let features = + if boringssl_enabled { "--no-default-features --features boringssl" } else { "" }; + run_cmd_shell( + root, + format!("cargo build {locked_arg} {features} -p ldt_np_adv_ffi --quiet --release"), + )?; + let build_dir = root.join("cmake-build"); + fs::create_dir_all(&build_dir)?; run_cmd_shell_with_color::<YellowStderr>( &build_dir, "cmake -G Ninja -DENABLE_TESTS=true -DCMAKE_BUILD_TYPE=Release -DENABLE_FUZZ=false ..", )?; - - run_cmd_shell(root, format!("cargo build {locked_arg} -p ldt_np_adv_ffi --quiet --release"))?; run_cmd_shell_with_color::<YellowStderr>(&build_dir, "cmake --build . --target ldt_c_sample")?; run_cmd_shell_with_color::<YellowStderr>( &build_dir, "cmake --build . --target ldt_benchmarks", )?; + // Force detection of updated static lib if previous version was already built + let test_dir = build_dir.join("presence/ldt_np_adv_ffi/c/tests"); + let _ = run_cmd_shell_with_color::<YellowStderr>(&test_dir, "rm ldt_ffi_tests"); + run_cmd_shell_with_color::<YellowStderr>(&build_dir, "cmake --build . --target ldt_ffi_tests")?; + run_cmd_shell_with_color::<YellowStderr>(&test_dir, "ctest")?; + Ok(()) +} - // Run the LDT ffi unit tests. These are rebuilt and tested against all of the different - // Cargo build configurations based on the feature flags. - let ldt_tests_dir = build_dir.join("ldt_np_adv_ffi/c/tests"); - for build_config in [ - // test with default build settings (rustcrypto, no_std) - format!("build {locked_arg} --quiet --release"), - // test with boringssl crypto feature flag - format!("build {locked_arg} --quiet --no-default-features --features boringssl --release"), - // test without defaults and std feature flag - format!("build {locked_arg} --quiet --no-default-features --features std --release"), - ] { - run_cmd_shell(root, format!("cargo {} -p ldt_np_adv_ffi", build_config))?; - // Force detection of updated `ldt_np_adv_ffi` static lib - let _ = run_cmd_shell_with_color::<YellowStderr>(&ldt_tests_dir, "rm ldt_ffi_tests"); - run_cmd_shell_with_color::<YellowStderr>( - &build_dir, - "cmake --build . --target ldt_ffi_tests", - )?; - run_cmd_shell_with_color::<YellowStderr>(&ldt_tests_dir, "ctest")?; - } +pub(crate) fn check_ukey2_cmake( + root: &path::Path, + cargo_options: &CargoOptions, + boringssl_enabled: bool, +) -> anyhow::Result<()> { + log::info!("Checking Ukey2 ffi"); + let locked_arg = if cargo_options.locked { "--locked" } else { "" }; + let features = + if boringssl_enabled { "--no-default-features --features boringssl" } else { "" }; + run_cmd_shell( + root, + format!("cargo build -p ukey2_c_ffi {locked_arg} {features} --quiet --release --lib"), + )?; + + let build_dir = root.join("cmake-build"); + fs::create_dir_all(&build_dir)?; + run_cmd_shell_with_color::<YellowStderr>( + &build_dir, + "cmake -G Ninja -DENABLE_TESTS=true -DENABLE_FUZZ=false ..", + )?; + let test_dir = build_dir.join("connections/ukey2/ukey2_c_ffi/cpp"); + let _ = run_cmd_shell_with_color::<YellowStderr>(&test_dir, "rm ukey2_ffi_test"); + run_cmd_shell_with_color::<YellowStderr>( + &build_dir, + "cmake --build . --target ukey2_ffi_test", + )?; + run_cmd_shell_with_color::<YellowStderr>(&test_dir, "ctest")?; Ok(()) }
diff --git a/nearby/src/fuzzers.rs b/nearby/src/fuzzers.rs index fa4f21e..e809518 100644 --- a/nearby/src/fuzzers.rs +++ b/nearby/src/fuzzers.rs
@@ -63,11 +63,9 @@ // Runs the fuzztest fuzzers as short lived unit tests, compatible with gtest pub(crate) fn build_fuzztest_unit_tests(root: &path::Path) -> anyhow::Result<()> { log::info!("Checking fuzztest targets in unit test mode"); - - // first build the rust static libs to link against - let np_ffi_crate_dir = root.join("presence/np_c_ffi"); - run_cmd_shell(&np_ffi_crate_dir, "cargo build --release")?; - let build_dir = root.join("presence/cmake-build"); + run_cmd_shell(root, "cargo build -p np_c_ffi --release")?; + run_cmd_shell(root, "cargo build -p ldt_np_adv_ffi --release")?; + let build_dir = root.join("cmake-build"); fs::create_dir_all(&build_dir)?; run_cmd_shell_with_color::<YellowStderr>(&build_dir, "cmake -G Ninja -DENABLE_FUZZ=true ..")?; @@ -78,7 +76,13 @@ )?; } - run_cmd_shell_with_color::<YellowStderr>(&build_dir.join("np_cpp_ffi/fuzz/"), "ctest")?; - run_cmd_shell_with_color::<YellowStderr>(&build_dir.join("ldt_np_adv_ffi/c/fuzz/"), "ctest")?; + run_cmd_shell_with_color::<YellowStderr>( + &build_dir.join("presence/np_cpp_ffi/fuzz/"), + "ctest", + )?; + run_cmd_shell_with_color::<YellowStderr>( + &build_dir.join("presence/ldt_np_adv_ffi/c/fuzz/"), + "ctest", + )?; Ok(()) }
diff --git a/nearby/src/jni.rs b/nearby/src/jni.rs index 54aafdc..4ef3590 100644 --- a/nearby/src/jni.rs +++ b/nearby/src/jni.rs
@@ -15,13 +15,8 @@ use cmd_runner::run_cmd_shell; use std::path; -// This has to happen after both boringssl has been built and prepare rust openssl patches has been run. -pub fn check_ldt_jni(root: &path::Path) -> anyhow::Result<()> { - run_cmd_shell(root, "cargo build -p ldt_np_jni --no-default-features --features=boringssl")?; - Ok(()) -} - -pub fn run_kotlin_tests(root: &path::Path) -> anyhow::Result<()> { +pub fn run_ldt_kotlin_tests(root: &path::Path) -> anyhow::Result<()> { + run_cmd_shell(root, "cargo build -p ldt_np_jni")?; let kotlin_lib_path = root.to_path_buf().join("presence/ldt_np_jni/java/LdtNpJni"); run_cmd_shell(&kotlin_lib_path, "./gradlew :test")?; Ok(()) @@ -36,7 +31,7 @@ pub fn run_np_java_ffi_tests(root: &path::Path) -> anyhow::Result<()> { run_cmd_shell(root, "cargo build -p np_java_ffi -F crypto_provider_default/rustcrypto")?; - let ukey2_jni_path = root.to_path_buf().join("presence/np_java_ffi"); - run_cmd_shell(&ukey2_jni_path, "./gradlew :test --info --rerun")?; + let np_java_path = root.to_path_buf().join("presence/np_java_ffi"); + run_cmd_shell(&np_java_path, "./gradlew :test --info --rerun")?; Ok(()) }
diff --git a/nearby/src/main.rs b/nearby/src/main.rs index 25fe348..6fe4263 100644 --- a/nearby/src/main.rs +++ b/nearby/src/main.rs
@@ -14,6 +14,7 @@ extern crate core; +use anyhow::anyhow; use clap::Parser as _; use cmd_runner::{license_checker::LicenseSubcommand, run_cmd, run_cmd_shell, YellowStderr}; use env_logger::Env; @@ -25,7 +26,6 @@ mod fuzzers; mod jni; mod license; -mod ukey2; fn main() -> anyhow::Result<()> { env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); @@ -46,10 +46,12 @@ )); } Subcommand::VerifyCi { ref check_options } => verify_ci(&root_dir, check_options)?, + Subcommand::RunAllChecks { ref check_options } => run_all_checks(&root_dir, check_options)?, Subcommand::CleanEverything => clean_everything(&root_dir)?, Subcommand::CheckFormat(ref options) => check_format(&root_dir, options)?, Subcommand::CheckWorkspace(ref options) => check_workspace(&root_dir, options)?, - Subcommand::CheckAllFfi(ref options) => ffi::check_ffi(&root_dir, options)?, + Subcommand::CheckAllFfi(ref options) => ffi::check_all_ffi(&root_dir, options, false)?, + Subcommand::BazelBuild => bazel_build(&root_dir)?, Subcommand::BuildBoringssl => crypto_ffi::build_boringssl(&root_dir)?, Subcommand::CheckBoringssl(ref options) => crypto_ffi::check_boringssl(&root_dir, options)?, Subcommand::CheckBoringsslAtLatest(ref options) => { @@ -60,18 +62,29 @@ Subcommand::License(license_subcommand) => { license_subcommand.run(&LICENSE_CHECKER, &root_dir)? } - Subcommand::CheckUkey2Ffi(ref options) => ukey2::check_ukey2_ffi(&root_dir, options)?, + Subcommand::CheckUkey2Ffi(ref options) => { + ffi::check_ukey2_cmake(&root_dir, options, false)? + } Subcommand::RunUkey2JniTests => jni::run_ukey2_jni_tests(&root_dir)?, Subcommand::RunNpJavaFfiTests => jni::run_np_java_ffi_tests(&root_dir)?, - Subcommand::CheckLdtJni => jni::check_ldt_jni(&root_dir)?, - Subcommand::CheckLdtCmake(ref options) => ffi::check_ldt_cmake(&root_dir, options)?, - Subcommand::CheckNpFfiCmake(ref options) => ffi::check_np_ffi_cmake(&root_dir, options)?, - Subcommand::RunKotlinTests => jni::run_kotlin_tests(&root_dir)?, + Subcommand::CheckLdtCmake(ref options) => ffi::check_ldt_cmake(&root_dir, options, false)?, + Subcommand::CheckNpFfiCmake(ref options) => { + ffi::check_np_ffi_cmake(&root_dir, options, false)? + } + Subcommand::RunLdtKotlinTests => jni::run_ldt_kotlin_tests(&root_dir)?, } Ok(()) } +fn bazel_build(root: &path::Path) -> anyhow::Result<()> { + let beto_rust_root = + root.parent().ok_or_else(|| anyhow!("project root dir has no parent dir"))?; + run_cmd_shell(beto_rust_root, "bazel build ldt_np_adv_ffi")?; + run_cmd_shell(beto_rust_root, "bazel build np_cpp_sample")?; + Ok(()) +} + fn check_format(root: &path::Path, options: &FormatterOptions) -> anyhow::Result<()> { // Rust format { @@ -150,31 +163,55 @@ Ok(()) } -/// Runs default checks that are suiable for verifying a local change. -pub fn run_default_checks(root: &path::Path, check_options: &CheckOptions) -> anyhow::Result<()> { - license::LICENSE_CHECKER.check(root)?; - check_workspace(root, check_options)?; - crypto_ffi::check_boringssl(root, &check_options.cargo_options)?; - ffi::check_ffi(root, &check_options.cargo_options)?; - if !cfg!(target_os = "windows") { - fuzzers::build_fuzztest_unit_tests(root)?; - } - crypto_ffi::check_boringssl_at_head(root, &check_options.cargo_options)?; - ukey2::check_ukey2_ffi(root, &check_options.cargo_options)?; - if !cfg!(target_os = "windows") { - // Test below requires Java SE 9, but on Windows we only have Java SE 8 installed +pub fn verify_ci(root: &path::Path, check_options: &crate::CheckOptions) -> anyhow::Result<()> { + if cfg!(target_os = "linux") { + run_all_checks(root, check_options)?; + } else if cfg!(target_os = "macos") { + license::LICENSE_CHECKER.check(root)?; + check_workspace(root, check_options)?; + ffi::check_all_ffi(root, &check_options.cargo_options, false)?; jni::run_np_java_ffi_tests(root)?; + jni::run_ldt_kotlin_tests(root)?; + jni::run_ukey2_jni_tests(root)?; + } else if cfg!(windows) { + license::LICENSE_CHECKER.check(root)?; + check_workspace(root, check_options)?; + ffi::check_all_ffi(root, &check_options.cargo_options, false)?; + } else { + panic!("Unsupported OS for running CI!") } - jni::run_ukey2_jni_tests(root)?; Ok(()) } /// Runs checks to ensure lints are passing and all targets are building -pub fn verify_ci(root: &path::Path, check_options: &CheckOptions) -> anyhow::Result<()> { +pub fn run_all_checks(root: &path::Path, check_options: &CheckOptions) -> anyhow::Result<()> { run_default_checks(root, check_options)?; Ok(()) } +/// Runs default checks that are suiable for verifying a local change. +pub fn run_default_checks(root: &path::Path, check_options: &CheckOptions) -> anyhow::Result<()> { + license::LICENSE_CHECKER.check(root)?; + check_workspace(root, check_options)?; + // ffi build and run C++ tests against rustcrypto + ffi::check_all_ffi(root, &check_options.cargo_options, false)?; + + // ffi build and run tests against boringssl + crypto_ffi::check_boringssl(root, &check_options.cargo_options)?; + ffi::check_all_ffi(root, &check_options.cargo_options, true)?; + + if !cfg!(target_os = "windows") { + fuzzers::build_fuzztest_unit_tests(root)?; + } + if !cfg!(target_os = "windows") { + // Test below requires Java SE 9, but on Windows we only have Java SE 8 installed + jni::run_np_java_ffi_tests(root)?; + } + jni::run_ldt_kotlin_tests(root)?; + jni::run_ukey2_jni_tests(root)?; + Ok(()) +} + pub fn clean_everything(root: &path::Path) -> anyhow::Result<()> { run_cmd_shell(root, "cargo clean")?; run_cmd_shell(&root.join("presence/np_c_ffi"), "cargo clean")?; @@ -192,11 +229,18 @@ #[derive(clap::Subcommand, Debug, Clone)] enum Subcommand { - /// Runs all of the checks that CI runs + /// Runs all the checks that CI runs VerifyCi { #[command(flatten)] check_options: CheckOptions, }, + /// Runs all available checks, including ones that are not normally run on CI + RunAllChecks { + #[command(flatten)] + check_options: CheckOptions, + }, + /// Builds all the bazel targets + BazelBuild, /// Runs the default set of checks suitable for verifying local changes. RunDefaultChecks(CheckOptions), /// Cleans the main workspace and all sub projects - useful if upgrading rust compiler version @@ -227,10 +271,8 @@ License(LicenseSubcommand), /// Builds and runs tests for the UKEY2 FFI CheckUkey2Ffi(CargoOptions), - /// Checks the build of ldt_jni wrapper with non default features, ie boringssl - CheckLdtJni, /// Runs the kotlin tests of the LDT Jni API - RunKotlinTests, + RunLdtKotlinTests, /// Checks the build of the ukey2_jni wrapper and runs tests RunUkey2JniTests, /// Checks the build of the np_java_ffi wrapper and runs tests
diff --git a/nearby/src/ukey2.rs b/nearby/src/ukey2.rs deleted file mode 100644 index 5e711a1..0000000 --- a/nearby/src/ukey2.rs +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use cmd_runner::{run_cmd_shell, run_cmd_shell_with_color, YellowStderr}; -use std::{fs, path}; - -use crate::CargoOptions; - -pub(crate) fn check_ukey2_ffi( - root: &path::Path, - cargo_options: &CargoOptions, -) -> anyhow::Result<()> { - log::info!("Checking Ukey2 ffi"); - let ffi_dir = root.join("connections/ukey2/ukey2_c_ffi"); - - let locked_arg = if cargo_options.locked { "--locked" } else { "" }; - - // Default build, RustCrypto - run_cmd_shell(&ffi_dir, format!("cargo build {locked_arg} --quiet --release --lib"))?; - // BoringSSL - run_cmd_shell( - &ffi_dir, - format!("cargo build {locked_arg} --quiet --no-default-features --features=boringssl"), - )?; - run_cmd_shell(&ffi_dir, "cargo clippy --no-default-features --features=boringssl")?; - - // now run cmake build - let ffi_build_dir = ffi_dir.join("cpp/build"); - fs::create_dir_all(&ffi_build_dir)?; - run_cmd_shell_with_color::<YellowStderr>(&ffi_build_dir, "cmake ..")?; - run_cmd_shell_with_color::<YellowStderr>(&ffi_build_dir, "cmake --build .")?; - run_cmd_shell_with_color::<YellowStderr>(&ffi_build_dir, "ctest")?; - Ok(()) -}
diff --git a/remoteauth/Cargo.lock b/remoteauth/Cargo.lock index 165b375..7e17954 100644 --- a/remoteauth/Cargo.lock +++ b/remoteauth/Cargo.lock
@@ -28,47 +28,48 @@ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys", @@ -76,15 +77,15 @@ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bstr" @@ -115,9 +116,9 @@ [[package]] name = "cc" -version = "1.0.94" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" [[package]] name = "cfg-if" @@ -196,9 +197,9 @@ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "core-foundation-sys" @@ -361,6 +362,12 @@ ] [[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] name = "itoa" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -383,9 +390,9 @@ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "license" @@ -412,9 +419,9 @@ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -440,9 +447,9 @@ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -503,9 +510,9 @@ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -518,18 +525,18 @@ [[package]] name = "serde" -version = "1.0.198" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.198" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", @@ -561,9 +568,9 @@ [[package]] name = "syn" -version = "2.0.60" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -581,18 +588,18 @@ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", @@ -682,37 +689,15 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index"